Implement -mmemcpy-strategy= and -mmemset-strategy= options
[official-gcc.git] / gcc / config / i386 / i386.md
blob84515ae56f2faa02825c7b6dd4f0413bf5a65e9d
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,slm,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,
337    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
338    push,pop,call,callv,leave,
339    str,bitmanip,
340    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
341    fxch,fistp,fisttp,frndint,
342    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
343    ssemul,sseimul,ssediv,sselog,sselog1,
344    sseishft,sseishft1,ssecmp,ssecomi,
345    ssecvt,ssecvt1,sseicvt,sseins,
346    sseshuf,sseshuf1,ssemuladd,sse4arg,
347    lwp,
348    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
349   (const_string "other"))
351 ;; Main data type used by the insn
352 (define_attr "mode"
353   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
354   (const_string "unknown"))
356 ;; The CPU unit operations uses.
357 (define_attr "unit" "integer,i387,sse,mmx,unknown"
358   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
359                           fxch,fistp,fisttp,frndint")
360            (const_string "i387")
361          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
362                           ssemul,sseimul,ssediv,sselog,sselog1,
363                           sseishft,sseishft1,ssecmp,ssecomi,
364                           ssecvt,ssecvt1,sseicvt,sseins,
365                           sseshuf,sseshuf1,ssemuladd,sse4arg")
366            (const_string "sse")
367          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
368            (const_string "mmx")
369          (eq_attr "type" "other")
370            (const_string "unknown")]
371          (const_string "integer")))
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,
621                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
622                    mmx,mmxmov,mmxcmp,mmxcvt")
623               (match_operand 2 "memory_operand"))
624            (const_string "load")
625          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
626               (match_operand 3 "memory_operand"))
627            (const_string "load")
628         ]
629         (const_string "none")))
631 ;; Indicates if an instruction has both an immediate and a displacement.
633 (define_attr "imm_disp" "false,true,unknown"
634   (cond [(eq_attr "type" "other,multi")
635            (const_string "unknown")
636          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
637               (and (match_operand 0 "memory_displacement_operand")
638                    (match_operand 1 "immediate_operand")))
639            (const_string "true")
640          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
641               (and (match_operand 0 "memory_displacement_operand")
642                    (match_operand 2 "immediate_operand")))
643            (const_string "true")
644         ]
645         (const_string "false")))
647 ;; Indicates if an FP operation has an integer source.
649 (define_attr "fp_int_src" "false,true"
650   (const_string "false"))
652 ;; Defines rounding mode of an FP operation.
654 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
655   (const_string "any"))
657 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
658 (define_attr "use_carry" "0,1" (const_string "0"))
660 ;; Define attribute to indicate unaligned ssemov insns
661 (define_attr "movu" "0,1" (const_string "0"))
663 ;; Used to control the "enabled" attribute on a per-instruction basis.
664 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
665                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
666                     avx2,noavx2,bmi2,fma4,fma"
667   (const_string "base"))
669 (define_attr "enabled" ""
670   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
671          (eq_attr "isa" "x64_sse4")
672            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
673          (eq_attr "isa" "x64_sse4_noavx")
674            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
675          (eq_attr "isa" "x64_avx")
676            (symbol_ref "TARGET_64BIT && TARGET_AVX")
677          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
678          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
679          (eq_attr "isa" "sse2_noavx")
680            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
681          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
682          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
683          (eq_attr "isa" "sse4_noavx")
684            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
685          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
686          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
687          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
688          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
689          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
690          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
691          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
692         ]
693         (const_int 1)))
695 ;; Describe a user's asm statement.
696 (define_asm_attributes
697   [(set_attr "length" "128")
698    (set_attr "type" "multi")])
700 (define_code_iterator plusminus [plus minus])
702 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
704 ;; Base name for define_insn
705 (define_code_attr plusminus_insn
706   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
707    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
709 ;; Base name for insn mnemonic.
710 (define_code_attr plusminus_mnemonic
711   [(plus "add") (ss_plus "adds") (us_plus "addus")
712    (minus "sub") (ss_minus "subs") (us_minus "subus")])
713 (define_code_attr plusminus_carry_mnemonic
714   [(plus "adc") (minus "sbb")])
716 ;; Mark commutative operators as such in constraints.
717 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
718                         (minus "") (ss_minus "") (us_minus "")])
720 ;; Mapping of max and min
721 (define_code_iterator maxmin [smax smin umax umin])
723 ;; Mapping of signed max and min
724 (define_code_iterator smaxmin [smax smin])
726 ;; Mapping of unsigned max and min
727 (define_code_iterator umaxmin [umax umin])
729 ;; Base name for integer and FP insn mnemonic
730 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
731                               (umax "maxu") (umin "minu")])
732 (define_code_attr maxmin_float [(smax "max") (smin "min")])
734 ;; Mapping of logic operators
735 (define_code_iterator any_logic [and ior xor])
736 (define_code_iterator any_or [ior xor])
738 ;; Base name for insn mnemonic.
739 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
741 ;; Mapping of logic-shift operators
742 (define_code_iterator any_lshift [ashift lshiftrt])
744 ;; Mapping of shift-right operators
745 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
747 ;; Mapping of all shift operators
748 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
750 ;; Base name for define_insn
751 (define_code_attr shift_insn
752   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
754 ;; Base name for insn mnemonic.
755 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
756 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
758 ;; Mapping of rotate operators
759 (define_code_iterator any_rotate [rotate rotatert])
761 ;; Base name for define_insn
762 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
764 ;; Base name for insn mnemonic.
765 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
767 ;; Mapping of abs neg operators
768 (define_code_iterator absneg [abs neg])
770 ;; Base name for x87 insn mnemonic.
771 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
773 ;; Used in signed and unsigned widening multiplications.
774 (define_code_iterator any_extend [sign_extend zero_extend])
776 ;; Prefix for insn menmonic.
777 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
779 ;; Prefix for define_insn
780 (define_code_attr u [(sign_extend "") (zero_extend "u")])
781 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
782 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
784 ;; All integer modes.
785 (define_mode_iterator SWI1248x [QI HI SI DI])
787 ;; All integer modes without QImode.
788 (define_mode_iterator SWI248x [HI SI DI])
790 ;; All integer modes without QImode and HImode.
791 (define_mode_iterator SWI48x [SI DI])
793 ;; All integer modes without SImode and DImode.
794 (define_mode_iterator SWI12 [QI HI])
796 ;; All integer modes without DImode.
797 (define_mode_iterator SWI124 [QI HI SI])
799 ;; All integer modes without QImode and DImode.
800 (define_mode_iterator SWI24 [HI SI])
802 ;; Single word integer modes.
803 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
805 ;; Single word integer modes without QImode.
806 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
808 ;; Single word integer modes without QImode and HImode.
809 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
811 ;; All math-dependant single and double word integer modes.
812 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
813                              (HI "TARGET_HIMODE_MATH")
814                              SI DI (TI "TARGET_64BIT")])
816 ;; Math-dependant single word integer modes.
817 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
818                             (HI "TARGET_HIMODE_MATH")
819                             SI (DI "TARGET_64BIT")])
821 ;; Math-dependant integer modes without DImode.
822 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
823                                (HI "TARGET_HIMODE_MATH")
824                                SI])
826 ;; Math-dependant single word integer modes without QImode.
827 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
828                                SI (DI "TARGET_64BIT")])
830 ;; Double word integer modes.
831 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
832                            (TI "TARGET_64BIT")])
834 ;; Double word integer modes as mode attribute.
835 (define_mode_attr DWI [(SI "DI") (DI "TI")])
836 (define_mode_attr dwi [(SI "di") (DI "ti")])
838 ;; Half mode for double word integer modes.
839 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
840                             (DI "TARGET_64BIT")])
842 ;; Instruction suffix for integer modes.
843 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
845 ;; Pointer size prefix for integer modes (Intel asm dialect)
846 (define_mode_attr iptrsize [(QI "BYTE")
847                             (HI "WORD")
848                             (SI "DWORD")
849                             (DI "QWORD")])
851 ;; Register class for integer modes.
852 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
854 ;; Immediate operand constraint for integer modes.
855 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
857 ;; General operand constraint for word modes.
858 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
860 ;; Immediate operand constraint for double integer modes.
861 (define_mode_attr di [(SI "nF") (DI "e")])
863 ;; Immediate operand constraint for shifts.
864 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
866 ;; General operand predicate for integer modes.
867 (define_mode_attr general_operand
868         [(QI "general_operand")
869          (HI "general_operand")
870          (SI "x86_64_general_operand")
871          (DI "x86_64_general_operand")
872          (TI "x86_64_general_operand")])
874 ;; General sign/zero extend operand predicate for integer modes.
875 (define_mode_attr general_szext_operand
876         [(QI "general_operand")
877          (HI "general_operand")
878          (SI "x86_64_szext_general_operand")
879          (DI "x86_64_szext_general_operand")])
881 ;; Immediate operand predicate for integer modes.
882 (define_mode_attr immediate_operand
883         [(QI "immediate_operand")
884          (HI "immediate_operand")
885          (SI "x86_64_immediate_operand")
886          (DI "x86_64_immediate_operand")])
888 ;; Nonmemory operand predicate for integer modes.
889 (define_mode_attr nonmemory_operand
890         [(QI "nonmemory_operand")
891          (HI "nonmemory_operand")
892          (SI "x86_64_nonmemory_operand")
893          (DI "x86_64_nonmemory_operand")])
895 ;; Operand predicate for shifts.
896 (define_mode_attr shift_operand
897         [(QI "nonimmediate_operand")
898          (HI "nonimmediate_operand")
899          (SI "nonimmediate_operand")
900          (DI "shiftdi_operand")
901          (TI "register_operand")])
903 ;; Operand predicate for shift argument.
904 (define_mode_attr shift_immediate_operand
905         [(QI "const_1_to_31_operand")
906          (HI "const_1_to_31_operand")
907          (SI "const_1_to_31_operand")
908          (DI "const_1_to_63_operand")])
910 ;; Input operand predicate for arithmetic left shifts.
911 (define_mode_attr ashl_input_operand
912         [(QI "nonimmediate_operand")
913          (HI "nonimmediate_operand")
914          (SI "nonimmediate_operand")
915          (DI "ashldi_input_operand")
916          (TI "reg_or_pm1_operand")])
918 ;; SSE and x87 SFmode and DFmode floating point modes
919 (define_mode_iterator MODEF [SF DF])
921 ;; All x87 floating point modes
922 (define_mode_iterator X87MODEF [SF DF XF])
924 ;; SSE instruction suffix for various modes
925 (define_mode_attr ssemodesuffix
926   [(SF "ss") (DF "sd")
927    (V8SF "ps") (V4DF "pd")
928    (V4SF "ps") (V2DF "pd")
929    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
930    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
932 ;; SSE vector suffix for floating point modes
933 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
935 ;; SSE vector mode corresponding to a scalar mode
936 (define_mode_attr ssevecmode
937   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
938 (define_mode_attr ssevecmodelower
939   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
941 ;; Instruction suffix for REX 64bit operators.
942 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
944 ;; This mode iterator allows :P to be used for patterns that operate on
945 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
946 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
948 ;; This mode iterator allows :W to be used for patterns that operate on
949 ;; word_mode sized quantities.
950 (define_mode_iterator W
951   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
953 ;; This mode iterator allows :PTR to be used for patterns that operate on
954 ;; ptr_mode sized quantities.
955 (define_mode_iterator PTR
956   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
958 ;; Scheduling descriptions
960 (include "pentium.md")
961 (include "ppro.md")
962 (include "k6.md")
963 (include "athlon.md")
964 (include "bdver1.md")
965 (include "bdver3.md")
966 (include "btver2.md")
967 (include "geode.md")
968 (include "atom.md")
969 (include "slm.md")
970 (include "core2.md")
973 ;; Operand and operator predicates and constraints
975 (include "predicates.md")
976 (include "constraints.md")
979 ;; Compare and branch/compare and store instructions.
981 (define_expand "cbranch<mode>4"
982   [(set (reg:CC FLAGS_REG)
983         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
984                     (match_operand:SDWIM 2 "<general_operand>")))
985    (set (pc) (if_then_else
986                (match_operator 0 "ordered_comparison_operator"
987                 [(reg:CC FLAGS_REG) (const_int 0)])
988                (label_ref (match_operand 3))
989                (pc)))]
990   ""
992   if (MEM_P (operands[1]) && MEM_P (operands[2]))
993     operands[1] = force_reg (<MODE>mode, operands[1]);
994   ix86_expand_branch (GET_CODE (operands[0]),
995                       operands[1], operands[2], operands[3]);
996   DONE;
999 (define_expand "cstore<mode>4"
1000   [(set (reg:CC FLAGS_REG)
1001         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1002                     (match_operand:SWIM 3 "<general_operand>")))
1003    (set (match_operand:QI 0 "register_operand")
1004         (match_operator 1 "ordered_comparison_operator"
1005           [(reg:CC FLAGS_REG) (const_int 0)]))]
1006   ""
1008   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1009     operands[2] = force_reg (<MODE>mode, operands[2]);
1010   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1011                      operands[2], operands[3]);
1012   DONE;
1015 (define_expand "cmp<mode>_1"
1016   [(set (reg:CC FLAGS_REG)
1017         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1018                     (match_operand:SWI48 1 "<general_operand>")))])
1020 (define_insn "*cmp<mode>_ccno_1"
1021   [(set (reg FLAGS_REG)
1022         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1023                  (match_operand:SWI 1 "const0_operand")))]
1024   "ix86_match_ccmode (insn, CCNOmode)"
1025   "@
1026    test{<imodesuffix>}\t%0, %0
1027    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1028   [(set_attr "type" "test,icmp")
1029    (set_attr "length_immediate" "0,1")
1030    (set_attr "mode" "<MODE>")])
1032 (define_insn "*cmp<mode>_1"
1033   [(set (reg FLAGS_REG)
1034         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1035                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1036   "ix86_match_ccmode (insn, CCmode)"
1037   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1038   [(set_attr "type" "icmp")
1039    (set_attr "mode" "<MODE>")])
1041 (define_insn "*cmp<mode>_minus_1"
1042   [(set (reg FLAGS_REG)
1043         (compare
1044           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1045                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1046           (const_int 0)))]
1047   "ix86_match_ccmode (insn, CCGOCmode)"
1048   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1049   [(set_attr "type" "icmp")
1050    (set_attr "mode" "<MODE>")])
1052 (define_insn "*cmpqi_ext_1"
1053   [(set (reg FLAGS_REG)
1054         (compare
1055           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1056           (subreg:QI
1057             (zero_extract:SI
1058               (match_operand 1 "ext_register_operand" "Q,Q")
1059               (const_int 8)
1060               (const_int 8)) 0)))]
1061   "ix86_match_ccmode (insn, CCmode)"
1062   "cmp{b}\t{%h1, %0|%0, %h1}"
1063   [(set_attr "isa" "*,nox64")
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 "const_int_operand")))])
1092 (define_insn "*cmpqi_ext_3"
1093   [(set (reg FLAGS_REG)
1094         (compare
1095           (subreg:QI
1096             (zero_extract:SI
1097               (match_operand 0 "ext_register_operand" "Q,Q")
1098               (const_int 8)
1099               (const_int 8)) 0)
1100           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1101   "ix86_match_ccmode (insn, CCmode)"
1102   "cmp{b}\t{%1, %h0|%h0, %1}"
1103   [(set_attr "isa" "*,nox64")
1104    (set_attr "type" "icmp")
1105    (set_attr "modrm" "1")
1106    (set_attr "mode" "QI")])
1108 (define_insn "*cmpqi_ext_4"
1109   [(set (reg FLAGS_REG)
1110         (compare
1111           (subreg:QI
1112             (zero_extract:SI
1113               (match_operand 0 "ext_register_operand" "Q")
1114               (const_int 8)
1115               (const_int 8)) 0)
1116           (subreg:QI
1117             (zero_extract:SI
1118               (match_operand 1 "ext_register_operand" "Q")
1119               (const_int 8)
1120               (const_int 8)) 0)))]
1121   "ix86_match_ccmode (insn, CCmode)"
1122   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1123   [(set_attr "type" "icmp")
1124    (set_attr "mode" "QI")])
1126 ;; These implement float point compares.
1127 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1128 ;; which would allow mix and match FP modes on the compares.  Which is what
1129 ;; the old patterns did, but with many more of them.
1131 (define_expand "cbranchxf4"
1132   [(set (reg:CC FLAGS_REG)
1133         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1134                     (match_operand:XF 2 "nonmemory_operand")))
1135    (set (pc) (if_then_else
1136               (match_operator 0 "ix86_fp_comparison_operator"
1137                [(reg:CC FLAGS_REG)
1138                 (const_int 0)])
1139               (label_ref (match_operand 3))
1140               (pc)))]
1141   "TARGET_80387"
1143   ix86_expand_branch (GET_CODE (operands[0]),
1144                       operands[1], operands[2], operands[3]);
1145   DONE;
1148 (define_expand "cstorexf4"
1149   [(set (reg:CC FLAGS_REG)
1150         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1151                     (match_operand:XF 3 "nonmemory_operand")))
1152    (set (match_operand:QI 0 "register_operand")
1153               (match_operator 1 "ix86_fp_comparison_operator"
1154                [(reg:CC FLAGS_REG)
1155                 (const_int 0)]))]
1156   "TARGET_80387"
1158   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1159                      operands[2], operands[3]);
1160   DONE;
1163 (define_expand "cbranch<mode>4"
1164   [(set (reg:CC FLAGS_REG)
1165         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1166                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1167    (set (pc) (if_then_else
1168               (match_operator 0 "ix86_fp_comparison_operator"
1169                [(reg:CC FLAGS_REG)
1170                 (const_int 0)])
1171               (label_ref (match_operand 3))
1172               (pc)))]
1173   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1175   ix86_expand_branch (GET_CODE (operands[0]),
1176                       operands[1], operands[2], operands[3]);
1177   DONE;
1180 (define_expand "cstore<mode>4"
1181   [(set (reg:CC FLAGS_REG)
1182         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1183                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1184    (set (match_operand:QI 0 "register_operand")
1185               (match_operator 1 "ix86_fp_comparison_operator"
1186                [(reg:CC FLAGS_REG)
1187                 (const_int 0)]))]
1188   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1190   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1191                      operands[2], operands[3]);
1192   DONE;
1195 (define_expand "cbranchcc4"
1196   [(set (pc) (if_then_else
1197               (match_operator 0 "comparison_operator"
1198                [(match_operand 1 "flags_reg_operand")
1199                 (match_operand 2 "const0_operand")])
1200               (label_ref (match_operand 3))
1201               (pc)))]
1202   ""
1204   ix86_expand_branch (GET_CODE (operands[0]),
1205                       operands[1], operands[2], operands[3]);
1206   DONE;
1209 (define_expand "cstorecc4"
1210   [(set (match_operand:QI 0 "register_operand")
1211               (match_operator 1 "comparison_operator"
1212                [(match_operand 2 "flags_reg_operand")
1213                 (match_operand 3 "const0_operand")]))]
1214   ""
1216   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1217                      operands[2], operands[3]);
1218   DONE;
1222 ;; FP compares, step 1:
1223 ;; Set the FP condition codes.
1225 ;; CCFPmode     compare with exceptions
1226 ;; CCFPUmode    compare with no exceptions
1228 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1229 ;; used to manage the reg stack popping would not be preserved.
1231 (define_insn "*cmp<mode>_0_i387"
1232   [(set (match_operand:HI 0 "register_operand" "=a")
1233         (unspec:HI
1234           [(compare:CCFP
1235              (match_operand:X87MODEF 1 "register_operand" "f")
1236              (match_operand:X87MODEF 2 "const0_operand"))]
1237         UNSPEC_FNSTSW))]
1238   "TARGET_80387"
1239   "* return output_fp_compare (insn, operands, false, false);"
1240   [(set_attr "type" "multi")
1241    (set_attr "unit" "i387")
1242    (set_attr "mode" "<MODE>")])
1244 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1245   [(set (reg:CCFP FLAGS_REG)
1246         (compare:CCFP
1247           (match_operand:X87MODEF 1 "register_operand" "f")
1248           (match_operand:X87MODEF 2 "const0_operand")))
1249    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1250   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1251   "#"
1252   "&& reload_completed"
1253   [(set (match_dup 0)
1254         (unspec:HI
1255           [(compare:CCFP (match_dup 1)(match_dup 2))]
1256         UNSPEC_FNSTSW))
1257    (set (reg:CC FLAGS_REG)
1258         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1259   ""
1260   [(set_attr "type" "multi")
1261    (set_attr "unit" "i387")
1262    (set_attr "mode" "<MODE>")])
1264 (define_insn "*cmpxf_i387"
1265   [(set (match_operand:HI 0 "register_operand" "=a")
1266         (unspec:HI
1267           [(compare:CCFP
1268              (match_operand:XF 1 "register_operand" "f")
1269              (match_operand:XF 2 "register_operand" "f"))]
1270           UNSPEC_FNSTSW))]
1271   "TARGET_80387"
1272   "* return output_fp_compare (insn, operands, false, false);"
1273   [(set_attr "type" "multi")
1274    (set_attr "unit" "i387")
1275    (set_attr "mode" "XF")])
1277 (define_insn_and_split "*cmpxf_cc_i387"
1278   [(set (reg:CCFP FLAGS_REG)
1279         (compare:CCFP
1280           (match_operand:XF 1 "register_operand" "f")
1281           (match_operand:XF 2 "register_operand" "f")))
1282    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1283   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1284   "#"
1285   "&& reload_completed"
1286   [(set (match_dup 0)
1287         (unspec:HI
1288           [(compare:CCFP (match_dup 1)(match_dup 2))]
1289         UNSPEC_FNSTSW))
1290    (set (reg:CC FLAGS_REG)
1291         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1292   ""
1293   [(set_attr "type" "multi")
1294    (set_attr "unit" "i387")
1295    (set_attr "mode" "XF")])
1297 (define_insn "*cmp<mode>_i387"
1298   [(set (match_operand:HI 0 "register_operand" "=a")
1299         (unspec:HI
1300           [(compare:CCFP
1301              (match_operand:MODEF 1 "register_operand" "f")
1302              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1303           UNSPEC_FNSTSW))]
1304   "TARGET_80387"
1305   "* return output_fp_compare (insn, operands, false, false);"
1306   [(set_attr "type" "multi")
1307    (set_attr "unit" "i387")
1308    (set_attr "mode" "<MODE>")])
1310 (define_insn_and_split "*cmp<mode>_cc_i387"
1311   [(set (reg:CCFP FLAGS_REG)
1312         (compare:CCFP
1313           (match_operand:MODEF 1 "register_operand" "f")
1314           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1315    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1316   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1317   "#"
1318   "&& reload_completed"
1319   [(set (match_dup 0)
1320         (unspec:HI
1321           [(compare:CCFP (match_dup 1)(match_dup 2))]
1322         UNSPEC_FNSTSW))
1323    (set (reg:CC FLAGS_REG)
1324         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1325   ""
1326   [(set_attr "type" "multi")
1327    (set_attr "unit" "i387")
1328    (set_attr "mode" "<MODE>")])
1330 (define_insn "*cmpu<mode>_i387"
1331   [(set (match_operand:HI 0 "register_operand" "=a")
1332         (unspec:HI
1333           [(compare:CCFPU
1334              (match_operand:X87MODEF 1 "register_operand" "f")
1335              (match_operand:X87MODEF 2 "register_operand" "f"))]
1336           UNSPEC_FNSTSW))]
1337   "TARGET_80387"
1338   "* return output_fp_compare (insn, operands, false, true);"
1339   [(set_attr "type" "multi")
1340    (set_attr "unit" "i387")
1341    (set_attr "mode" "<MODE>")])
1343 (define_insn_and_split "*cmpu<mode>_cc_i387"
1344   [(set (reg:CCFPU FLAGS_REG)
1345         (compare:CCFPU
1346           (match_operand:X87MODEF 1 "register_operand" "f")
1347           (match_operand:X87MODEF 2 "register_operand" "f")))
1348    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1349   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1350   "#"
1351   "&& reload_completed"
1352   [(set (match_dup 0)
1353         (unspec:HI
1354           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1355         UNSPEC_FNSTSW))
1356    (set (reg:CC FLAGS_REG)
1357         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1358   ""
1359   [(set_attr "type" "multi")
1360    (set_attr "unit" "i387")
1361    (set_attr "mode" "<MODE>")])
1363 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1364   [(set (match_operand:HI 0 "register_operand" "=a")
1365         (unspec:HI
1366           [(compare:CCFP
1367              (match_operand:X87MODEF 1 "register_operand" "f")
1368              (match_operator:X87MODEF 3 "float_operator"
1369                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1370           UNSPEC_FNSTSW))]
1371   "TARGET_80387
1372    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1373        || optimize_function_for_size_p (cfun))"
1374   "* return output_fp_compare (insn, operands, false, false);"
1375   [(set_attr "type" "multi")
1376    (set_attr "unit" "i387")
1377    (set_attr "fp_int_src" "true")
1378    (set_attr "mode" "<SWI24:MODE>")])
1380 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1381   [(set (reg:CCFP FLAGS_REG)
1382         (compare:CCFP
1383           (match_operand:X87MODEF 1 "register_operand" "f")
1384           (match_operator:X87MODEF 3 "float_operator"
1385             [(match_operand:SWI24 2 "memory_operand" "m")])))
1386    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1387   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1388    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1389        || optimize_function_for_size_p (cfun))"
1390   "#"
1391   "&& reload_completed"
1392   [(set (match_dup 0)
1393         (unspec:HI
1394           [(compare:CCFP
1395              (match_dup 1)
1396              (match_op_dup 3 [(match_dup 2)]))]
1397         UNSPEC_FNSTSW))
1398    (set (reg:CC FLAGS_REG)
1399         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1400   ""
1401   [(set_attr "type" "multi")
1402    (set_attr "unit" "i387")
1403    (set_attr "fp_int_src" "true")
1404    (set_attr "mode" "<SWI24:MODE>")])
1406 ;; FP compares, step 2
1407 ;; Move the fpsw to ax.
1409 (define_insn "x86_fnstsw_1"
1410   [(set (match_operand:HI 0 "register_operand" "=a")
1411         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1412   "TARGET_80387"
1413   "fnstsw\t%0"
1414   [(set (attr "length")
1415         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1416    (set_attr "mode" "SI")
1417    (set_attr "unit" "i387")])
1419 ;; FP compares, step 3
1420 ;; Get ax into flags, general case.
1422 (define_insn "x86_sahf_1"
1423   [(set (reg:CC FLAGS_REG)
1424         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1425                    UNSPEC_SAHF))]
1426   "TARGET_SAHF"
1428 #ifndef HAVE_AS_IX86_SAHF
1429   if (TARGET_64BIT)
1430     return ASM_BYTE "0x9e";
1431   else
1432 #endif
1433   return "sahf";
1435   [(set_attr "length" "1")
1436    (set_attr "athlon_decode" "vector")
1437    (set_attr "amdfam10_decode" "direct")
1438    (set_attr "bdver1_decode" "direct")
1439    (set_attr "mode" "SI")])
1441 ;; Pentium Pro can do steps 1 through 3 in one go.
1442 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1443 ;; (these i387 instructions set flags directly)
1445 (define_mode_iterator FPCMP [CCFP CCFPU])
1446 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1448 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1449   [(set (reg:FPCMP FLAGS_REG)
1450         (compare:FPCMP
1451           (match_operand:MODEF 0 "register_operand" "f,x")
1452           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1453   "TARGET_MIX_SSE_I387
1454    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1455   "* return output_fp_compare (insn, operands, true,
1456                                <FPCMP:MODE>mode == CCFPUmode);"
1457   [(set_attr "type" "fcmp,ssecomi")
1458    (set_attr "prefix" "orig,maybe_vex")
1459    (set_attr "mode" "<MODEF:MODE>")
1460    (set (attr "prefix_rep")
1461         (if_then_else (eq_attr "type" "ssecomi")
1462                       (const_string "0")
1463                       (const_string "*")))
1464    (set (attr "prefix_data16")
1465         (cond [(eq_attr "type" "fcmp")
1466                  (const_string "*")
1467                (eq_attr "mode" "DF")
1468                  (const_string "1")
1469               ]
1470               (const_string "0")))
1471    (set_attr "athlon_decode" "vector")
1472    (set_attr "amdfam10_decode" "direct")
1473    (set_attr "bdver1_decode" "double")])
1475 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1476   [(set (reg:FPCMP FLAGS_REG)
1477         (compare:FPCMP
1478           (match_operand:MODEF 0 "register_operand" "x")
1479           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1480   "TARGET_SSE_MATH
1481    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1482   "* return output_fp_compare (insn, operands, true,
1483                                <FPCMP:MODE>mode == CCFPUmode);"
1484   [(set_attr "type" "ssecomi")
1485    (set_attr "prefix" "maybe_vex")
1486    (set_attr "mode" "<MODEF:MODE>")
1487    (set_attr "prefix_rep" "0")
1488    (set (attr "prefix_data16")
1489         (if_then_else (eq_attr "mode" "DF")
1490                       (const_string "1")
1491                       (const_string "0")))
1492    (set_attr "athlon_decode" "vector")
1493    (set_attr "amdfam10_decode" "direct")
1494    (set_attr "bdver1_decode" "double")])
1496 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1497   [(set (reg:FPCMP FLAGS_REG)
1498         (compare:FPCMP
1499           (match_operand:X87MODEF 0 "register_operand" "f")
1500           (match_operand:X87MODEF 1 "register_operand" "f")))]
1501   "TARGET_80387 && TARGET_CMOVE
1502    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1503   "* return output_fp_compare (insn, operands, true,
1504                                <FPCMP:MODE>mode == CCFPUmode);"
1505   [(set_attr "type" "fcmp")
1506    (set_attr "mode" "<X87MODEF:MODE>")
1507    (set_attr "athlon_decode" "vector")
1508    (set_attr "amdfam10_decode" "direct")
1509    (set_attr "bdver1_decode" "double")])
1511 ;; Push/pop instructions.
1513 (define_insn "*push<mode>2"
1514   [(set (match_operand:DWI 0 "push_operand" "=<")
1515         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1516   ""
1517   "#"
1518   [(set_attr "type" "multi")
1519    (set_attr "mode" "<MODE>")])
1521 (define_split
1522   [(set (match_operand:TI 0 "push_operand")
1523         (match_operand:TI 1 "general_operand"))]
1524   "TARGET_64BIT && reload_completed
1525    && !SSE_REG_P (operands[1])"
1526   [(const_int 0)]
1527   "ix86_split_long_move (operands); DONE;")
1529 (define_insn "*pushdi2_rex64"
1530   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1531         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1532   "TARGET_64BIT"
1533   "@
1534    push{q}\t%1
1535    #"
1536   [(set_attr "type" "push,multi")
1537    (set_attr "mode" "DI")])
1539 ;; Convert impossible pushes of immediate to existing instructions.
1540 ;; First try to get scratch register and go through it.  In case this
1541 ;; fails, push sign extended lower part first and then overwrite
1542 ;; upper part by 32bit move.
1543 (define_peephole2
1544   [(match_scratch:DI 2 "r")
1545    (set (match_operand:DI 0 "push_operand")
1546         (match_operand:DI 1 "immediate_operand"))]
1547   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1548    && !x86_64_immediate_operand (operands[1], DImode)"
1549   [(set (match_dup 2) (match_dup 1))
1550    (set (match_dup 0) (match_dup 2))])
1552 ;; We need to define this as both peepholer and splitter for case
1553 ;; peephole2 pass is not run.
1554 ;; "&& 1" is needed to keep it from matching the previous pattern.
1555 (define_peephole2
1556   [(set (match_operand:DI 0 "push_operand")
1557         (match_operand:DI 1 "immediate_operand"))]
1558   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1559    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1560   [(set (match_dup 0) (match_dup 1))
1561    (set (match_dup 2) (match_dup 3))]
1563   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1565   operands[1] = gen_lowpart (DImode, operands[2]);
1566   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1567                                                    GEN_INT (4)));
1570 (define_split
1571   [(set (match_operand:DI 0 "push_operand")
1572         (match_operand:DI 1 "immediate_operand"))]
1573   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1574                     ? epilogue_completed : reload_completed)
1575    && !symbolic_operand (operands[1], DImode)
1576    && !x86_64_immediate_operand (operands[1], DImode)"
1577   [(set (match_dup 0) (match_dup 1))
1578    (set (match_dup 2) (match_dup 3))]
1580   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1582   operands[1] = gen_lowpart (DImode, operands[2]);
1583   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1584                                                    GEN_INT (4)));
1587 (define_split
1588   [(set (match_operand:DI 0 "push_operand")
1589         (match_operand:DI 1 "general_operand"))]
1590   "!TARGET_64BIT && reload_completed
1591    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1592   [(const_int 0)]
1593   "ix86_split_long_move (operands); DONE;")
1595 (define_insn "*pushsi2"
1596   [(set (match_operand:SI 0 "push_operand" "=<")
1597         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1598   "!TARGET_64BIT"
1599   "push{l}\t%1"
1600   [(set_attr "type" "push")
1601    (set_attr "mode" "SI")])
1603 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1604 ;; "push a byte/word".  But actually we use pushl, which has the effect
1605 ;; of rounding the amount pushed up to a word.
1607 ;; For TARGET_64BIT we always round up to 8 bytes.
1608 (define_insn "*push<mode>2_rex64"
1609   [(set (match_operand:SWI124 0 "push_operand" "=X")
1610         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1611   "TARGET_64BIT"
1612   "push{q}\t%q1"
1613   [(set_attr "type" "push")
1614    (set_attr "mode" "DI")])
1616 (define_insn "*push<mode>2"
1617   [(set (match_operand:SWI12 0 "push_operand" "=X")
1618         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1619   "!TARGET_64BIT"
1620   "push{l}\t%k1"
1621   [(set_attr "type" "push")
1622    (set_attr "mode" "SI")])
1624 (define_insn "*push<mode>2_prologue"
1625   [(set (match_operand:W 0 "push_operand" "=<")
1626         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1627    (clobber (mem:BLK (scratch)))]
1628   ""
1629   "push{<imodesuffix>}\t%1"
1630   [(set_attr "type" "push")
1631    (set_attr "mode" "<MODE>")])
1633 (define_insn "*pop<mode>1"
1634   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1635         (match_operand:W 1 "pop_operand" ">"))]
1636   ""
1637   "pop{<imodesuffix>}\t%0"
1638   [(set_attr "type" "pop")
1639    (set_attr "mode" "<MODE>")])
1641 (define_insn "*pop<mode>1_epilogue"
1642   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1643         (match_operand:W 1 "pop_operand" ">"))
1644    (clobber (mem:BLK (scratch)))]
1645   ""
1646   "pop{<imodesuffix>}\t%0"
1647   [(set_attr "type" "pop")
1648    (set_attr "mode" "<MODE>")])
1650 ;; Move instructions.
1652 ;; Reload patterns to support multi-word load/store
1653 ;; with non-offsetable address.
1654 (define_expand "reload_noff_store"
1655   [(parallel [(match_operand 0 "memory_operand" "=m")
1656               (match_operand 1 "register_operand" "r")
1657               (match_operand:DI 2 "register_operand" "=&r")])]
1658   "TARGET_64BIT"
1660   rtx mem = operands[0];
1661   rtx addr = XEXP (mem, 0);
1663   emit_move_insn (operands[2], addr);
1664   mem = replace_equiv_address_nv (mem, operands[2]);
1666   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1667   DONE;
1670 (define_expand "reload_noff_load"
1671   [(parallel [(match_operand 0 "register_operand" "=r")
1672               (match_operand 1 "memory_operand" "m")
1673               (match_operand:DI 2 "register_operand" "=r")])]
1674   "TARGET_64BIT"
1676   rtx mem = operands[1];
1677   rtx addr = XEXP (mem, 0);
1679   emit_move_insn (operands[2], addr);
1680   mem = replace_equiv_address_nv (mem, operands[2]);
1682   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1683   DONE;
1686 (define_expand "movoi"
1687   [(set (match_operand:OI 0 "nonimmediate_operand")
1688         (match_operand:OI 1 "general_operand"))]
1689   "TARGET_AVX"
1690   "ix86_expand_move (OImode, operands); DONE;")
1692 (define_expand "movti"
1693   [(set (match_operand:TI 0 "nonimmediate_operand")
1694         (match_operand:TI 1 "nonimmediate_operand"))]
1695   "TARGET_64BIT || TARGET_SSE"
1697   if (TARGET_64BIT)
1698     ix86_expand_move (TImode, operands);
1699   else if (push_operand (operands[0], TImode))
1700     ix86_expand_push (TImode, operands[1]);
1701   else
1702     ix86_expand_vector_move (TImode, operands);
1703   DONE;
1706 ;; This expands to what emit_move_complex would generate if we didn't
1707 ;; have a movti pattern.  Having this avoids problems with reload on
1708 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1709 ;; to have around all the time.
1710 (define_expand "movcdi"
1711   [(set (match_operand:CDI 0 "nonimmediate_operand")
1712         (match_operand:CDI 1 "general_operand"))]
1713   ""
1715   if (push_operand (operands[0], CDImode))
1716     emit_move_complex_push (CDImode, operands[0], operands[1]);
1717   else
1718     emit_move_complex_parts (operands[0], operands[1]);
1719   DONE;
1722 (define_expand "mov<mode>"
1723   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1724         (match_operand:SWI1248x 1 "general_operand"))]
1725   ""
1726   "ix86_expand_move (<MODE>mode, operands); DONE;")
1728 (define_insn "*mov<mode>_xor"
1729   [(set (match_operand:SWI48 0 "register_operand" "=r")
1730         (match_operand:SWI48 1 "const0_operand"))
1731    (clobber (reg:CC FLAGS_REG))]
1732   "reload_completed"
1733   "xor{l}\t%k0, %k0"
1734   [(set_attr "type" "alu1")
1735    (set_attr "mode" "SI")
1736    (set_attr "length_immediate" "0")])
1738 (define_insn "*mov<mode>_or"
1739   [(set (match_operand:SWI48 0 "register_operand" "=r")
1740         (match_operand:SWI48 1 "const_int_operand"))
1741    (clobber (reg:CC FLAGS_REG))]
1742   "reload_completed
1743    && operands[1] == constm1_rtx"
1744   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1745   [(set_attr "type" "alu1")
1746    (set_attr "mode" "<MODE>")
1747    (set_attr "length_immediate" "1")])
1749 (define_insn "*movoi_internal_avx"
1750   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1751         (match_operand:OI 1 "vector_move_operand"  "C ,xm,x"))]
1752   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1754   switch (get_attr_type (insn))
1755     {
1756     case TYPE_SSELOG1:
1757       return standard_sse_constant_opcode (insn, operands[1]);
1759     case TYPE_SSEMOV:
1760       if (misaligned_operand (operands[0], OImode)
1761           || misaligned_operand (operands[1], OImode))
1762         {
1763           if (get_attr_mode (insn) == MODE_V8SF)
1764             return "vmovups\t{%1, %0|%0, %1}";
1765           else
1766             return "vmovdqu\t{%1, %0|%0, %1}";
1767         }
1768       else
1769         {
1770           if (get_attr_mode (insn) == MODE_V8SF)
1771             return "vmovaps\t{%1, %0|%0, %1}";
1772           else
1773             return "vmovdqa\t{%1, %0|%0, %1}";
1774         }
1776     default:
1777       gcc_unreachable ();
1778     }
1780   [(set_attr "type" "sselog1,ssemov,ssemov")
1781    (set_attr "prefix" "vex")
1782    (set (attr "mode")
1783         (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1784                  (const_string "V8SF")
1785                (and (eq_attr "alternative" "2")
1786                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1787                  (const_string "V8SF")
1788               ]
1789               (const_string "OI")))])
1791 (define_insn "*movti_internal"
1792   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1793         (match_operand:TI 1 "general_operand"      "riFo,re,C,xm,x"))]
1794   "(TARGET_64BIT || TARGET_SSE)
1795    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1797   switch (get_attr_type (insn))
1798     {
1799     case TYPE_MULTI:
1800       return "#";
1802     case TYPE_SSELOG1:
1803       return standard_sse_constant_opcode (insn, operands[1]);
1805     case TYPE_SSEMOV:
1806       /* TDmode values are passed as TImode on the stack.  Moving them
1807          to stack may result in unaligned memory access.  */
1808       if (misaligned_operand (operands[0], TImode)
1809           || misaligned_operand (operands[1], TImode))
1810         {
1811           if (get_attr_mode (insn) == MODE_V4SF)
1812             return "%vmovups\t{%1, %0|%0, %1}";
1813           else
1814             return "%vmovdqu\t{%1, %0|%0, %1}";
1815         }
1816       else
1817         {
1818           if (get_attr_mode (insn) == MODE_V4SF)
1819             return "%vmovaps\t{%1, %0|%0, %1}";
1820           else
1821             return "%vmovdqa\t{%1, %0|%0, %1}";
1822         }
1824     default:
1825       gcc_unreachable ();
1826     }
1828   [(set_attr "isa" "x64,x64,*,*,*")
1829    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1830    (set (attr "prefix")
1831      (if_then_else (eq_attr "type" "sselog1,ssemov")
1832        (const_string "maybe_vex")
1833        (const_string "orig")))
1834    (set (attr "mode")
1835         (cond [(eq_attr "alternative" "0,1")
1836                  (const_string "DI")
1837                (ior (not (match_test "TARGET_SSE2"))
1838                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1839                  (const_string "V4SF")
1840                (and (eq_attr "alternative" "4")
1841                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1842                  (const_string "V4SF")
1843                (match_test "TARGET_AVX")
1844                  (const_string "TI")
1845                (match_test "optimize_function_for_size_p (cfun)")
1846                  (const_string "V4SF")
1847                ]
1848                (const_string "TI")))])
1850 (define_split
1851   [(set (match_operand:TI 0 "nonimmediate_operand")
1852         (match_operand:TI 1 "general_operand"))]
1853   "reload_completed
1854    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1855   [(const_int 0)]
1856   "ix86_split_long_move (operands); DONE;")
1858 (define_insn "*movdi_internal"
1859   [(set (match_operand:DI 0 "nonimmediate_operand"
1860     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*x,*x,*x,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1861         (match_operand:DI 1 "general_operand"
1862     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*x,m ,*x,*Yj,*x,r   ,*Yj ,*Yn"))]
1863   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1865   switch (get_attr_type (insn))
1866     {
1867     case TYPE_MULTI:
1868       return "#";
1870     case TYPE_MMX:
1871       return "pxor\t%0, %0";
1873     case TYPE_MMXMOV:
1874 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1875       /* Handle broken assemblers that require movd instead of movq.  */
1876       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1877         return "movd\t{%1, %0|%0, %1}";
1878 #endif
1879       return "movq\t{%1, %0|%0, %1}";
1881     case TYPE_SSELOG1:
1882       if (GENERAL_REG_P (operands[0]))
1883         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
1885       return standard_sse_constant_opcode (insn, operands[1]);
1887     case TYPE_SSEMOV:
1888       switch (get_attr_mode (insn))
1889         {
1890         case MODE_DI:
1891 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1892           /* Handle broken assemblers that require movd instead of movq.  */
1893           if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1894             return "%vmovd\t{%1, %0|%0, %1}";
1895 #endif
1896           return "%vmovq\t{%1, %0|%0, %1}";
1897         case MODE_TI:
1898           return "%vmovdqa\t{%1, %0|%0, %1}";
1900         case MODE_V2SF:
1901           gcc_assert (!TARGET_AVX);
1902           return "movlps\t{%1, %0|%0, %1}";
1903         case MODE_V4SF:
1904           return "%vmovaps\t{%1, %0|%0, %1}";
1906         default:
1907           gcc_unreachable ();
1908         }
1910     case TYPE_SSECVT:
1911       if (SSE_REG_P (operands[0]))
1912         return "movq2dq\t{%1, %0|%0, %1}";
1913       else
1914         return "movdq2q\t{%1, %0|%0, %1}";
1916     case TYPE_LEA:
1917       return "lea{q}\t{%E1, %0|%0, %E1}";
1919     case TYPE_IMOV:
1920       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1921       if (get_attr_mode (insn) == MODE_SI)
1922         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1923       else if (which_alternative == 4)
1924         return "movabs{q}\t{%1, %0|%0, %1}";
1925       else if (ix86_use_lea_for_mov (insn, operands))
1926         return "lea{q}\t{%E1, %0|%0, %E1}";
1927       else
1928         return "mov{q}\t{%1, %0|%0, %1}";
1930     default:
1931       gcc_unreachable ();
1932     }
1934   [(set (attr "isa")
1935      (cond [(eq_attr "alternative" "0,1")
1936               (const_string "nox64")
1937             (eq_attr "alternative" "2,3,4,5,10,11,16,18")
1938               (const_string "x64")
1939             (eq_attr "alternative" "17")
1940               (const_string "x64_sse4")
1941            ]
1942            (const_string "*")))
1943    (set (attr "type")
1944      (cond [(eq_attr "alternative" "0,1")
1945               (const_string "multi")
1946             (eq_attr "alternative" "6")
1947               (const_string "mmx")
1948             (eq_attr "alternative" "7,8,9,10,11")
1949               (const_string "mmxmov")
1950             (eq_attr "alternative" "12,17")
1951               (const_string "sselog1")
1952             (eq_attr "alternative" "13,14,15,16,18")
1953               (const_string "ssemov")
1954             (eq_attr "alternative" "19,20")
1955               (const_string "ssecvt")
1956             (match_operand 1 "pic_32bit_operand")
1957               (const_string "lea")
1958            ]
1959            (const_string "imov")))
1960    (set (attr "modrm")
1961      (if_then_else
1962        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1963          (const_string "0")
1964          (const_string "*")))
1965    (set (attr "length_immediate")
1966      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1967               (const_string "8")
1968             (eq_attr "alternative" "17")
1969               (const_string "1")
1970            ]
1971            (const_string "*")))
1972    (set (attr "prefix_rex")
1973      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
1974        (const_string "1")
1975        (const_string "*")))
1976    (set (attr "prefix_extra")
1977      (if_then_else (eq_attr "alternative" "17")
1978        (const_string "1")
1979        (const_string "*")))
1980    (set (attr "prefix")
1981      (if_then_else (eq_attr "type" "sselog1,ssemov")
1982        (const_string "maybe_vex")
1983        (const_string "orig")))
1984    (set (attr "prefix_data16")
1985      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
1986        (const_string "1")
1987        (const_string "*")))
1988    (set (attr "mode")
1989      (cond [(eq_attr "alternative" "2")
1990               (const_string "SI")
1991             (eq_attr "alternative" "12,13")
1992               (cond [(ior (not (match_test "TARGET_SSE2"))
1993                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1994                        (const_string "V4SF")
1995                      (match_test "TARGET_AVX")
1996                        (const_string "TI")
1997                      (match_test "optimize_function_for_size_p (cfun)")
1998                        (const_string "V4SF")
1999                     ]
2000                     (const_string "TI"))
2002             (and (eq_attr "alternative" "14,15")
2003                  (not (match_test "TARGET_SSE2")))
2004               (const_string "V2SF")
2005             (eq_attr "alternative" "17")
2006               (const_string "TI")
2007            ]
2008            (const_string "DI")))])
2010 (define_split
2011   [(set (match_operand:DI 0 "nonimmediate_operand")
2012         (match_operand:DI 1 "general_operand"))]
2013   "!TARGET_64BIT && reload_completed
2014    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2015    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2016   [(const_int 0)]
2017   "ix86_split_long_move (operands); DONE;")
2019 (define_insn "*movsi_internal"
2020   [(set (match_operand:SI 0 "nonimmediate_operand"
2021                         "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?r,?*Yi")
2022         (match_operand:SI 1 "general_operand"
2023                         "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yj,*x,r"))]
2024   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2026   switch (get_attr_type (insn))
2027     {
2028     case TYPE_SSELOG1:
2029       if (GENERAL_REG_P (operands[0]))
2030         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2032       return standard_sse_constant_opcode (insn, operands[1]);
2034     case TYPE_SSEMOV:
2035       switch (get_attr_mode (insn))
2036         {
2037         case MODE_SI:
2038           return "%vmovd\t{%1, %0|%0, %1}";
2039         case MODE_TI:
2040           return "%vmovdqa\t{%1, %0|%0, %1}";
2042         case MODE_V4SF:
2043           return "%vmovaps\t{%1, %0|%0, %1}";
2045         case MODE_SF:
2046           gcc_assert (!TARGET_AVX);
2047           return "movss\t{%1, %0|%0, %1}";
2049         default:
2050           gcc_unreachable ();
2051         }
2053     case TYPE_MMX:
2054       return "pxor\t%0, %0";
2056     case TYPE_MMXMOV:
2057       switch (get_attr_mode (insn))
2058         {
2059         case MODE_DI:
2060           return "movq\t{%1, %0|%0, %1}";
2061         case MODE_SI:
2062           return "movd\t{%1, %0|%0, %1}";
2064         default:
2065           gcc_unreachable ();
2066         }
2068     case TYPE_LEA:
2069       return "lea{l}\t{%E1, %0|%0, %E1}";
2071     case TYPE_IMOV:
2072       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2073       if (ix86_use_lea_for_mov (insn, operands))
2074         return "lea{l}\t{%E1, %0|%0, %E1}";
2075       else
2076         return "mov{l}\t{%1, %0|%0, %1}";
2078     default:
2079       gcc_unreachable ();
2080     }
2082   [(set (attr "isa")
2083      (if_then_else (eq_attr "alternative" "11")
2084        (const_string "sse4")
2085        (const_string "*")))
2086    (set (attr "type")
2087      (cond [(eq_attr "alternative" "2")
2088               (const_string "mmx")
2089             (eq_attr "alternative" "3,4,5")
2090               (const_string "mmxmov")
2091             (eq_attr "alternative" "6,11")
2092               (const_string "sselog1")
2093             (eq_attr "alternative" "7,8,9,10,12")
2094               (const_string "ssemov")
2095             (match_operand 1 "pic_32bit_operand")
2096               (const_string "lea")
2097            ]
2098            (const_string "imov")))
2099    (set (attr "length_immediate")
2100      (if_then_else (eq_attr "alternative" "11")
2101        (const_string "1")
2102        (const_string "*")))
2103    (set (attr "prefix_extra")
2104      (if_then_else (eq_attr "alternative" "11")
2105        (const_string "1")
2106        (const_string "*")))
2107    (set (attr "prefix")
2108      (if_then_else (eq_attr "type" "sselog1,ssemov")
2109        (const_string "maybe_vex")
2110        (const_string "orig")))
2111    (set (attr "prefix_data16")
2112      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2113        (const_string "1")
2114        (const_string "*")))
2115    (set (attr "mode")
2116      (cond [(eq_attr "alternative" "2,3")
2117               (const_string "DI")
2118             (eq_attr "alternative" "6,7")
2119               (cond [(ior (not (match_test "TARGET_SSE2"))
2120                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2121                        (const_string "V4SF")
2122                      (match_test "TARGET_AVX")
2123                        (const_string "TI")
2124                      (match_test "optimize_function_for_size_p (cfun)")
2125                        (const_string "V4SF")
2126                     ]
2127                     (const_string "TI"))
2129             (and (eq_attr "alternative" "8,9")
2130                  (not (match_test "TARGET_SSE2")))
2131               (const_string "SF")
2132             (eq_attr "alternative" "11")
2133               (const_string "TI")
2134            ]
2135            (const_string "SI")))])
2137 (define_insn "*movhi_internal"
2138   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
2139         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn"))]
2140   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2142   switch (get_attr_type (insn))
2143     {
2144     case TYPE_IMOVX:
2145       /* movzwl is faster than movw on p2 due to partial word stalls,
2146          though not as fast as an aligned movl.  */
2147       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2148     default:
2149       if (get_attr_mode (insn) == MODE_SI)
2150         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2151       else
2152         return "mov{w}\t{%1, %0|%0, %1}";
2153     }
2155   [(set (attr "type")
2156      (cond [(match_test "optimize_function_for_size_p (cfun)")
2157               (const_string "imov")
2158             (and (eq_attr "alternative" "0")
2159                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2160                       (not (match_test "TARGET_HIMODE_MATH"))))
2161               (const_string "imov")
2162             (and (eq_attr "alternative" "1,2")
2163                  (match_operand:HI 1 "aligned_operand"))
2164               (const_string "imov")
2165             (and (match_test "TARGET_MOVX")
2166                  (eq_attr "alternative" "0,2"))
2167               (const_string "imovx")
2168            ]
2169            (const_string "imov")))
2170     (set (attr "mode")
2171       (cond [(eq_attr "type" "imovx")
2172                (const_string "SI")
2173              (and (eq_attr "alternative" "1,2")
2174                   (match_operand:HI 1 "aligned_operand"))
2175                (const_string "SI")
2176              (and (eq_attr "alternative" "0")
2177                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2178                        (not (match_test "TARGET_HIMODE_MATH"))))
2179                (const_string "SI")
2180             ]
2181             (const_string "HI")))])
2183 ;; Situation is quite tricky about when to choose full sized (SImode) move
2184 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2185 ;; partial register dependency machines (such as AMD Athlon), where QImode
2186 ;; moves issue extra dependency and for partial register stalls machines
2187 ;; that don't use QImode patterns (and QImode move cause stall on the next
2188 ;; instruction).
2190 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2191 ;; register stall machines with, where we use QImode instructions, since
2192 ;; partial register stall can be caused there.  Then we use movzx.
2193 (define_insn "*movqi_internal"
2194   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2195         (match_operand:QI 1 "general_operand"      "q ,qn,qm,q,rn,qm,qn"))]
2196   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2198   switch (get_attr_type (insn))
2199     {
2200     case TYPE_IMOVX:
2201       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2202       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2203     default:
2204       if (get_attr_mode (insn) == MODE_SI)
2205         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2206       else
2207         return "mov{b}\t{%1, %0|%0, %1}";
2208     }
2210   [(set (attr "type")
2211      (cond [(and (eq_attr "alternative" "5")
2212                  (not (match_operand:QI 1 "aligned_operand")))
2213               (const_string "imovx")
2214             (match_test "optimize_function_for_size_p (cfun)")
2215               (const_string "imov")
2216             (and (eq_attr "alternative" "3")
2217                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2218                       (not (match_test "TARGET_QIMODE_MATH"))))
2219               (const_string "imov")
2220             (eq_attr "alternative" "3,5")
2221               (const_string "imovx")
2222             (and (match_test "TARGET_MOVX")
2223                  (eq_attr "alternative" "2"))
2224               (const_string "imovx")
2225            ]
2226            (const_string "imov")))
2227    (set (attr "mode")
2228       (cond [(eq_attr "alternative" "3,4,5")
2229                (const_string "SI")
2230              (eq_attr "alternative" "6")
2231                (const_string "QI")
2232              (eq_attr "type" "imovx")
2233                (const_string "SI")
2234              (and (eq_attr "type" "imov")
2235                   (and (eq_attr "alternative" "0,1")
2236                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2237                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2238                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2239                (const_string "SI")
2240              ;; Avoid partial register stalls when not using QImode arithmetic
2241              (and (eq_attr "type" "imov")
2242                   (and (eq_attr "alternative" "0,1")
2243                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2244                             (not (match_test "TARGET_QIMODE_MATH")))))
2245                (const_string "SI")
2246            ]
2247            (const_string "QI")))])
2249 ;; Stores and loads of ax to arbitrary constant address.
2250 ;; We fake an second form of instruction to force reload to load address
2251 ;; into register when rax is not available
2252 (define_insn "*movabs<mode>_1"
2253   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2254         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2255   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2256   "@
2257    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2258    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2259   [(set_attr "type" "imov")
2260    (set_attr "modrm" "0,*")
2261    (set_attr "length_address" "8,0")
2262    (set_attr "length_immediate" "0,*")
2263    (set_attr "memory" "store")
2264    (set_attr "mode" "<MODE>")])
2266 (define_insn "*movabs<mode>_2"
2267   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2268         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2269   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2270   "@
2271    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2272    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2273   [(set_attr "type" "imov")
2274    (set_attr "modrm" "0,*")
2275    (set_attr "length_address" "8,0")
2276    (set_attr "length_immediate" "0")
2277    (set_attr "memory" "load")
2278    (set_attr "mode" "<MODE>")])
2280 (define_insn "swap<mode>"
2281   [(set (match_operand:SWI48 0 "register_operand" "+r")
2282         (match_operand:SWI48 1 "register_operand" "+r"))
2283    (set (match_dup 1)
2284         (match_dup 0))]
2285   ""
2286   "xchg{<imodesuffix>}\t%1, %0"
2287   [(set_attr "type" "imov")
2288    (set_attr "mode" "<MODE>")
2289    (set_attr "pent_pair" "np")
2290    (set_attr "athlon_decode" "vector")
2291    (set_attr "amdfam10_decode" "double")
2292    (set_attr "bdver1_decode" "double")])
2294 (define_insn "*swap<mode>_1"
2295   [(set (match_operand:SWI12 0 "register_operand" "+r")
2296         (match_operand:SWI12 1 "register_operand" "+r"))
2297    (set (match_dup 1)
2298         (match_dup 0))]
2299   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2300   "xchg{l}\t%k1, %k0"
2301   [(set_attr "type" "imov")
2302    (set_attr "mode" "SI")
2303    (set_attr "pent_pair" "np")
2304    (set_attr "athlon_decode" "vector")
2305    (set_attr "amdfam10_decode" "double")
2306    (set_attr "bdver1_decode" "double")])
2308 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2309 ;; is disabled for AMDFAM10
2310 (define_insn "*swap<mode>_2"
2311   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2312         (match_operand:SWI12 1 "register_operand" "+<r>"))
2313    (set (match_dup 1)
2314         (match_dup 0))]
2315   "TARGET_PARTIAL_REG_STALL"
2316   "xchg{<imodesuffix>}\t%1, %0"
2317   [(set_attr "type" "imov")
2318    (set_attr "mode" "<MODE>")
2319    (set_attr "pent_pair" "np")
2320    (set_attr "athlon_decode" "vector")])
2322 (define_expand "movstrict<mode>"
2323   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2324         (match_operand:SWI12 1 "general_operand"))]
2325   ""
2327   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2328     FAIL;
2329   if (GET_CODE (operands[0]) == SUBREG
2330       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2331     FAIL;
2332   /* Don't generate memory->memory moves, go through a register */
2333   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2334     operands[1] = force_reg (<MODE>mode, operands[1]);
2337 (define_insn "*movstrict<mode>_1"
2338   [(set (strict_low_part
2339           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2340         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2341   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2342    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2343   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2344   [(set_attr "type" "imov")
2345    (set_attr "mode" "<MODE>")])
2347 (define_insn "*movstrict<mode>_xor"
2348   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2349         (match_operand:SWI12 1 "const0_operand"))
2350    (clobber (reg:CC FLAGS_REG))]
2351   "reload_completed"
2352   "xor{<imodesuffix>}\t%0, %0"
2353   [(set_attr "type" "alu1")
2354    (set_attr "mode" "<MODE>")
2355    (set_attr "length_immediate" "0")])
2357 (define_insn "*mov<mode>_extv_1"
2358   [(set (match_operand:SWI24 0 "register_operand" "=R")
2359         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2360                             (const_int 8)
2361                             (const_int 8)))]
2362   ""
2363   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2364   [(set_attr "type" "imovx")
2365    (set_attr "mode" "SI")])
2367 (define_insn "*movqi_extv_1"
2368   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2369         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2370                          (const_int 8)
2371                          (const_int 8)))]
2372   ""
2374   switch (get_attr_type (insn))
2375     {
2376     case TYPE_IMOVX:
2377       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2378     default:
2379       return "mov{b}\t{%h1, %0|%0, %h1}";
2380     }
2382   [(set_attr "isa" "*,*,nox64")
2383    (set (attr "type")
2384      (if_then_else (and (match_operand:QI 0 "register_operand")
2385                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2386                              (match_test "TARGET_MOVX")))
2387         (const_string "imovx")
2388         (const_string "imov")))
2389    (set (attr "mode")
2390      (if_then_else (eq_attr "type" "imovx")
2391         (const_string "SI")
2392         (const_string "QI")))])
2394 (define_insn "*mov<mode>_extzv_1"
2395   [(set (match_operand:SWI48 0 "register_operand" "=R")
2396         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2397                             (const_int 8)
2398                             (const_int 8)))]
2399   ""
2400   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2401   [(set_attr "type" "imovx")
2402    (set_attr "mode" "SI")])
2404 (define_insn "*movqi_extzv_2"
2405   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2406         (subreg:QI
2407           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2408                            (const_int 8)
2409                            (const_int 8)) 0))]
2410   ""
2412   switch (get_attr_type (insn))
2413     {
2414     case TYPE_IMOVX:
2415       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2416     default:
2417       return "mov{b}\t{%h1, %0|%0, %h1}";
2418     }
2420   [(set_attr "isa" "*,*,nox64")
2421    (set (attr "type")
2422      (if_then_else (and (match_operand:QI 0 "register_operand")
2423                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2424                              (match_test "TARGET_MOVX")))
2425         (const_string "imovx")
2426         (const_string "imov")))
2427    (set (attr "mode")
2428      (if_then_else (eq_attr "type" "imovx")
2429         (const_string "SI")
2430         (const_string "QI")))])
2432 (define_insn "mov<mode>_insv_1"
2433   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2434                              (const_int 8)
2435                              (const_int 8))
2436         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2437   ""
2439   if (CONST_INT_P (operands[1]))
2440     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2441   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2443   [(set_attr "isa" "*,nox64")
2444    (set_attr "type" "imov")
2445    (set_attr "mode" "QI")])
2447 (define_insn "*movqi_insv_2"
2448   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2449                          (const_int 8)
2450                          (const_int 8))
2451         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2452                      (const_int 8)))]
2453   ""
2454   "mov{b}\t{%h1, %h0|%h0, %h1}"
2455   [(set_attr "type" "imov")
2456    (set_attr "mode" "QI")])
2458 ;; Floating point push instructions.
2460 (define_insn "*pushtf"
2461   [(set (match_operand:TF 0 "push_operand" "=<,<")
2462         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2463   "TARGET_64BIT || TARGET_SSE"
2465   /* This insn should be already split before reg-stack.  */
2466   gcc_unreachable ();
2468   [(set_attr "isa" "*,x64")
2469    (set_attr "type" "multi")
2470    (set_attr "unit" "sse,*")
2471    (set_attr "mode" "TF,DI")])
2473 ;; %%% Kill this when call knows how to work this out.
2474 (define_split
2475   [(set (match_operand:TF 0 "push_operand")
2476         (match_operand:TF 1 "sse_reg_operand"))]
2477   "TARGET_SSE && reload_completed"
2478   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2479    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2481 (define_insn "*pushxf"
2482   [(set (match_operand:XF 0 "push_operand" "=<,<")
2483         (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2484   ""
2486   /* This insn should be already split before reg-stack.  */
2487   gcc_unreachable ();
2489   [(set_attr "type" "multi")
2490    (set_attr "unit" "i387,*")
2491    (set (attr "mode")
2492         (cond [(eq_attr "alternative" "1")
2493                  (if_then_else (match_test "TARGET_64BIT")
2494                    (const_string "DI")
2495                    (const_string "SI"))
2496               ]
2497               (const_string "XF")))])
2499 ;; %%% Kill this when call knows how to work this out.
2500 (define_split
2501   [(set (match_operand:XF 0 "push_operand")
2502         (match_operand:XF 1 "fp_register_operand"))]
2503   "reload_completed"
2504   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2505    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2506   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2508 (define_insn "*pushdf"
2509   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2510         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2511   ""
2513   /* This insn should be already split before reg-stack.  */
2514   gcc_unreachable ();
2516   [(set_attr "isa" "*,nox64,x64,sse2")
2517    (set_attr "type" "multi")
2518    (set_attr "unit" "i387,*,*,sse")
2519    (set_attr "mode" "DF,SI,DI,DF")])
2521 ;; %%% Kill this when call knows how to work this out.
2522 (define_split
2523   [(set (match_operand:DF 0 "push_operand")
2524         (match_operand:DF 1 "any_fp_register_operand"))]
2525   "reload_completed"
2526   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2527    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2529 (define_insn "*pushsf_rex64"
2530   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2531         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2532   "TARGET_64BIT"
2534   /* Anything else should be already split before reg-stack.  */
2535   gcc_assert (which_alternative == 1);
2536   return "push{q}\t%q1";
2538   [(set_attr "type" "multi,push,multi")
2539    (set_attr "unit" "i387,*,*")
2540    (set_attr "mode" "SF,DI,SF")])
2542 (define_insn "*pushsf"
2543   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2544         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2545   "!TARGET_64BIT"
2547   /* Anything else should be already split before reg-stack.  */
2548   gcc_assert (which_alternative == 1);
2549   return "push{l}\t%1";
2551   [(set_attr "type" "multi,push,multi")
2552    (set_attr "unit" "i387,*,*")
2553    (set_attr "mode" "SF,SI,SF")])
2555 ;; %%% Kill this when call knows how to work this out.
2556 (define_split
2557   [(set (match_operand:SF 0 "push_operand")
2558         (match_operand:SF 1 "any_fp_register_operand"))]
2559   "reload_completed"
2560   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2561    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2562   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2564 (define_split
2565   [(set (match_operand:SF 0 "push_operand")
2566         (match_operand:SF 1 "memory_operand"))]
2567   "reload_completed
2568    && (operands[2] = find_constant_src (insn))"
2569   [(set (match_dup 0) (match_dup 2))])
2571 (define_split
2572   [(set (match_operand 0 "push_operand")
2573         (match_operand 1 "general_operand"))]
2574   "reload_completed
2575    && (GET_MODE (operands[0]) == TFmode
2576        || GET_MODE (operands[0]) == XFmode
2577        || GET_MODE (operands[0]) == DFmode)
2578    && !ANY_FP_REG_P (operands[1])"
2579   [(const_int 0)]
2580   "ix86_split_long_move (operands); DONE;")
2582 ;; Floating point move instructions.
2584 (define_expand "movtf"
2585   [(set (match_operand:TF 0 "nonimmediate_operand")
2586         (match_operand:TF 1 "nonimmediate_operand"))]
2587   "TARGET_64BIT || TARGET_SSE"
2588   "ix86_expand_move (TFmode, operands); DONE;")
2590 (define_expand "mov<mode>"
2591   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2592         (match_operand:X87MODEF 1 "general_operand"))]
2593   ""
2594   "ix86_expand_move (<MODE>mode, operands); DONE;")
2596 (define_insn "*movtf_internal"
2597   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2598         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2599   "(TARGET_64BIT || TARGET_SSE)
2600    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2601    && (!can_create_pseudo_p ()
2602        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2603        || GET_CODE (operands[1]) != CONST_DOUBLE
2604        || (optimize_function_for_size_p (cfun)
2605            && standard_sse_constant_p (operands[1])
2606            && !memory_operand (operands[0], TFmode))
2607        || (!TARGET_MEMORY_MISMATCH_STALL
2608            && memory_operand (operands[0], TFmode)))"
2610   switch (get_attr_type (insn))
2611     {
2612     case TYPE_SSELOG1:
2613       return standard_sse_constant_opcode (insn, operands[1]);
2615     case TYPE_SSEMOV:
2616       /* Handle misaligned load/store since we
2617          don't have movmisaligntf pattern. */
2618       if (misaligned_operand (operands[0], TFmode)
2619           || misaligned_operand (operands[1], TFmode))
2620         {
2621           if (get_attr_mode (insn) == MODE_V4SF)
2622             return "%vmovups\t{%1, %0|%0, %1}";
2623           else
2624             return "%vmovdqu\t{%1, %0|%0, %1}";
2625         }
2626       else
2627         {
2628           if (get_attr_mode (insn) == MODE_V4SF)
2629             return "%vmovaps\t{%1, %0|%0, %1}";
2630           else
2631             return "%vmovdqa\t{%1, %0|%0, %1}";
2632         }
2634     case TYPE_MULTI:
2635         return "#";
2637     default:
2638       gcc_unreachable ();
2639     }
2641   [(set_attr "isa" "*,*,*,x64,x64")
2642    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2643    (set (attr "prefix")
2644      (if_then_else (eq_attr "type" "sselog1,ssemov")
2645        (const_string "maybe_vex")
2646        (const_string "orig")))
2647    (set (attr "mode")
2648         (cond [(eq_attr "alternative" "3,4")
2649                  (const_string "DI")
2650                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2651                  (const_string "V4SF")
2652                (and (eq_attr "alternative" "2")
2653                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2654                  (const_string "V4SF")
2655                (match_test "TARGET_AVX")
2656                  (const_string "TI")
2657                (ior (not (match_test "TARGET_SSE2"))
2658                     (match_test "optimize_function_for_size_p (cfun)"))
2659                  (const_string "V4SF")
2660                ]
2661                (const_string "TI")))])
2663 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2664 (define_insn "*movxf_internal"
2665   [(set (match_operand:XF 0 "nonimmediate_operand"
2666          "=f,m,f,?Yx*r ,!o   ,!o")
2667         (match_operand:XF 1 "general_operand"
2668          "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2669   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2670    && (!can_create_pseudo_p ()
2671        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2672        || GET_CODE (operands[1]) != CONST_DOUBLE
2673        || (optimize_function_for_size_p (cfun)
2674            && standard_80387_constant_p (operands[1]) > 0
2675            && !memory_operand (operands[0], XFmode))
2676        || (!TARGET_MEMORY_MISMATCH_STALL
2677            && memory_operand (operands[0], XFmode)))"
2679   switch (get_attr_type (insn))
2680     {
2681     case TYPE_FMOV:
2682       if (which_alternative == 2)
2683         return standard_80387_constant_opcode (operands[1]);
2684       return output_387_reg_move (insn, operands);
2686     case TYPE_MULTI:
2687       return "#";
2689     default:
2690       gcc_unreachable ();
2691     }
2693   [(set_attr "isa" "*,*,*,*,nox64,x64")
2694    (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2695    (set (attr "mode")
2696         (cond [(eq_attr "alternative" "3,4,5")
2697                  (if_then_else (match_test "TARGET_64BIT")
2698                    (const_string "DI")
2699                    (const_string "SI"))
2700               ]
2701               (const_string "XF")))])
2703 ;; Possible store forwarding (partial memory) stall in alternative 4.
2704 (define_insn "*movdf_internal"
2705   [(set (match_operand:DF 0 "nonimmediate_operand"
2706     "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,?r,?m,?r,?r,x,x,x,m,*x,*x,*x,m ,r ,Yi")
2707         (match_operand:DF 1 "general_operand"
2708     "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,x,m,x,C ,*x,m ,*x,Yj,r"))]
2709   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2710    && (!can_create_pseudo_p ()
2711        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2712        || GET_CODE (operands[1]) != CONST_DOUBLE
2713        || (optimize_function_for_size_p (cfun)
2714            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2715                 && standard_80387_constant_p (operands[1]) > 0)
2716                || (TARGET_SSE2 && TARGET_SSE_MATH
2717                    && standard_sse_constant_p (operands[1])))
2718            && !memory_operand (operands[0], DFmode))
2719        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2720            && memory_operand (operands[0], DFmode)))"
2722   switch (get_attr_type (insn))
2723     {
2724     case TYPE_FMOV:
2725       if (which_alternative == 2)
2726         return standard_80387_constant_opcode (operands[1]);
2727       return output_387_reg_move (insn, operands);
2729     case TYPE_MULTI:
2730       return "#";
2732     case TYPE_IMOV:
2733       if (get_attr_mode (insn) == MODE_SI)
2734         return "mov{l}\t{%1, %k0|%k0, %1}";
2735       else if (which_alternative == 8)
2736         return "movabs{q}\t{%1, %0|%0, %1}";
2737       else
2738         return "mov{q}\t{%1, %0|%0, %1}";
2740     case TYPE_SSELOG1:
2741       return standard_sse_constant_opcode (insn, operands[1]);
2743     case TYPE_SSEMOV:
2744       switch (get_attr_mode (insn))
2745         {
2746         case MODE_DF:
2747           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2748             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2749           return "%vmovsd\t{%1, %0|%0, %1}";
2751         case MODE_V4SF:
2752           return "%vmovaps\t{%1, %0|%0, %1}";
2753         case MODE_V2DF:
2754           return "%vmovapd\t{%1, %0|%0, %1}";
2756         case MODE_V2SF:
2757           gcc_assert (!TARGET_AVX);
2758           return "movlps\t{%1, %0|%0, %1}";
2759         case MODE_V1DF:
2760           gcc_assert (!TARGET_AVX);
2761           return "movlpd\t{%1, %0|%0, %1}";
2763         case MODE_DI:
2764 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2765           /* Handle broken assemblers that require movd instead of movq.  */
2766           if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2767             return "%vmovd\t{%1, %0|%0, %1}";
2768 #endif
2769           return "%vmovq\t{%1, %0|%0, %1}";
2771         default:
2772           gcc_unreachable ();
2773         }
2775     default:
2776       gcc_unreachable ();
2777     }
2779   [(set (attr "isa")
2780         (cond [(eq_attr "alternative" "3,4")
2781                  (const_string "nox64")
2782                (eq_attr "alternative" "5,6,7,8,17,18")
2783                  (const_string "x64")
2784                (eq_attr "alternative" "9,10,11,12")
2785                  (const_string "sse2")
2786               ]
2787               (const_string "*")))
2788    (set (attr "type")
2789         (cond [(eq_attr "alternative" "0,1,2")
2790                  (const_string "fmov")
2791                (eq_attr "alternative" "3,4")
2792                  (const_string "multi")
2793                (eq_attr "alternative" "5,6,7,8")
2794                  (const_string "imov")
2795                (eq_attr "alternative" "9,13")
2796                  (const_string "sselog1")
2797               ]
2798               (const_string "ssemov")))
2799    (set (attr "modrm")
2800      (if_then_else (eq_attr "alternative" "8")
2801        (const_string "0")
2802        (const_string "*")))
2803    (set (attr "length_immediate")
2804      (if_then_else (eq_attr "alternative" "8")
2805        (const_string "8")
2806        (const_string "*")))
2807    (set (attr "prefix")
2808      (if_then_else (eq_attr "type" "sselog1,ssemov")
2809        (const_string "maybe_vex")
2810        (const_string "orig")))
2811    (set (attr "prefix_data16")
2812      (if_then_else
2813        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2814             (eq_attr "mode" "V1DF"))
2815        (const_string "1")
2816        (const_string "*")))
2817    (set (attr "mode")
2818         (cond [(eq_attr "alternative" "3,4,7")
2819                  (const_string "SI")
2820                (eq_attr "alternative" "5,6,8,17,18")
2821                  (const_string "DI")
2823                /* xorps is one byte shorter for non-AVX targets.  */
2824                (eq_attr "alternative" "9,13")
2825                  (cond [(not (match_test "TARGET_SSE2"))
2826                           (const_string "V4SF")
2827                         (match_test "TARGET_AVX")
2828                           (const_string "V2DF")
2829                         (match_test "optimize_function_for_size_p (cfun)")
2830                           (const_string "V4SF")
2831                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2832                           (const_string "TI")
2833                        ]
2834                        (const_string "V2DF"))
2836                /* For architectures resolving dependencies on
2837                   whole SSE registers use movapd to break dependency
2838                   chains, otherwise use short move to avoid extra work.  */
2840                /* movaps is one byte shorter for non-AVX targets.  */
2841                (eq_attr "alternative" "10,14")
2842                  (cond [(ior (not (match_test "TARGET_SSE2"))
2843                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2844                           (const_string "V4SF")
2845                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2846                           (const_string "V2DF")
2847                         (match_test "TARGET_AVX")
2848                           (const_string "DF")
2849                         (match_test "optimize_function_for_size_p (cfun)")
2850                           (const_string "V4SF")
2851                        ]
2852                        (const_string "DF"))
2854                /* For architectures resolving dependencies on register
2855                   parts we may avoid extra work to zero out upper part
2856                   of register.  */
2857                (eq_attr "alternative" "11,15")
2858                  (cond [(not (match_test "TARGET_SSE2"))
2859                           (const_string "V2SF")
2860                         (match_test "TARGET_AVX")
2861                           (const_string "DF")
2862                         (match_test "TARGET_SSE_SPLIT_REGS")
2863                           (const_string "V1DF")
2864                        ]
2865                        (const_string "DF"))
2867                (and (eq_attr "alternative" "12,16")
2868                     (not (match_test "TARGET_SSE2")))
2869                  (const_string "V2SF")
2870               ]
2871               (const_string "DF")))])
2873 (define_insn "*movsf_internal"
2874   [(set (match_operand:SF 0 "nonimmediate_operand"
2875           "=Yf*f,m   ,Yf*f,?r ,?m,x,x,x,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
2876         (match_operand:SF 1 "general_operand"
2877           "Yf*fm,Yf*f,G   ,rmF,rF,C,x,m,x,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
2878   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2879    && (!can_create_pseudo_p ()
2880        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2881        || GET_CODE (operands[1]) != CONST_DOUBLE
2882        || (optimize_function_for_size_p (cfun)
2883            && ((!TARGET_SSE_MATH
2884                 && standard_80387_constant_p (operands[1]) > 0)
2885                || (TARGET_SSE_MATH
2886                    && standard_sse_constant_p (operands[1]))))
2887        || memory_operand (operands[0], SFmode))"
2889   switch (get_attr_type (insn))
2890     {
2891     case TYPE_FMOV:
2892       if (which_alternative == 2)
2893         return standard_80387_constant_opcode (operands[1]);
2894       return output_387_reg_move (insn, operands);
2896     case TYPE_IMOV:
2897       return "mov{l}\t{%1, %0|%0, %1}";
2899     case TYPE_SSELOG1:
2900       return standard_sse_constant_opcode (insn, operands[1]);
2902     case TYPE_SSEMOV:
2903       switch (get_attr_mode (insn))
2904         {
2905         case MODE_SF:
2906           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2907             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
2908           return "%vmovss\t{%1, %0|%0, %1}";
2910         case MODE_V4SF:
2911           return "%vmovaps\t{%1, %0|%0, %1}";
2913         case MODE_SI:
2914           return "%vmovd\t{%1, %0|%0, %1}";
2916         default:
2917           gcc_unreachable ();
2918         }
2920     case TYPE_MMXMOV:
2921       switch (get_attr_mode (insn))
2922         {
2923         case MODE_DI:
2924           return "movq\t{%1, %0|%0, %1}";
2925         case MODE_SI:
2926           return "movd\t{%1, %0|%0, %1}";
2928         default:
2929           gcc_unreachable ();
2930         }
2932     default:
2933       gcc_unreachable ();
2934     }
2936   [(set (attr "type")
2937         (cond [(eq_attr "alternative" "0,1,2")
2938                  (const_string "fmov")
2939                (eq_attr "alternative" "3,4")
2940                  (const_string "imov")
2941                (eq_attr "alternative" "5")
2942                  (const_string "sselog1")
2943                (eq_attr "alternative" "11,12,13,14,15")
2944                  (const_string "mmxmov")
2945               ]
2946               (const_string "ssemov")))
2947    (set (attr "prefix")
2948      (if_then_else (eq_attr "type" "sselog1,ssemov")
2949        (const_string "maybe_vex")
2950        (const_string "orig")))
2951    (set (attr "prefix_data16")
2952      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2953        (const_string "1")
2954        (const_string "*")))
2955    (set (attr "mode")
2956         (cond [(eq_attr "alternative" "3,4,9,10,14,15")
2957                  (const_string "SI")
2958                (eq_attr "alternative" "11")
2959                  (const_string "DI")
2960                (eq_attr "alternative" "5")
2961                  (cond [(not (match_test "TARGET_SSE2"))
2962                           (const_string "V4SF")
2963                         (match_test "TARGET_AVX")
2964                           (const_string "V4SF")
2965                         (match_test "optimize_function_for_size_p (cfun)")
2966                           (const_string "V4SF")
2967                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2968                           (const_string "TI")
2969                        ]
2970                        (const_string "V4SF"))
2972                /* For architectures resolving dependencies on
2973                   whole SSE registers use APS move to break dependency
2974                   chains, otherwise use short move to avoid extra work.
2976                   Do the same for architectures resolving dependencies on
2977                   the parts.  While in DF mode it is better to always handle
2978                   just register parts, the SF mode is different due to lack
2979                   of instructions to load just part of the register.  It is
2980                   better to maintain the whole registers in single format
2981                   to avoid problems on using packed logical operations.  */
2982                (and (eq_attr "alternative" "6")
2983                     (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2984                          (match_test "TARGET_SSE_SPLIT_REGS")))
2985                  (const_string "V4SF")
2986               ]
2987               (const_string "SF")))])
2989 (define_split
2990   [(set (match_operand 0 "any_fp_register_operand")
2991         (match_operand 1 "memory_operand"))]
2992   "reload_completed
2993    && (GET_MODE (operands[0]) == TFmode
2994        || GET_MODE (operands[0]) == XFmode
2995        || GET_MODE (operands[0]) == DFmode
2996        || GET_MODE (operands[0]) == SFmode)
2997    && (operands[2] = find_constant_src (insn))"
2998   [(set (match_dup 0) (match_dup 2))]
3000   rtx c = operands[2];
3001   int r = REGNO (operands[0]);
3003   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3004       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3005     FAIL;
3008 (define_split
3009   [(set (match_operand 0 "any_fp_register_operand")
3010         (float_extend (match_operand 1 "memory_operand")))]
3011   "reload_completed
3012    && (GET_MODE (operands[0]) == TFmode
3013        || GET_MODE (operands[0]) == XFmode
3014        || GET_MODE (operands[0]) == DFmode)
3015    && (operands[2] = find_constant_src (insn))"
3016   [(set (match_dup 0) (match_dup 2))]
3018   rtx c = operands[2];
3019   int r = REGNO (operands[0]);
3021   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3022       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3023     FAIL;
3026 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3027 (define_split
3028   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3029         (match_operand:X87MODEF 1 "immediate_operand"))]
3030   "reload_completed
3031    && (standard_80387_constant_p (operands[1]) == 8
3032        || standard_80387_constant_p (operands[1]) == 9)"
3033   [(set (match_dup 0)(match_dup 1))
3034    (set (match_dup 0)
3035         (neg:X87MODEF (match_dup 0)))]
3037   REAL_VALUE_TYPE r;
3039   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3040   if (real_isnegzero (&r))
3041     operands[1] = CONST0_RTX (<MODE>mode);
3042   else
3043     operands[1] = CONST1_RTX (<MODE>mode);
3046 (define_split
3047   [(set (match_operand 0 "nonimmediate_operand")
3048         (match_operand 1 "general_operand"))]
3049   "reload_completed
3050    && (GET_MODE (operands[0]) == TFmode
3051        || GET_MODE (operands[0]) == XFmode
3052        || GET_MODE (operands[0]) == DFmode)
3053    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3054   [(const_int 0)]
3055   "ix86_split_long_move (operands); DONE;")
3057 (define_insn "swapxf"
3058   [(set (match_operand:XF 0 "register_operand" "+f")
3059         (match_operand:XF 1 "register_operand" "+f"))
3060    (set (match_dup 1)
3061         (match_dup 0))]
3062   "TARGET_80387"
3064   if (STACK_TOP_P (operands[0]))
3065     return "fxch\t%1";
3066   else
3067     return "fxch\t%0";
3069   [(set_attr "type" "fxch")
3070    (set_attr "mode" "XF")])
3072 (define_insn "*swap<mode>"
3073   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3074         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3075    (set (match_dup 1)
3076         (match_dup 0))]
3077   "TARGET_80387 || reload_completed"
3079   if (STACK_TOP_P (operands[0]))
3080     return "fxch\t%1";
3081   else
3082     return "fxch\t%0";
3084   [(set_attr "type" "fxch")
3085    (set_attr "mode" "<MODE>")])
3087 ;; Zero extension instructions
3089 (define_expand "zero_extendsidi2"
3090   [(set (match_operand:DI 0 "nonimmediate_operand")
3091         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3093 (define_insn "*zero_extendsidi2"
3094   [(set (match_operand:DI 0 "nonimmediate_operand"
3095                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3096         (zero_extend:DI
3097          (match_operand:SI 1 "x86_64_zext_operand"
3098                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3099   ""
3101   switch (get_attr_type (insn))
3102     {
3103     case TYPE_IMOVX:
3104       if (ix86_use_lea_for_mov (insn, operands))
3105         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3106       else
3107         return "mov{l}\t{%1, %k0|%k0, %1}";
3109     case TYPE_MULTI:
3110       return "#";
3112     case TYPE_MMXMOV:
3113       return "movd\t{%1, %0|%0, %1}";
3115     case TYPE_SSELOG1:
3116       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3118     case TYPE_SSEMOV:
3119       if (GENERAL_REG_P (operands[0]))
3120         return "%vmovd\t{%1, %k0|%k0, %1}";
3122       return "%vmovd\t{%1, %0|%0, %1}";
3124     default:
3125       gcc_unreachable ();
3126     }
3128   [(set (attr "isa")
3129      (cond [(eq_attr "alternative" "0,1,2")
3130               (const_string "nox64")
3131             (eq_attr "alternative" "3,7")
3132               (const_string "x64")
3133             (eq_attr "alternative" "8")
3134               (const_string "x64_sse4")
3135             (eq_attr "alternative" "10")
3136               (const_string "sse2")
3137            ]
3138            (const_string "*")))
3139    (set (attr "type")
3140      (cond [(eq_attr "alternative" "0,1,2,4")
3141               (const_string "multi")
3142             (eq_attr "alternative" "5,6")
3143               (const_string "mmxmov")
3144             (eq_attr "alternative" "7,9,10")
3145               (const_string "ssemov")
3146             (eq_attr "alternative" "8")
3147               (const_string "sselog1")
3148            ]
3149            (const_string "imovx")))
3150    (set (attr "prefix_extra")
3151      (if_then_else (eq_attr "alternative" "8")
3152        (const_string "1")
3153        (const_string "*")))
3154    (set (attr "length_immediate")
3155      (if_then_else (eq_attr "alternative" "8")
3156        (const_string "1")
3157        (const_string "*")))
3158    (set (attr "prefix")
3159      (if_then_else (eq_attr "type" "ssemov,sselog1")
3160        (const_string "maybe_vex")
3161        (const_string "orig")))
3162    (set (attr "prefix_0f")
3163      (if_then_else (eq_attr "type" "imovx")
3164        (const_string "0")
3165        (const_string "*")))
3166    (set (attr "mode")
3167      (cond [(eq_attr "alternative" "5,6")
3168               (const_string "DI")
3169             (eq_attr "alternative" "7,8,9")
3170               (const_string "TI")
3171            ]
3172            (const_string "SI")))])
3174 (define_split
3175   [(set (match_operand:DI 0 "memory_operand")
3176         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3177   "reload_completed"
3178   [(set (match_dup 4) (const_int 0))]
3179   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3181 (define_split
3182   [(set (match_operand:DI 0 "register_operand")
3183         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3184   "!TARGET_64BIT && reload_completed
3185    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3186    && true_regnum (operands[0]) == true_regnum (operands[1])"
3187   [(set (match_dup 4) (const_int 0))]
3188   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3190 (define_split
3191   [(set (match_operand:DI 0 "nonimmediate_operand")
3192         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3193   "!TARGET_64BIT && reload_completed
3194    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3195    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3196   [(set (match_dup 3) (match_dup 1))
3197    (set (match_dup 4) (const_int 0))]
3198   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3200 (define_insn "zero_extend<mode>di2"
3201   [(set (match_operand:DI 0 "register_operand" "=r")
3202         (zero_extend:DI
3203          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3204   "TARGET_64BIT"
3205   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3206   [(set_attr "type" "imovx")
3207    (set_attr "mode" "SI")])
3209 (define_expand "zero_extend<mode>si2"
3210   [(set (match_operand:SI 0 "register_operand")
3211         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3212   ""
3214   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3215     {
3216       operands[1] = force_reg (<MODE>mode, operands[1]);
3217       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3218       DONE;
3219     }
3222 (define_insn_and_split "zero_extend<mode>si2_and"
3223   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3224         (zero_extend:SI
3225           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3226    (clobber (reg:CC FLAGS_REG))]
3227   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3228   "#"
3229   "&& reload_completed"
3230   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3231               (clobber (reg:CC FLAGS_REG))])]
3233   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3234     {
3235       ix86_expand_clear (operands[0]);
3237       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3238       emit_insn (gen_movstrict<mode>
3239                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3240       DONE;
3241     }
3243   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3245   [(set_attr "type" "alu1")
3246    (set_attr "mode" "SI")])
3248 (define_insn "*zero_extend<mode>si2"
3249   [(set (match_operand:SI 0 "register_operand" "=r")
3250         (zero_extend:SI
3251           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3252   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3253   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3254   [(set_attr "type" "imovx")
3255    (set_attr "mode" "SI")])
3257 (define_expand "zero_extendqihi2"
3258   [(set (match_operand:HI 0 "register_operand")
3259         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3260   ""
3262   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3263     {
3264       operands[1] = force_reg (QImode, operands[1]);
3265       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3266       DONE;
3267     }
3270 (define_insn_and_split "zero_extendqihi2_and"
3271   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3272         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3273    (clobber (reg:CC FLAGS_REG))]
3274   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3275   "#"
3276   "&& reload_completed"
3277   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3278               (clobber (reg:CC FLAGS_REG))])]
3280   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3281     {
3282       ix86_expand_clear (operands[0]);
3284       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3285       emit_insn (gen_movstrictqi
3286                   (gen_lowpart (QImode, operands[0]), operands[1]));
3287       DONE;
3288     }
3290   operands[0] = gen_lowpart (SImode, operands[0]);
3292   [(set_attr "type" "alu1")
3293    (set_attr "mode" "SI")])
3295 ; zero extend to SImode to avoid partial register stalls
3296 (define_insn "*zero_extendqihi2"
3297   [(set (match_operand:HI 0 "register_operand" "=r")
3298         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3299   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3300   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3301   [(set_attr "type" "imovx")
3302    (set_attr "mode" "SI")])
3304 ;; Sign extension instructions
3306 (define_expand "extendsidi2"
3307   [(set (match_operand:DI 0 "register_operand")
3308         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3309   ""
3311   if (!TARGET_64BIT)
3312     {
3313       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3314       DONE;
3315     }
3318 (define_insn "*extendsidi2_rex64"
3319   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3320         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3321   "TARGET_64BIT"
3322   "@
3323    {cltq|cdqe}
3324    movs{lq|x}\t{%1, %0|%0, %1}"
3325   [(set_attr "type" "imovx")
3326    (set_attr "mode" "DI")
3327    (set_attr "prefix_0f" "0")
3328    (set_attr "modrm" "0,1")])
3330 (define_insn "extendsidi2_1"
3331   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3332         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3333    (clobber (reg:CC FLAGS_REG))
3334    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3335   "!TARGET_64BIT"
3336   "#")
3338 ;; Split the memory case.  If the source register doesn't die, it will stay
3339 ;; this way, if it does die, following peephole2s take care of it.
3340 (define_split
3341   [(set (match_operand:DI 0 "memory_operand")
3342         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3343    (clobber (reg:CC FLAGS_REG))
3344    (clobber (match_operand:SI 2 "register_operand"))]
3345   "reload_completed"
3346   [(const_int 0)]
3348   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3350   emit_move_insn (operands[3], operands[1]);
3352   /* Generate a cltd if possible and doing so it profitable.  */
3353   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3354       && true_regnum (operands[1]) == AX_REG
3355       && true_regnum (operands[2]) == DX_REG)
3356     {
3357       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3358     }
3359   else
3360     {
3361       emit_move_insn (operands[2], operands[1]);
3362       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3363     }
3364   emit_move_insn (operands[4], operands[2]);
3365   DONE;
3368 ;; Peepholes for the case where the source register does die, after
3369 ;; being split with the above splitter.
3370 (define_peephole2
3371   [(set (match_operand:SI 0 "memory_operand")
3372         (match_operand:SI 1 "register_operand"))
3373    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3374    (parallel [(set (match_dup 2)
3375                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3376                (clobber (reg:CC FLAGS_REG))])
3377    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3378   "REGNO (operands[1]) != REGNO (operands[2])
3379    && peep2_reg_dead_p (2, operands[1])
3380    && peep2_reg_dead_p (4, operands[2])
3381    && !reg_mentioned_p (operands[2], operands[3])"
3382   [(set (match_dup 0) (match_dup 1))
3383    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3384               (clobber (reg:CC FLAGS_REG))])
3385    (set (match_dup 3) (match_dup 1))])
3387 (define_peephole2
3388   [(set (match_operand:SI 0 "memory_operand")
3389         (match_operand:SI 1 "register_operand"))
3390    (parallel [(set (match_operand:SI 2 "register_operand")
3391                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3392                (clobber (reg:CC FLAGS_REG))])
3393    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3394   "/* cltd is shorter than sarl $31, %eax */
3395    !optimize_function_for_size_p (cfun)
3396    && true_regnum (operands[1]) == AX_REG
3397    && true_regnum (operands[2]) == DX_REG
3398    && peep2_reg_dead_p (2, operands[1])
3399    && peep2_reg_dead_p (3, operands[2])
3400    && !reg_mentioned_p (operands[2], operands[3])"
3401   [(set (match_dup 0) (match_dup 1))
3402    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3403               (clobber (reg:CC FLAGS_REG))])
3404    (set (match_dup 3) (match_dup 1))])
3406 ;; Extend to register case.  Optimize case where source and destination
3407 ;; registers match and cases where we can use cltd.
3408 (define_split
3409   [(set (match_operand:DI 0 "register_operand")
3410         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3411    (clobber (reg:CC FLAGS_REG))
3412    (clobber (match_scratch:SI 2))]
3413   "reload_completed"
3414   [(const_int 0)]
3416   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3418   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3419     emit_move_insn (operands[3], operands[1]);
3421   /* Generate a cltd if possible and doing so it profitable.  */
3422   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3423       && true_regnum (operands[3]) == AX_REG
3424       && true_regnum (operands[4]) == DX_REG)
3425     {
3426       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3427       DONE;
3428     }
3430   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3431     emit_move_insn (operands[4], operands[1]);
3433   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3434   DONE;
3437 (define_insn "extend<mode>di2"
3438   [(set (match_operand:DI 0 "register_operand" "=r")
3439         (sign_extend:DI
3440          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3441   "TARGET_64BIT"
3442   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3443   [(set_attr "type" "imovx")
3444    (set_attr "mode" "DI")])
3446 (define_insn "extendhisi2"
3447   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3448         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3449   ""
3451   switch (get_attr_prefix_0f (insn))
3452     {
3453     case 0:
3454       return "{cwtl|cwde}";
3455     default:
3456       return "movs{wl|x}\t{%1, %0|%0, %1}";
3457     }
3459   [(set_attr "type" "imovx")
3460    (set_attr "mode" "SI")
3461    (set (attr "prefix_0f")
3462      ;; movsx is short decodable while cwtl is vector decoded.
3463      (if_then_else (and (eq_attr "cpu" "!k6")
3464                         (eq_attr "alternative" "0"))
3465         (const_string "0")
3466         (const_string "1")))
3467    (set (attr "modrm")
3468      (if_then_else (eq_attr "prefix_0f" "0")
3469         (const_string "0")
3470         (const_string "1")))])
3472 (define_insn "*extendhisi2_zext"
3473   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3474         (zero_extend:DI
3475          (sign_extend:SI
3476           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3477   "TARGET_64BIT"
3479   switch (get_attr_prefix_0f (insn))
3480     {
3481     case 0:
3482       return "{cwtl|cwde}";
3483     default:
3484       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3485     }
3487   [(set_attr "type" "imovx")
3488    (set_attr "mode" "SI")
3489    (set (attr "prefix_0f")
3490      ;; movsx is short decodable while cwtl is vector decoded.
3491      (if_then_else (and (eq_attr "cpu" "!k6")
3492                         (eq_attr "alternative" "0"))
3493         (const_string "0")
3494         (const_string "1")))
3495    (set (attr "modrm")
3496      (if_then_else (eq_attr "prefix_0f" "0")
3497         (const_string "0")
3498         (const_string "1")))])
3500 (define_insn "extendqisi2"
3501   [(set (match_operand:SI 0 "register_operand" "=r")
3502         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3503   ""
3504   "movs{bl|x}\t{%1, %0|%0, %1}"
3505    [(set_attr "type" "imovx")
3506     (set_attr "mode" "SI")])
3508 (define_insn "*extendqisi2_zext"
3509   [(set (match_operand:DI 0 "register_operand" "=r")
3510         (zero_extend:DI
3511           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3512   "TARGET_64BIT"
3513   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3514    [(set_attr "type" "imovx")
3515     (set_attr "mode" "SI")])
3517 (define_insn "extendqihi2"
3518   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3519         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3520   ""
3522   switch (get_attr_prefix_0f (insn))
3523     {
3524     case 0:
3525       return "{cbtw|cbw}";
3526     default:
3527       return "movs{bw|x}\t{%1, %0|%0, %1}";
3528     }
3530   [(set_attr "type" "imovx")
3531    (set_attr "mode" "HI")
3532    (set (attr "prefix_0f")
3533      ;; movsx is short decodable while cwtl is vector decoded.
3534      (if_then_else (and (eq_attr "cpu" "!k6")
3535                         (eq_attr "alternative" "0"))
3536         (const_string "0")
3537         (const_string "1")))
3538    (set (attr "modrm")
3539      (if_then_else (eq_attr "prefix_0f" "0")
3540         (const_string "0")
3541         (const_string "1")))])
3543 ;; Conversions between float and double.
3545 ;; These are all no-ops in the model used for the 80387.
3546 ;; So just emit moves.
3548 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3549 (define_split
3550   [(set (match_operand:DF 0 "push_operand")
3551         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3552   "reload_completed"
3553   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3554    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3556 (define_split
3557   [(set (match_operand:XF 0 "push_operand")
3558         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3559   "reload_completed"
3560   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3561    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3562   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3564 (define_expand "extendsfdf2"
3565   [(set (match_operand:DF 0 "nonimmediate_operand")
3566         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3567   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3569   /* ??? Needed for compress_float_constant since all fp constants
3570      are TARGET_LEGITIMATE_CONSTANT_P.  */
3571   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3572     {
3573       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3574           && standard_80387_constant_p (operands[1]) > 0)
3575         {
3576           operands[1] = simplify_const_unary_operation
3577             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3578           emit_move_insn_1 (operands[0], operands[1]);
3579           DONE;
3580         }
3581       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3582     }
3585 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3586    cvtss2sd:
3587       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3588       cvtps2pd xmm2,xmm1
3589    We do the conversion post reload to avoid producing of 128bit spills
3590    that might lead to ICE on 32bit target.  The sequence unlikely combine
3591    anyway.  */
3592 (define_split
3593   [(set (match_operand:DF 0 "register_operand")
3594         (float_extend:DF
3595           (match_operand:SF 1 "nonimmediate_operand")))]
3596   "TARGET_USE_VECTOR_FP_CONVERTS
3597    && optimize_insn_for_speed_p ()
3598    && reload_completed && SSE_REG_P (operands[0])"
3599    [(set (match_dup 2)
3600          (float_extend:V2DF
3601            (vec_select:V2SF
3602              (match_dup 3)
3603              (parallel [(const_int 0) (const_int 1)]))))]
3605   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3606   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3607   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3608      Try to avoid move when unpacking can be done in source.  */
3609   if (REG_P (operands[1]))
3610     {
3611       /* If it is unsafe to overwrite upper half of source, we need
3612          to move to destination and unpack there.  */
3613       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3614            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3615           && true_regnum (operands[0]) != true_regnum (operands[1]))
3616         {
3617           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3618           emit_move_insn (tmp, operands[1]);
3619         }
3620       else
3621         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3622       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3623                                              operands[3]));
3624     }
3625   else
3626     emit_insn (gen_vec_setv4sf_0 (operands[3],
3627                                   CONST0_RTX (V4SFmode), operands[1]));
3630 ;; It's more profitable to split and then extend in the same register.
3631 (define_peephole2
3632   [(set (match_operand:DF 0 "register_operand")
3633         (float_extend:DF
3634           (match_operand:SF 1 "memory_operand")))]
3635   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3636    && optimize_insn_for_speed_p ()
3637    && SSE_REG_P (operands[0])"
3638   [(set (match_dup 2) (match_dup 1))
3639    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3640   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3642 (define_insn "*extendsfdf2_mixed"
3643   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3644         (float_extend:DF
3645           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3646   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3648   switch (which_alternative)
3649     {
3650     case 0:
3651     case 1:
3652       return output_387_reg_move (insn, operands);
3654     case 2:
3655       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3657     default:
3658       gcc_unreachable ();
3659     }
3661   [(set_attr "type" "fmov,fmov,ssecvt")
3662    (set_attr "prefix" "orig,orig,maybe_vex")
3663    (set_attr "mode" "SF,XF,DF")])
3665 (define_insn "*extendsfdf2_sse"
3666   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3667         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3668   "TARGET_SSE2 && TARGET_SSE_MATH"
3669   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3670   [(set_attr "type" "ssecvt")
3671    (set_attr "prefix" "maybe_vex")
3672    (set_attr "mode" "DF")])
3674 (define_insn "*extendsfdf2_i387"
3675   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3676         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3677   "TARGET_80387"
3678   "* return output_387_reg_move (insn, operands);"
3679   [(set_attr "type" "fmov")
3680    (set_attr "mode" "SF,XF")])
3682 (define_expand "extend<mode>xf2"
3683   [(set (match_operand:XF 0 "nonimmediate_operand")
3684         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3685   "TARGET_80387"
3687   /* ??? Needed for compress_float_constant since all fp constants
3688      are TARGET_LEGITIMATE_CONSTANT_P.  */
3689   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3690     {
3691       if (standard_80387_constant_p (operands[1]) > 0)
3692         {
3693           operands[1] = simplify_const_unary_operation
3694             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3695           emit_move_insn_1 (operands[0], operands[1]);
3696           DONE;
3697         }
3698       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3699     }
3702 (define_insn "*extend<mode>xf2_i387"
3703   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3704         (float_extend:XF
3705           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3706   "TARGET_80387"
3707   "* return output_387_reg_move (insn, operands);"
3708   [(set_attr "type" "fmov")
3709    (set_attr "mode" "<MODE>,XF")])
3711 ;; %%% This seems bad bad news.
3712 ;; This cannot output into an f-reg because there is no way to be sure
3713 ;; of truncating in that case.  Otherwise this is just like a simple move
3714 ;; insn.  So we pretend we can output to a reg in order to get better
3715 ;; register preferencing, but we really use a stack slot.
3717 ;; Conversion from DFmode to SFmode.
3719 (define_expand "truncdfsf2"
3720   [(set (match_operand:SF 0 "nonimmediate_operand")
3721         (float_truncate:SF
3722           (match_operand:DF 1 "nonimmediate_operand")))]
3723   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3725   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3726     ;
3727   else if (flag_unsafe_math_optimizations)
3728     ;
3729   else
3730     {
3731       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3732       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3733       DONE;
3734     }
3737 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3738    cvtsd2ss:
3739       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3740       cvtpd2ps xmm2,xmm1
3741    We do the conversion post reload to avoid producing of 128bit spills
3742    that might lead to ICE on 32bit target.  The sequence unlikely combine
3743    anyway.  */
3744 (define_split
3745   [(set (match_operand:SF 0 "register_operand")
3746         (float_truncate:SF
3747           (match_operand:DF 1 "nonimmediate_operand")))]
3748   "TARGET_USE_VECTOR_FP_CONVERTS
3749    && optimize_insn_for_speed_p ()
3750    && reload_completed && SSE_REG_P (operands[0])"
3751    [(set (match_dup 2)
3752          (vec_concat:V4SF
3753            (float_truncate:V2SF
3754              (match_dup 4))
3755            (match_dup 3)))]
3757   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3758   operands[3] = CONST0_RTX (V2SFmode);
3759   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3760   /* Use movsd for loading from memory, unpcklpd for registers.
3761      Try to avoid move when unpacking can be done in source, or SSE3
3762      movddup is available.  */
3763   if (REG_P (operands[1]))
3764     {
3765       if (!TARGET_SSE3
3766           && true_regnum (operands[0]) != true_regnum (operands[1])
3767           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3768               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3769         {
3770           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3771           emit_move_insn (tmp, operands[1]);
3772           operands[1] = tmp;
3773         }
3774       else if (!TARGET_SSE3)
3775         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3776       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3777     }
3778   else
3779     emit_insn (gen_sse2_loadlpd (operands[4],
3780                                  CONST0_RTX (V2DFmode), operands[1]));
3783 ;; It's more profitable to split and then extend in the same register.
3784 (define_peephole2
3785   [(set (match_operand:SF 0 "register_operand")
3786         (float_truncate:SF
3787           (match_operand:DF 1 "memory_operand")))]
3788   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3789    && optimize_insn_for_speed_p ()
3790    && SSE_REG_P (operands[0])"
3791   [(set (match_dup 2) (match_dup 1))
3792    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3793   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3795 (define_expand "truncdfsf2_with_temp"
3796   [(parallel [(set (match_operand:SF 0)
3797                    (float_truncate:SF (match_operand:DF 1)))
3798               (clobber (match_operand:SF 2))])])
3800 (define_insn "*truncdfsf_fast_mixed"
3801   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
3802         (float_truncate:SF
3803           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
3804   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3806   switch (which_alternative)
3807     {
3808     case 0:
3809       return output_387_reg_move (insn, operands);
3810     case 1:
3811       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3812     default:
3813       gcc_unreachable ();
3814     }
3816   [(set_attr "type" "fmov,ssecvt")
3817    (set_attr "prefix" "orig,maybe_vex")
3818    (set_attr "mode" "SF")])
3820 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3821 ;; because nothing we do here is unsafe.
3822 (define_insn "*truncdfsf_fast_sse"
3823   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3824         (float_truncate:SF
3825           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3826   "TARGET_SSE2 && TARGET_SSE_MATH"
3827   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
3828   [(set_attr "type" "ssecvt")
3829    (set_attr "prefix" "maybe_vex")
3830    (set_attr "mode" "SF")])
3832 (define_insn "*truncdfsf_fast_i387"
3833   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3834         (float_truncate:SF
3835           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3836   "TARGET_80387 && flag_unsafe_math_optimizations"
3837   "* return output_387_reg_move (insn, operands);"
3838   [(set_attr "type" "fmov")
3839    (set_attr "mode" "SF")])
3841 (define_insn "*truncdfsf_mixed"
3842   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
3843         (float_truncate:SF
3844           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
3845    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
3846   "TARGET_MIX_SSE_I387"
3848   switch (which_alternative)
3849     {
3850     case 0:
3851       return output_387_reg_move (insn, operands);
3852     case 1:
3853       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3855     default:
3856       return "#";
3857     }
3859   [(set_attr "isa" "*,sse2,*,*,*")
3860    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
3861    (set_attr "unit" "*,*,i387,i387,i387")
3862    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
3863    (set_attr "mode" "SF")])
3865 (define_insn "*truncdfsf_i387"
3866   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
3867         (float_truncate:SF
3868           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
3869    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
3870   "TARGET_80387"
3872   switch (which_alternative)
3873     {
3874     case 0:
3875       return output_387_reg_move (insn, operands);
3877     default:
3878       return "#";
3879     }
3881   [(set_attr "type" "fmov,multi,multi,multi")
3882    (set_attr "unit" "*,i387,i387,i387")
3883    (set_attr "mode" "SF")])
3885 (define_insn "*truncdfsf2_i387_1"
3886   [(set (match_operand:SF 0 "memory_operand" "=m")
3887         (float_truncate:SF
3888           (match_operand:DF 1 "register_operand" "f")))]
3889   "TARGET_80387
3890    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3891    && !TARGET_MIX_SSE_I387"
3892   "* return output_387_reg_move (insn, operands);"
3893   [(set_attr "type" "fmov")
3894    (set_attr "mode" "SF")])
3896 (define_split
3897   [(set (match_operand:SF 0 "register_operand")
3898         (float_truncate:SF
3899          (match_operand:DF 1 "fp_register_operand")))
3900    (clobber (match_operand 2))]
3901   "reload_completed"
3902   [(set (match_dup 2) (match_dup 1))
3903    (set (match_dup 0) (match_dup 2))]
3904   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
3906 ;; Conversion from XFmode to {SF,DF}mode
3908 (define_expand "truncxf<mode>2"
3909   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
3910                    (float_truncate:MODEF
3911                      (match_operand:XF 1 "register_operand")))
3912               (clobber (match_dup 2))])]
3913   "TARGET_80387"
3915   if (flag_unsafe_math_optimizations)
3916     {
3917       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3918       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3919       if (reg != operands[0])
3920         emit_move_insn (operands[0], reg);
3921       DONE;
3922     }
3923   else
3924     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3927 (define_insn "*truncxfsf2_mixed"
3928   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3929         (float_truncate:SF
3930           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
3931    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
3932   "TARGET_80387"
3934   gcc_assert (!which_alternative);
3935   return output_387_reg_move (insn, operands);
3937   [(set_attr "type" "fmov,multi,multi,multi")
3938    (set_attr "unit" "*,i387,i387,i387")
3939    (set_attr "mode" "SF")])
3941 (define_insn "*truncxfdf2_mixed"
3942   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3943         (float_truncate:DF
3944           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
3945    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
3946   "TARGET_80387"
3948   gcc_assert (!which_alternative);
3949   return output_387_reg_move (insn, operands);
3951   [(set_attr "isa" "*,*,sse2,*")
3952    (set_attr "type" "fmov,multi,multi,multi")
3953    (set_attr "unit" "*,i387,i387,i387")
3954    (set_attr "mode" "DF")])
3956 (define_insn "truncxf<mode>2_i387_noop"
3957   [(set (match_operand:MODEF 0 "register_operand" "=f")
3958         (float_truncate:MODEF
3959           (match_operand:XF 1 "register_operand" "f")))]
3960   "TARGET_80387 && flag_unsafe_math_optimizations"
3961   "* return output_387_reg_move (insn, operands);"
3962   [(set_attr "type" "fmov")
3963    (set_attr "mode" "<MODE>")])
3965 (define_insn "*truncxf<mode>2_i387"
3966   [(set (match_operand:MODEF 0 "memory_operand" "=m")
3967         (float_truncate:MODEF
3968           (match_operand:XF 1 "register_operand" "f")))]
3969   "TARGET_80387"
3970   "* return output_387_reg_move (insn, operands);"
3971   [(set_attr "type" "fmov")
3972    (set_attr "mode" "<MODE>")])
3974 (define_split
3975   [(set (match_operand:MODEF 0 "register_operand")
3976         (float_truncate:MODEF
3977           (match_operand:XF 1 "register_operand")))
3978    (clobber (match_operand:MODEF 2 "memory_operand"))]
3979   "TARGET_80387 && reload_completed"
3980   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
3981    (set (match_dup 0) (match_dup 2))])
3983 (define_split
3984   [(set (match_operand:MODEF 0 "memory_operand")
3985         (float_truncate:MODEF
3986           (match_operand:XF 1 "register_operand")))
3987    (clobber (match_operand:MODEF 2 "memory_operand"))]
3988   "TARGET_80387"
3989   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
3991 ;; Signed conversion to DImode.
3993 (define_expand "fix_truncxfdi2"
3994   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3995                    (fix:DI (match_operand:XF 1 "register_operand")))
3996               (clobber (reg:CC FLAGS_REG))])]
3997   "TARGET_80387"
3999   if (TARGET_FISTTP)
4000    {
4001      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4002      DONE;
4003    }
4006 (define_expand "fix_trunc<mode>di2"
4007   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4008                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4009               (clobber (reg:CC FLAGS_REG))])]
4010   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4012   if (TARGET_FISTTP
4013       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4014    {
4015      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4016      DONE;
4017    }
4018   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4019    {
4020      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4021      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4022      if (out != operands[0])
4023         emit_move_insn (operands[0], out);
4024      DONE;
4025    }
4028 ;; Signed conversion to SImode.
4030 (define_expand "fix_truncxfsi2"
4031   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4032                    (fix:SI (match_operand:XF 1 "register_operand")))
4033               (clobber (reg:CC FLAGS_REG))])]
4034   "TARGET_80387"
4036   if (TARGET_FISTTP)
4037    {
4038      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4039      DONE;
4040    }
4043 (define_expand "fix_trunc<mode>si2"
4044   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4045                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4046               (clobber (reg:CC FLAGS_REG))])]
4047   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4049   if (TARGET_FISTTP
4050       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4051    {
4052      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4053      DONE;
4054    }
4055   if (SSE_FLOAT_MODE_P (<MODE>mode))
4056    {
4057      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4058      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4059      if (out != operands[0])
4060         emit_move_insn (operands[0], out);
4061      DONE;
4062    }
4065 ;; Signed conversion to HImode.
4067 (define_expand "fix_trunc<mode>hi2"
4068   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4069                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4070               (clobber (reg:CC FLAGS_REG))])]
4071   "TARGET_80387
4072    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4074   if (TARGET_FISTTP)
4075    {
4076      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4077      DONE;
4078    }
4081 ;; Unsigned conversion to SImode.
4083 (define_expand "fixuns_trunc<mode>si2"
4084   [(parallel
4085     [(set (match_operand:SI 0 "register_operand")
4086           (unsigned_fix:SI
4087             (match_operand:MODEF 1 "nonimmediate_operand")))
4088      (use (match_dup 2))
4089      (clobber (match_scratch:<ssevecmode> 3))
4090      (clobber (match_scratch:<ssevecmode> 4))])]
4091   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4093   enum machine_mode mode = <MODE>mode;
4094   enum machine_mode vecmode = <ssevecmode>mode;
4095   REAL_VALUE_TYPE TWO31r;
4096   rtx two31;
4098   if (optimize_insn_for_size_p ())
4099     FAIL;
4101   real_ldexp (&TWO31r, &dconst1, 31);
4102   two31 = const_double_from_real_value (TWO31r, mode);
4103   two31 = ix86_build_const_vector (vecmode, true, two31);
4104   operands[2] = force_reg (vecmode, two31);
4107 (define_insn_and_split "*fixuns_trunc<mode>_1"
4108   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4109         (unsigned_fix:SI
4110           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4111    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4112    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4113    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4114   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4115    && optimize_function_for_speed_p (cfun)"
4116   "#"
4117   "&& reload_completed"
4118   [(const_int 0)]
4120   ix86_split_convert_uns_si_sse (operands);
4121   DONE;
4124 ;; Unsigned conversion to HImode.
4125 ;; Without these patterns, we'll try the unsigned SI conversion which
4126 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4128 (define_expand "fixuns_trunc<mode>hi2"
4129   [(set (match_dup 2)
4130         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4131    (set (match_operand:HI 0 "nonimmediate_operand")
4132         (subreg:HI (match_dup 2) 0))]
4133   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4134   "operands[2] = gen_reg_rtx (SImode);")
4136 ;; When SSE is available, it is always faster to use it!
4137 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4138   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4139         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4140   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4141    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4142   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4143   [(set_attr "type" "sseicvt")
4144    (set_attr "prefix" "maybe_vex")
4145    (set (attr "prefix_rex")
4146         (if_then_else
4147           (match_test "<SWI48:MODE>mode == DImode")
4148           (const_string "1")
4149           (const_string "*")))
4150    (set_attr "mode" "<MODEF:MODE>")
4151    (set_attr "athlon_decode" "double,vector")
4152    (set_attr "amdfam10_decode" "double,double")
4153    (set_attr "bdver1_decode" "double,double")])
4155 ;; Avoid vector decoded forms of the instruction.
4156 (define_peephole2
4157   [(match_scratch:MODEF 2 "x")
4158    (set (match_operand:SWI48 0 "register_operand")
4159         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4160   "TARGET_AVOID_VECTOR_DECODE
4161    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4162    && optimize_insn_for_speed_p ()"
4163   [(set (match_dup 2) (match_dup 1))
4164    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4166 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4167   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4168         (fix:SWI248x (match_operand 1 "register_operand")))]
4169   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4170    && TARGET_FISTTP
4171    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4172          && (TARGET_64BIT || <MODE>mode != DImode))
4173         && TARGET_SSE_MATH)
4174    && can_create_pseudo_p ()"
4175   "#"
4176   "&& 1"
4177   [(const_int 0)]
4179   if (memory_operand (operands[0], VOIDmode))
4180     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4181   else
4182     {
4183       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4184       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4185                                                             operands[1],
4186                                                             operands[2]));
4187     }
4188   DONE;
4190   [(set_attr "type" "fisttp")
4191    (set_attr "mode" "<MODE>")])
4193 (define_insn "fix_trunc<mode>_i387_fisttp"
4194   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4195         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4196    (clobber (match_scratch:XF 2 "=&1f"))]
4197   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4198    && TARGET_FISTTP
4199    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200          && (TARGET_64BIT || <MODE>mode != DImode))
4201         && TARGET_SSE_MATH)"
4202   "* return output_fix_trunc (insn, operands, true);"
4203   [(set_attr "type" "fisttp")
4204    (set_attr "mode" "<MODE>")])
4206 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4207   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4208         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4209    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4210    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4211   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4212    && TARGET_FISTTP
4213    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4214         && (TARGET_64BIT || <MODE>mode != DImode))
4215         && TARGET_SSE_MATH)"
4216   "#"
4217   [(set_attr "type" "fisttp")
4218    (set_attr "mode" "<MODE>")])
4220 (define_split
4221   [(set (match_operand:SWI248x 0 "register_operand")
4222         (fix:SWI248x (match_operand 1 "register_operand")))
4223    (clobber (match_operand:SWI248x 2 "memory_operand"))
4224    (clobber (match_scratch 3))]
4225   "reload_completed"
4226   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4227               (clobber (match_dup 3))])
4228    (set (match_dup 0) (match_dup 2))])
4230 (define_split
4231   [(set (match_operand:SWI248x 0 "memory_operand")
4232         (fix:SWI248x (match_operand 1 "register_operand")))
4233    (clobber (match_operand:SWI248x 2 "memory_operand"))
4234    (clobber (match_scratch 3))]
4235   "reload_completed"
4236   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4237               (clobber (match_dup 3))])])
4239 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4240 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4241 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4242 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4243 ;; function in i386.c.
4244 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4245   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4246         (fix:SWI248x (match_operand 1 "register_operand")))
4247    (clobber (reg:CC FLAGS_REG))]
4248   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4249    && !TARGET_FISTTP
4250    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4251          && (TARGET_64BIT || <MODE>mode != DImode))
4252    && can_create_pseudo_p ()"
4253   "#"
4254   "&& 1"
4255   [(const_int 0)]
4257   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4259   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4260   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4261   if (memory_operand (operands[0], VOIDmode))
4262     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4263                                          operands[2], operands[3]));
4264   else
4265     {
4266       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4267       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4268                                                      operands[2], operands[3],
4269                                                      operands[4]));
4270     }
4271   DONE;
4273   [(set_attr "type" "fistp")
4274    (set_attr "i387_cw" "trunc")
4275    (set_attr "mode" "<MODE>")])
4277 (define_insn "fix_truncdi_i387"
4278   [(set (match_operand:DI 0 "memory_operand" "=m")
4279         (fix:DI (match_operand 1 "register_operand" "f")))
4280    (use (match_operand:HI 2 "memory_operand" "m"))
4281    (use (match_operand:HI 3 "memory_operand" "m"))
4282    (clobber (match_scratch:XF 4 "=&1f"))]
4283   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4284    && !TARGET_FISTTP
4285    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4286   "* return output_fix_trunc (insn, operands, false);"
4287   [(set_attr "type" "fistp")
4288    (set_attr "i387_cw" "trunc")
4289    (set_attr "mode" "DI")])
4291 (define_insn "fix_truncdi_i387_with_temp"
4292   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4293         (fix:DI (match_operand 1 "register_operand" "f,f")))
4294    (use (match_operand:HI 2 "memory_operand" "m,m"))
4295    (use (match_operand:HI 3 "memory_operand" "m,m"))
4296    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4297    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4298   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4299    && !TARGET_FISTTP
4300    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4301   "#"
4302   [(set_attr "type" "fistp")
4303    (set_attr "i387_cw" "trunc")
4304    (set_attr "mode" "DI")])
4306 (define_split
4307   [(set (match_operand:DI 0 "register_operand")
4308         (fix:DI (match_operand 1 "register_operand")))
4309    (use (match_operand:HI 2 "memory_operand"))
4310    (use (match_operand:HI 3 "memory_operand"))
4311    (clobber (match_operand:DI 4 "memory_operand"))
4312    (clobber (match_scratch 5))]
4313   "reload_completed"
4314   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4315               (use (match_dup 2))
4316               (use (match_dup 3))
4317               (clobber (match_dup 5))])
4318    (set (match_dup 0) (match_dup 4))])
4320 (define_split
4321   [(set (match_operand:DI 0 "memory_operand")
4322         (fix:DI (match_operand 1 "register_operand")))
4323    (use (match_operand:HI 2 "memory_operand"))
4324    (use (match_operand:HI 3 "memory_operand"))
4325    (clobber (match_operand:DI 4 "memory_operand"))
4326    (clobber (match_scratch 5))]
4327   "reload_completed"
4328   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4329               (use (match_dup 2))
4330               (use (match_dup 3))
4331               (clobber (match_dup 5))])])
4333 (define_insn "fix_trunc<mode>_i387"
4334   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4335         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4336    (use (match_operand:HI 2 "memory_operand" "m"))
4337    (use (match_operand:HI 3 "memory_operand" "m"))]
4338   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4339    && !TARGET_FISTTP
4340    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4341   "* return output_fix_trunc (insn, operands, false);"
4342   [(set_attr "type" "fistp")
4343    (set_attr "i387_cw" "trunc")
4344    (set_attr "mode" "<MODE>")])
4346 (define_insn "fix_trunc<mode>_i387_with_temp"
4347   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4348         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4349    (use (match_operand:HI 2 "memory_operand" "m,m"))
4350    (use (match_operand:HI 3 "memory_operand" "m,m"))
4351    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4352   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4353    && !TARGET_FISTTP
4354    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4355   "#"
4356   [(set_attr "type" "fistp")
4357    (set_attr "i387_cw" "trunc")
4358    (set_attr "mode" "<MODE>")])
4360 (define_split
4361   [(set (match_operand:SWI24 0 "register_operand")
4362         (fix:SWI24 (match_operand 1 "register_operand")))
4363    (use (match_operand:HI 2 "memory_operand"))
4364    (use (match_operand:HI 3 "memory_operand"))
4365    (clobber (match_operand:SWI24 4 "memory_operand"))]
4366   "reload_completed"
4367   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4368               (use (match_dup 2))
4369               (use (match_dup 3))])
4370    (set (match_dup 0) (match_dup 4))])
4372 (define_split
4373   [(set (match_operand:SWI24 0 "memory_operand")
4374         (fix:SWI24 (match_operand 1 "register_operand")))
4375    (use (match_operand:HI 2 "memory_operand"))
4376    (use (match_operand:HI 3 "memory_operand"))
4377    (clobber (match_operand:SWI24 4 "memory_operand"))]
4378   "reload_completed"
4379   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4380               (use (match_dup 2))
4381               (use (match_dup 3))])])
4383 (define_insn "x86_fnstcw_1"
4384   [(set (match_operand:HI 0 "memory_operand" "=m")
4385         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4386   "TARGET_80387"
4387   "fnstcw\t%0"
4388   [(set (attr "length")
4389         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4390    (set_attr "mode" "HI")
4391    (set_attr "unit" "i387")
4392    (set_attr "bdver1_decode" "vector")])
4394 (define_insn "x86_fldcw_1"
4395   [(set (reg:HI FPCR_REG)
4396         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4397   "TARGET_80387"
4398   "fldcw\t%0"
4399   [(set (attr "length")
4400         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4401    (set_attr "mode" "HI")
4402    (set_attr "unit" "i387")
4403    (set_attr "athlon_decode" "vector")
4404    (set_attr "amdfam10_decode" "vector")
4405    (set_attr "bdver1_decode" "vector")])
4407 ;; Conversion between fixed point and floating point.
4409 ;; Even though we only accept memory inputs, the backend _really_
4410 ;; wants to be able to do this between registers.
4412 (define_expand "floathi<mode>2"
4413   [(set (match_operand:X87MODEF 0 "register_operand")
4414         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4415   "TARGET_80387
4416    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4417        || TARGET_MIX_SSE_I387)")
4419 ;; Pre-reload splitter to add memory clobber to the pattern.
4420 (define_insn_and_split "*floathi<mode>2_1"
4421   [(set (match_operand:X87MODEF 0 "register_operand")
4422         (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4423   "TARGET_80387
4424    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4425        || TARGET_MIX_SSE_I387)
4426    && can_create_pseudo_p ()"
4427   "#"
4428   "&& 1"
4429   [(parallel [(set (match_dup 0)
4430               (float:X87MODEF (match_dup 1)))
4431    (clobber (match_dup 2))])]
4432   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4434 (define_insn "*floathi<mode>2_i387_with_temp"
4435   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4436         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4437   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4438   "TARGET_80387
4439    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4440        || TARGET_MIX_SSE_I387)"
4441   "#"
4442   [(set_attr "type" "fmov,multi")
4443    (set_attr "mode" "<MODE>")
4444    (set_attr "unit" "*,i387")
4445    (set_attr "fp_int_src" "true")])
4447 (define_insn "*floathi<mode>2_i387"
4448   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4449         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4450   "TARGET_80387
4451    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4452        || TARGET_MIX_SSE_I387)"
4453   "fild%Z1\t%1"
4454   [(set_attr "type" "fmov")
4455    (set_attr "mode" "<MODE>")
4456    (set_attr "fp_int_src" "true")])
4458 (define_split
4459   [(set (match_operand:X87MODEF 0 "register_operand")
4460         (float:X87MODEF (match_operand:HI 1 "register_operand")))
4461    (clobber (match_operand:HI 2 "memory_operand"))]
4462   "TARGET_80387
4463    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4464        || TARGET_MIX_SSE_I387)
4465    && reload_completed"
4466   [(set (match_dup 2) (match_dup 1))
4467    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4469 (define_split
4470   [(set (match_operand:X87MODEF 0 "register_operand")
4471         (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4472    (clobber (match_operand:HI 2 "memory_operand"))]
4473    "TARGET_80387
4474     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4475         || TARGET_MIX_SSE_I387)
4476     && reload_completed"
4477   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4479 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4480   [(set (match_operand:X87MODEF 0 "register_operand")
4481         (float:X87MODEF
4482           (match_operand:SWI48x 1 "nonimmediate_operand")))]
4483   "TARGET_80387
4484    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4485        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4487   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4488         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4489       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4490     {
4491       rtx reg = gen_reg_rtx (XFmode);
4492       rtx (*insn)(rtx, rtx);
4494       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4496       if (<X87MODEF:MODE>mode == SFmode)
4497         insn = gen_truncxfsf2;
4498       else if (<X87MODEF:MODE>mode == DFmode)
4499         insn = gen_truncxfdf2;
4500       else
4501         gcc_unreachable ();
4503       emit_insn (insn (operands[0], reg));
4504       DONE;
4505     }
4508 ;; Pre-reload splitter to add memory clobber to the pattern.
4509 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4510   [(set (match_operand:X87MODEF 0 "register_operand")
4511         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4512   "((TARGET_80387
4513      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4514      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4515            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4516          || TARGET_MIX_SSE_I387))
4517     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4518         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4519         && ((<SWI48x:MODE>mode == SImode
4520              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4521              && optimize_function_for_speed_p (cfun)
4522              && flag_trapping_math)
4523             || !(TARGET_INTER_UNIT_CONVERSIONS
4524                  || optimize_function_for_size_p (cfun)))))
4525    && can_create_pseudo_p ()"
4526   "#"
4527   "&& 1"
4528   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4529               (clobber (match_dup 2))])]
4531   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4533   /* Avoid store forwarding (partial memory) stall penalty
4534      by passing DImode value through XMM registers.  */
4535   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4536       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4537       && optimize_function_for_speed_p (cfun))
4538     {
4539       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4540                                                             operands[1],
4541                                                             operands[2]));
4542       DONE;
4543     }
4546 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4547   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4548         (float:MODEF
4549           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4550    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4551   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4552    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4553   "#"
4554   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4555    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4556    (set_attr "unit" "*,i387,*,*,*")
4557    (set_attr "athlon_decode" "*,*,double,direct,double")
4558    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4559    (set_attr "bdver1_decode" "*,*,double,direct,double")
4560    (set_attr "fp_int_src" "true")])
4562 (define_insn "*floatsi<mode>2_vector_mixed"
4563   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4564         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4565   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4566    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4567   "@
4568    fild%Z1\t%1
4569    #"
4570   [(set_attr "type" "fmov,sseicvt")
4571    (set_attr "mode" "<MODE>,<ssevecmode>")
4572    (set_attr "unit" "i387,*")
4573    (set_attr "athlon_decode" "*,direct")
4574    (set_attr "amdfam10_decode" "*,double")
4575    (set_attr "bdver1_decode" "*,direct")
4576    (set_attr "fp_int_src" "true")])
4578 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4579   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4580         (float:MODEF
4581           (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4582    (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4583   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4584   "#"
4585   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4586    (set_attr "mode" "<MODEF:MODE>")
4587    (set_attr "unit" "*,i387,*,*")
4588    (set_attr "athlon_decode" "*,*,double,direct")
4589    (set_attr "amdfam10_decode" "*,*,vector,double")
4590    (set_attr "bdver1_decode" "*,*,double,direct")
4591    (set_attr "fp_int_src" "true")])
4593 (define_split
4594   [(set (match_operand:MODEF 0 "register_operand")
4595         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4596    (clobber (match_operand:SWI48 2 "memory_operand"))]
4597   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4598    && TARGET_INTER_UNIT_CONVERSIONS
4599    && reload_completed && SSE_REG_P (operands[0])"
4600   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4602 (define_split
4603   [(set (match_operand:MODEF 0 "register_operand")
4604         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4605    (clobber (match_operand:SWI48 2 "memory_operand"))]
4606   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4607    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4608    && reload_completed && SSE_REG_P (operands[0])"
4609   [(set (match_dup 2) (match_dup 1))
4610    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4612 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4613   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4614         (float:MODEF
4615           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4616   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4617    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4618   "@
4619    fild%Z1\t%1
4620    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4621    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4622   [(set_attr "type" "fmov,sseicvt,sseicvt")
4623    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4624    (set_attr "mode" "<MODEF:MODE>")
4625    (set (attr "prefix_rex")
4626      (if_then_else
4627        (and (eq_attr "prefix" "maybe_vex")
4628             (match_test "<SWI48:MODE>mode == DImode"))
4629        (const_string "1")
4630        (const_string "*")))
4631    (set_attr "unit" "i387,*,*")
4632    (set_attr "athlon_decode" "*,double,direct")
4633    (set_attr "amdfam10_decode" "*,vector,double")
4634    (set_attr "bdver1_decode" "*,double,direct")
4635    (set_attr "fp_int_src" "true")])
4637 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4638   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4639         (float:MODEF
4640           (match_operand:SWI48 1 "memory_operand" "m,m")))]
4641   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4642    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4643   "@
4644    fild%Z1\t%1
4645    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4646   [(set_attr "type" "fmov,sseicvt")
4647    (set_attr "prefix" "orig,maybe_vex")
4648    (set_attr "mode" "<MODEF:MODE>")
4649    (set (attr "prefix_rex")
4650      (if_then_else
4651        (and (eq_attr "prefix" "maybe_vex")
4652             (match_test "<SWI48:MODE>mode == DImode"))
4653        (const_string "1")
4654        (const_string "*")))
4655    (set_attr "athlon_decode" "*,direct")
4656    (set_attr "amdfam10_decode" "*,double")
4657    (set_attr "bdver1_decode" "*,direct")
4658    (set_attr "fp_int_src" "true")])
4660 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4661   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4662         (float:MODEF
4663           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4664    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4665   "TARGET_SSE2 && TARGET_SSE_MATH
4666    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4667   "#"
4668   [(set_attr "type" "sseicvt")
4669    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4670    (set_attr "athlon_decode" "double,direct,double")
4671    (set_attr "amdfam10_decode" "vector,double,double")
4672    (set_attr "bdver1_decode" "double,direct,double")
4673    (set_attr "fp_int_src" "true")])
4675 (define_insn "*floatsi<mode>2_vector_sse"
4676   [(set (match_operand:MODEF 0 "register_operand" "=x")
4677         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4678   "TARGET_SSE2 && TARGET_SSE_MATH
4679    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4680   "#"
4681   [(set_attr "type" "sseicvt")
4682    (set_attr "mode" "<MODE>")
4683    (set_attr "athlon_decode" "direct")
4684    (set_attr "amdfam10_decode" "double")
4685    (set_attr "bdver1_decode" "direct")
4686    (set_attr "fp_int_src" "true")])
4688 (define_split
4689   [(set (match_operand:MODEF 0 "register_operand")
4690         (float:MODEF (match_operand:SI 1 "register_operand")))
4691    (clobber (match_operand:SI 2 "memory_operand"))]
4692   "TARGET_SSE2 && TARGET_SSE_MATH
4693    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4694    && reload_completed && SSE_REG_P (operands[0])"
4695   [(const_int 0)]
4697   rtx op1 = operands[1];
4699   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4700                                      <MODE>mode, 0);
4701   if (GET_CODE (op1) == SUBREG)
4702     op1 = SUBREG_REG (op1);
4704   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4705     {
4706       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4707       emit_insn (gen_sse2_loadld (operands[4],
4708                                   CONST0_RTX (V4SImode), operands[1]));
4709     }
4710   /* We can ignore possible trapping value in the
4711      high part of SSE register for non-trapping math. */
4712   else if (SSE_REG_P (op1) && !flag_trapping_math)
4713     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4714   else
4715     {
4716       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4717       emit_move_insn (operands[2], operands[1]);
4718       emit_insn (gen_sse2_loadld (operands[4],
4719                                   CONST0_RTX (V4SImode), operands[2]));
4720     }
4721   if (<ssevecmode>mode == V4SFmode)
4722     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4723   else
4724     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4725   DONE;
4728 (define_split
4729   [(set (match_operand:MODEF 0 "register_operand")
4730         (float:MODEF (match_operand:SI 1 "memory_operand")))
4731    (clobber (match_operand:SI 2 "memory_operand"))]
4732   "TARGET_SSE2 && TARGET_SSE_MATH
4733    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4734    && reload_completed && SSE_REG_P (operands[0])"
4735   [(const_int 0)]
4737   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4738                                      <MODE>mode, 0);
4739   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4741   emit_insn (gen_sse2_loadld (operands[4],
4742                               CONST0_RTX (V4SImode), operands[1]));
4743   if (<ssevecmode>mode == V4SFmode)
4744     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4745   else
4746     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4747   DONE;
4750 (define_split
4751   [(set (match_operand:MODEF 0 "register_operand")
4752         (float:MODEF (match_operand:SI 1 "register_operand")))]
4753   "TARGET_SSE2 && TARGET_SSE_MATH
4754    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4755    && reload_completed && SSE_REG_P (operands[0])"
4756   [(const_int 0)]
4758   rtx op1 = operands[1];
4760   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4761                                      <MODE>mode, 0);
4762   if (GET_CODE (op1) == SUBREG)
4763     op1 = SUBREG_REG (op1);
4765   if (GENERAL_REG_P (op1))
4766     {
4767       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4768       if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4769         emit_insn (gen_sse2_loadld (operands[4],
4770                                     CONST0_RTX (V4SImode), operands[1]));
4771       else
4772         {
4773           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4774                                               operands[1]);
4775           emit_insn (gen_sse2_loadld (operands[4],
4776                                       CONST0_RTX (V4SImode), operands[5]));
4777           ix86_free_from_memory (GET_MODE (operands[1]));
4778         }
4779     }
4780   /* We can ignore possible trapping value in the
4781      high part of SSE register for non-trapping math. */
4782   else if (SSE_REG_P (op1) && !flag_trapping_math)
4783     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4784   else
4785     gcc_unreachable ();
4786   if (<ssevecmode>mode == V4SFmode)
4787     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4788   else
4789     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4790   DONE;
4793 (define_split
4794   [(set (match_operand:MODEF 0 "register_operand")
4795         (float:MODEF (match_operand:SI 1 "memory_operand")))]
4796   "TARGET_SSE2 && TARGET_SSE_MATH
4797    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4798    && reload_completed && SSE_REG_P (operands[0])"
4799   [(const_int 0)]
4801   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4802                                      <MODE>mode, 0);
4803   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4805   emit_insn (gen_sse2_loadld (operands[4],
4806                               CONST0_RTX (V4SImode), operands[1]));
4807   if (<ssevecmode>mode == V4SFmode)
4808     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4809   else
4810     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4811   DONE;
4814 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
4815   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4816         (float:MODEF
4817           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
4818   (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
4819   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4820   "#"
4821   [(set_attr "type" "sseicvt")
4822    (set_attr "mode" "<MODEF:MODE>")
4823    (set_attr "athlon_decode" "double,direct")
4824    (set_attr "amdfam10_decode" "vector,double")
4825    (set_attr "bdver1_decode" "double,direct")
4826    (set_attr "btver2_decode" "double,double")
4827    (set_attr "fp_int_src" "true")])
4829 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
4830   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4831         (float:MODEF
4832           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
4833   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4834    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4835   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4836   [(set_attr "type" "sseicvt")
4837    (set_attr "prefix" "maybe_vex")
4838    (set_attr "mode" "<MODEF:MODE>")
4839    (set (attr "prefix_rex")
4840      (if_then_else
4841        (and (eq_attr "prefix" "maybe_vex")
4842             (match_test "<SWI48:MODE>mode == DImode"))
4843        (const_string "1")
4844        (const_string "*")))
4845    (set_attr "athlon_decode" "double,direct")
4846    (set_attr "amdfam10_decode" "vector,double")
4847    (set_attr "bdver1_decode" "double,direct")
4848    (set_attr "btver2_decode" "double,double")
4849    (set_attr "fp_int_src" "true")])
4851 (define_split
4852   [(set (match_operand:MODEF 0 "register_operand")
4853         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
4854    (clobber (match_operand:SWI48 2 "memory_operand"))]
4855   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4856    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4857    && reload_completed && SSE_REG_P (operands[0])"
4858   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4860 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
4861   [(set (match_operand:MODEF 0 "register_operand" "=x")
4862         (float:MODEF
4863           (match_operand:SWI48 1 "memory_operand" "m")))]
4864   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4865    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4866   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4867   [(set_attr "type" "sseicvt")
4868    (set_attr "prefix" "maybe_vex")
4869    (set_attr "mode" "<MODEF:MODE>")
4870    (set (attr "prefix_rex")
4871      (if_then_else
4872        (and (eq_attr "prefix" "maybe_vex")
4873             (match_test "<SWI48:MODE>mode == DImode"))
4874        (const_string "1")
4875        (const_string "*")))
4876    (set_attr "athlon_decode" "direct")
4877    (set_attr "amdfam10_decode" "double")
4878    (set_attr "bdver1_decode" "direct")
4879    (set_attr "fp_int_src" "true")])
4881 (define_split
4882   [(set (match_operand:MODEF 0 "register_operand")
4883         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4884    (clobber (match_operand:SWI48 2 "memory_operand"))]
4885   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4886    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4887    && reload_completed && SSE_REG_P (operands[0])"
4888   [(set (match_dup 2) (match_dup 1))
4889    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4891 (define_split
4892   [(set (match_operand:MODEF 0 "register_operand")
4893         (float:MODEF (match_operand:SWI48 1 "memory_operand")))
4894    (clobber (match_operand:SWI48 2 "memory_operand"))]
4895   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4896    && reload_completed && SSE_REG_P (operands[0])"
4897   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4899 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
4900   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4901         (float:X87MODEF
4902           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
4903   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
4904   "TARGET_80387
4905    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4906   "@
4907    fild%Z1\t%1
4908    #"
4909   [(set_attr "type" "fmov,multi")
4910    (set_attr "mode" "<X87MODEF:MODE>")
4911    (set_attr "unit" "*,i387")
4912    (set_attr "fp_int_src" "true")])
4914 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
4915   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4916         (float:X87MODEF
4917           (match_operand:SWI48x 1 "memory_operand" "m")))]
4918   "TARGET_80387
4919    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4920   "fild%Z1\t%1"
4921   [(set_attr "type" "fmov")
4922    (set_attr "mode" "<X87MODEF:MODE>")
4923    (set_attr "fp_int_src" "true")])
4925 (define_split
4926   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4927         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
4928    (clobber (match_operand:SWI48x 2 "memory_operand"))]
4929   "TARGET_80387
4930    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4931    && reload_completed"
4932   [(set (match_dup 2) (match_dup 1))
4933    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4935 (define_split
4936   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4937         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
4938    (clobber (match_operand:SWI48x 2 "memory_operand"))]
4939   "TARGET_80387
4940    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4941    && reload_completed"
4942   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4944 ;; Avoid partial SSE register dependency stalls
4946 (define_split
4947   [(set (match_operand:MODEF 0 "register_operand")
4948         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4949   "TARGET_SSE2 && TARGET_SSE_MATH
4950    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4951    && optimize_function_for_speed_p (cfun)
4952    && reload_completed && SSE_REG_P (operands[0])"
4953   [(set (match_dup 0)
4954         (vec_merge:<ssevecmode>
4955           (vec_duplicate:<ssevecmode>
4956             (float:MODEF (match_dup 1)))
4957           (match_dup 0)
4958           (const_int 1)))]
4960   operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4961                                      <MODE>mode, 0);
4962   emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
4965 (define_split
4966   [(set (match_operand:MODEF 0 "register_operand")
4967         (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
4968   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4969    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4970    && optimize_function_for_speed_p (cfun)
4971    && reload_completed && SSE_REG_P (operands[0])"
4972   [(set (match_dup 0)
4973         (vec_merge:<ssevecmode>
4974           (vec_duplicate:<ssevecmode>
4975             (float:MODEF (match_dup 1)))
4976           (match_dup 0)
4977           (const_int 1)))]
4979   operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4980                                      <MODE>mode, 0);
4981   emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
4984 ;; Avoid store forwarding (partial memory) stall penalty
4985 ;; by passing DImode value through XMM registers.  */
4987 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4988   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4989         (float:X87MODEF
4990           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4991    (clobber (match_scratch:V4SI 3 "=X,x"))
4992    (clobber (match_scratch:V4SI 4 "=X,x"))
4993    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4994   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4995    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4996    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4997   "#"
4998   [(set_attr "type" "multi")
4999    (set_attr "mode" "<X87MODEF:MODE>")
5000    (set_attr "unit" "i387")
5001    (set_attr "fp_int_src" "true")])
5003 (define_split
5004   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5005         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5006    (clobber (match_scratch:V4SI 3))
5007    (clobber (match_scratch:V4SI 4))
5008    (clobber (match_operand:DI 2 "memory_operand"))]
5009   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5010    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5011    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5012    && reload_completed"
5013   [(set (match_dup 2) (match_dup 3))
5014    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5016   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5017      Assemble the 64-bit DImode value in an xmm register.  */
5018   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5019                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5020   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5021                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5022   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5023                                          operands[4]));
5025   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5028 (define_split
5029   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5030         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5031    (clobber (match_scratch:V4SI 3))
5032    (clobber (match_scratch:V4SI 4))
5033    (clobber (match_operand:DI 2 "memory_operand"))]
5034   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5035    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5036    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5037    && reload_completed"
5038   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5040 ;; Avoid store forwarding (partial memory) stall penalty by extending
5041 ;; SImode value to DImode through XMM register instead of pushing two
5042 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5043 ;; targets benefit from this optimization. Also note that fild
5044 ;; loads from memory only.
5046 (define_insn "*floatunssi<mode>2_1"
5047   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5048         (unsigned_float:X87MODEF
5049           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5050    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5051    (clobber (match_scratch:SI 3 "=X,x"))]
5052   "!TARGET_64BIT
5053    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5054    && TARGET_SSE"
5055   "#"
5056   [(set_attr "type" "multi")
5057    (set_attr "mode" "<MODE>")])
5059 (define_split
5060   [(set (match_operand:X87MODEF 0 "register_operand")
5061         (unsigned_float:X87MODEF
5062           (match_operand:SI 1 "register_operand")))
5063    (clobber (match_operand:DI 2 "memory_operand"))
5064    (clobber (match_scratch:SI 3))]
5065   "!TARGET_64BIT
5066    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5067    && TARGET_SSE
5068    && reload_completed"
5069   [(set (match_dup 2) (match_dup 1))
5070    (set (match_dup 0)
5071         (float:X87MODEF (match_dup 2)))]
5072   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5074 (define_split
5075   [(set (match_operand:X87MODEF 0 "register_operand")
5076         (unsigned_float:X87MODEF
5077           (match_operand:SI 1 "memory_operand")))
5078    (clobber (match_operand:DI 2 "memory_operand"))
5079    (clobber (match_scratch:SI 3))]
5080   "!TARGET_64BIT
5081    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5082    && TARGET_SSE
5083    && reload_completed"
5084   [(set (match_dup 2) (match_dup 3))
5085    (set (match_dup 0)
5086         (float:X87MODEF (match_dup 2)))]
5088   emit_move_insn (operands[3], operands[1]);
5089   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5092 (define_expand "floatunssi<mode>2"
5093   [(parallel
5094      [(set (match_operand:X87MODEF 0 "register_operand")
5095            (unsigned_float:X87MODEF
5096              (match_operand:SI 1 "nonimmediate_operand")))
5097       (clobber (match_dup 2))
5098       (clobber (match_scratch:SI 3))])]
5099   "!TARGET_64BIT
5100    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5101         && TARGET_SSE)
5102        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5104   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5105     {
5106       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5107       DONE;
5108     }
5109   else
5110     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5113 (define_expand "floatunsdisf2"
5114   [(use (match_operand:SF 0 "register_operand"))
5115    (use (match_operand:DI 1 "nonimmediate_operand"))]
5116   "TARGET_64BIT && TARGET_SSE_MATH"
5117   "x86_emit_floatuns (operands); DONE;")
5119 (define_expand "floatunsdidf2"
5120   [(use (match_operand:DF 0 "register_operand"))
5121    (use (match_operand:DI 1 "nonimmediate_operand"))]
5122   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5123    && TARGET_SSE2 && TARGET_SSE_MATH"
5125   if (TARGET_64BIT)
5126     x86_emit_floatuns (operands);
5127   else
5128     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5129   DONE;
5132 ;; Load effective address instructions
5134 (define_insn_and_split "*lea<mode>"
5135   [(set (match_operand:SWI48 0 "register_operand" "=r")
5136         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5137   ""
5139   if (SImode_address_operand (operands[1], VOIDmode))
5140     {
5141       gcc_assert (TARGET_64BIT);
5142       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5143     }
5144   else 
5145     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5147   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5148   [(const_int 0)]
5150   enum machine_mode mode = <MODE>mode;
5151   rtx pat;
5153   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5154      change operands[] array behind our back.  */
5155   pat = PATTERN (curr_insn);
5157   operands[0] = SET_DEST (pat);
5158   operands[1] = SET_SRC (pat);
5160   /* Emit all operations in SImode for zero-extended addresses.  Recall
5161      that x86_64 inheretly zero-extends SImode operations to DImode.  */
5162   if (SImode_address_operand (operands[1], VOIDmode))
5163     mode = SImode;
5165   ix86_split_lea_for_addr (curr_insn, operands, mode);
5166   DONE;
5168   [(set_attr "type" "lea")
5169    (set (attr "mode")
5170      (if_then_else
5171        (match_operand 1 "SImode_address_operand")
5172        (const_string "SI")
5173        (const_string "<MODE>")))])
5175 ;; Add instructions
5177 (define_expand "add<mode>3"
5178   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5179         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5180                     (match_operand:SDWIM 2 "<general_operand>")))]
5181   ""
5182   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5184 (define_insn_and_split "*add<dwi>3_doubleword"
5185   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5186         (plus:<DWI>
5187           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5188           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5189    (clobber (reg:CC FLAGS_REG))]
5190   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5191   "#"
5192   "reload_completed"
5193   [(parallel [(set (reg:CC FLAGS_REG)
5194                    (unspec:CC [(match_dup 1) (match_dup 2)]
5195                               UNSPEC_ADD_CARRY))
5196               (set (match_dup 0)
5197                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5198    (parallel [(set (match_dup 3)
5199                    (plus:DWIH
5200                      (match_dup 4)
5201                      (plus:DWIH
5202                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5203                        (match_dup 5))))
5204               (clobber (reg:CC FLAGS_REG))])]
5205   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5207 (define_insn "*add<mode>3_cc"
5208   [(set (reg:CC FLAGS_REG)
5209         (unspec:CC
5210           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5211            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5212           UNSPEC_ADD_CARRY))
5213    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5214         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5215   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5216   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5217   [(set_attr "type" "alu")
5218    (set_attr "mode" "<MODE>")])
5220 (define_insn "addqi3_cc"
5221   [(set (reg:CC FLAGS_REG)
5222         (unspec:CC
5223           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5224            (match_operand:QI 2 "general_operand" "qn,qm")]
5225           UNSPEC_ADD_CARRY))
5226    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5227         (plus:QI (match_dup 1) (match_dup 2)))]
5228   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5229   "add{b}\t{%2, %0|%0, %2}"
5230   [(set_attr "type" "alu")
5231    (set_attr "mode" "QI")])
5233 (define_insn "*add<mode>_1"
5234   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5235         (plus:SWI48
5236           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5237           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5238    (clobber (reg:CC FLAGS_REG))]
5239   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5241   switch (get_attr_type (insn))
5242     {
5243     case TYPE_LEA:
5244       return "#";
5246     case TYPE_INCDEC:
5247       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5248       if (operands[2] == const1_rtx)
5249         return "inc{<imodesuffix>}\t%0";
5250       else
5251         {
5252           gcc_assert (operands[2] == constm1_rtx);
5253           return "dec{<imodesuffix>}\t%0";
5254         }
5256     default:
5257       /* For most processors, ADD is faster than LEA.  This alternative
5258          was added to use ADD as much as possible.  */
5259       if (which_alternative == 2)
5260         {
5261           rtx tmp;
5262           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5263         }
5264         
5265       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5266       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5267         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5269       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5270     }
5272   [(set (attr "type")
5273      (cond [(eq_attr "alternative" "3")
5274               (const_string "lea")
5275             (match_operand:SWI48 2 "incdec_operand")
5276               (const_string "incdec")
5277            ]
5278            (const_string "alu")))
5279    (set (attr "length_immediate")
5280       (if_then_else
5281         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5282         (const_string "1")
5283         (const_string "*")))
5284    (set_attr "mode" "<MODE>")])
5286 ;; It may seem that nonimmediate operand is proper one for operand 1.
5287 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5288 ;; we take care in ix86_binary_operator_ok to not allow two memory
5289 ;; operands so proper swapping will be done in reload.  This allow
5290 ;; patterns constructed from addsi_1 to match.
5292 (define_insn "addsi_1_zext"
5293   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5294         (zero_extend:DI
5295           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5296                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5297    (clobber (reg:CC FLAGS_REG))]
5298   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5300   switch (get_attr_type (insn))
5301     {
5302     case TYPE_LEA:
5303       return "#";
5305     case TYPE_INCDEC:
5306       if (operands[2] == const1_rtx)
5307         return "inc{l}\t%k0";
5308       else
5309         {
5310           gcc_assert (operands[2] == constm1_rtx);
5311           return "dec{l}\t%k0";
5312         }
5314     default:
5315       /* For most processors, ADD is faster than LEA.  This alternative
5316          was added to use ADD as much as possible.  */
5317       if (which_alternative == 1)
5318         {
5319           rtx tmp;
5320           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5321         }
5323       if (x86_maybe_negate_const_int (&operands[2], SImode))
5324         return "sub{l}\t{%2, %k0|%k0, %2}";
5326       return "add{l}\t{%2, %k0|%k0, %2}";
5327     }
5329   [(set (attr "type")
5330      (cond [(eq_attr "alternative" "2")
5331               (const_string "lea")
5332             (match_operand:SI 2 "incdec_operand")
5333               (const_string "incdec")
5334            ]
5335            (const_string "alu")))
5336    (set (attr "length_immediate")
5337       (if_then_else
5338         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5339         (const_string "1")
5340         (const_string "*")))
5341    (set_attr "mode" "SI")])
5343 (define_insn "*addhi_1"
5344   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5345         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5346                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5347    (clobber (reg:CC FLAGS_REG))]
5348   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5350   switch (get_attr_type (insn))
5351     {
5352     case TYPE_LEA:
5353       return "#";
5355     case TYPE_INCDEC:
5356       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5357       if (operands[2] == const1_rtx)
5358         return "inc{w}\t%0";
5359       else
5360         {
5361           gcc_assert (operands[2] == constm1_rtx);
5362           return "dec{w}\t%0";
5363         }
5365     default:
5366       /* For most processors, ADD is faster than LEA.  This alternative
5367          was added to use ADD as much as possible.  */
5368       if (which_alternative == 2)
5369         {
5370           rtx tmp;
5371           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5372         }
5374       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5375       if (x86_maybe_negate_const_int (&operands[2], HImode))
5376         return "sub{w}\t{%2, %0|%0, %2}";
5378       return "add{w}\t{%2, %0|%0, %2}";
5379     }
5381   [(set (attr "type")
5382      (cond [(eq_attr "alternative" "3")
5383               (const_string "lea")
5384             (match_operand:HI 2 "incdec_operand")
5385               (const_string "incdec")
5386            ]
5387            (const_string "alu")))
5388    (set (attr "length_immediate")
5389       (if_then_else
5390         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5391         (const_string "1")
5392         (const_string "*")))
5393    (set_attr "mode" "HI,HI,HI,SI")])
5395 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5396 (define_insn "*addqi_1"
5397   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5398         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5399                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5400    (clobber (reg:CC FLAGS_REG))]
5401   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5403   bool widen = (which_alternative == 3 || which_alternative == 4);
5405   switch (get_attr_type (insn))
5406     {
5407     case TYPE_LEA:
5408       return "#";
5410     case TYPE_INCDEC:
5411       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5412       if (operands[2] == const1_rtx)
5413         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5414       else
5415         {
5416           gcc_assert (operands[2] == constm1_rtx);
5417           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5418         }
5420     default:
5421       /* For most processors, ADD is faster than LEA.  These alternatives
5422          were added to use ADD as much as possible.  */
5423       if (which_alternative == 2 || which_alternative == 4)
5424         {
5425           rtx tmp;
5426           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5427         }
5429       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5430       if (x86_maybe_negate_const_int (&operands[2], QImode))
5431         {
5432           if (widen)
5433             return "sub{l}\t{%2, %k0|%k0, %2}";
5434           else
5435             return "sub{b}\t{%2, %0|%0, %2}";
5436         }
5437       if (widen)
5438         return "add{l}\t{%k2, %k0|%k0, %k2}";
5439       else
5440         return "add{b}\t{%2, %0|%0, %2}";
5441     }
5443   [(set (attr "type")
5444      (cond [(eq_attr "alternative" "5")
5445               (const_string "lea")
5446             (match_operand:QI 2 "incdec_operand")
5447               (const_string "incdec")
5448            ]
5449            (const_string "alu")))
5450    (set (attr "length_immediate")
5451       (if_then_else
5452         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5453         (const_string "1")
5454         (const_string "*")))
5455    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5457 (define_insn "*addqi_1_slp"
5458   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5459         (plus:QI (match_dup 0)
5460                  (match_operand:QI 1 "general_operand" "qn,qm")))
5461    (clobber (reg:CC FLAGS_REG))]
5462   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5463    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5465   switch (get_attr_type (insn))
5466     {
5467     case TYPE_INCDEC:
5468       if (operands[1] == const1_rtx)
5469         return "inc{b}\t%0";
5470       else
5471         {
5472           gcc_assert (operands[1] == constm1_rtx);
5473           return "dec{b}\t%0";
5474         }
5476     default:
5477       if (x86_maybe_negate_const_int (&operands[1], QImode))
5478         return "sub{b}\t{%1, %0|%0, %1}";
5480       return "add{b}\t{%1, %0|%0, %1}";
5481     }
5483   [(set (attr "type")
5484      (if_then_else (match_operand:QI 1 "incdec_operand")
5485         (const_string "incdec")
5486         (const_string "alu1")))
5487    (set (attr "memory")
5488      (if_then_else (match_operand 1 "memory_operand")
5489         (const_string "load")
5490         (const_string "none")))
5491    (set_attr "mode" "QI")])
5493 ;; Split non destructive adds if we cannot use lea.
5494 (define_split
5495   [(set (match_operand:SWI48 0 "register_operand")
5496         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5497                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5498    (clobber (reg:CC FLAGS_REG))]
5499   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5500   [(set (match_dup 0) (match_dup 1))
5501    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5502               (clobber (reg:CC FLAGS_REG))])])
5504 ;; Convert add to the lea pattern to avoid flags dependency.
5505 (define_split
5506   [(set (match_operand:SWI 0 "register_operand")
5507         (plus:SWI (match_operand:SWI 1 "register_operand")
5508                   (match_operand:SWI 2 "<nonmemory_operand>")))
5509    (clobber (reg:CC FLAGS_REG))]
5510   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5511   [(const_int 0)]
5513   enum machine_mode mode = <MODE>mode;
5514   rtx pat;
5516   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5517     { 
5518       mode = SImode; 
5519       operands[0] = gen_lowpart (mode, operands[0]);
5520       operands[1] = gen_lowpart (mode, operands[1]);
5521       operands[2] = gen_lowpart (mode, operands[2]);
5522     }
5524   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5526   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5527   DONE;
5530 ;; Split non destructive adds if we cannot use lea.
5531 (define_split
5532   [(set (match_operand:DI 0 "register_operand")
5533         (zero_extend:DI
5534           (plus:SI (match_operand:SI 1 "register_operand")
5535                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5536    (clobber (reg:CC FLAGS_REG))]
5537   "TARGET_64BIT
5538    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5539   [(set (match_dup 3) (match_dup 1))
5540    (parallel [(set (match_dup 0)
5541                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5542               (clobber (reg:CC FLAGS_REG))])]
5543   "operands[3] = gen_lowpart (SImode, operands[0]);")
5545 ;; Convert add to the lea pattern to avoid flags dependency.
5546 (define_split
5547   [(set (match_operand:DI 0 "register_operand")
5548         (zero_extend:DI
5549           (plus:SI (match_operand:SI 1 "register_operand")
5550                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5551    (clobber (reg:CC FLAGS_REG))]
5552   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5553   [(set (match_dup 0)
5554         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5556 (define_insn "*add<mode>_2"
5557   [(set (reg FLAGS_REG)
5558         (compare
5559           (plus:SWI
5560             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5561             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5562           (const_int 0)))
5563    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5564         (plus:SWI (match_dup 1) (match_dup 2)))]
5565   "ix86_match_ccmode (insn, CCGOCmode)
5566    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5568   switch (get_attr_type (insn))
5569     {
5570     case TYPE_INCDEC:
5571       if (operands[2] == const1_rtx)
5572         return "inc{<imodesuffix>}\t%0";
5573       else
5574         {
5575           gcc_assert (operands[2] == constm1_rtx);
5576           return "dec{<imodesuffix>}\t%0";
5577         }
5579     default:
5580       if (which_alternative == 2)
5581         {
5582           rtx tmp;
5583           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5584         }
5585         
5586       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5587       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5588         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5590       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5591     }
5593   [(set (attr "type")
5594      (if_then_else (match_operand:SWI 2 "incdec_operand")
5595         (const_string "incdec")
5596         (const_string "alu")))
5597    (set (attr "length_immediate")
5598       (if_then_else
5599         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5600         (const_string "1")
5601         (const_string "*")))
5602    (set_attr "mode" "<MODE>")])
5604 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5605 (define_insn "*addsi_2_zext"
5606   [(set (reg FLAGS_REG)
5607         (compare
5608           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5609                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5610           (const_int 0)))
5611    (set (match_operand:DI 0 "register_operand" "=r,r")
5612         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5613   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5614    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5616   switch (get_attr_type (insn))
5617     {
5618     case TYPE_INCDEC:
5619       if (operands[2] == const1_rtx)
5620         return "inc{l}\t%k0";
5621       else
5622         {
5623           gcc_assert (operands[2] == constm1_rtx);
5624           return "dec{l}\t%k0";
5625         }
5627     default:
5628       if (which_alternative == 1)
5629         {
5630           rtx tmp;
5631           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5632         }
5634       if (x86_maybe_negate_const_int (&operands[2], SImode))
5635         return "sub{l}\t{%2, %k0|%k0, %2}";
5637       return "add{l}\t{%2, %k0|%k0, %2}";
5638     }
5640   [(set (attr "type")
5641      (if_then_else (match_operand:SI 2 "incdec_operand")
5642         (const_string "incdec")
5643         (const_string "alu")))
5644    (set (attr "length_immediate")
5645       (if_then_else
5646         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5647         (const_string "1")
5648         (const_string "*")))
5649    (set_attr "mode" "SI")])
5651 (define_insn "*add<mode>_3"
5652   [(set (reg FLAGS_REG)
5653         (compare
5654           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5655           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5656    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5657   "ix86_match_ccmode (insn, CCZmode)
5658    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5660   switch (get_attr_type (insn))
5661     {
5662     case TYPE_INCDEC:
5663       if (operands[2] == const1_rtx)
5664         return "inc{<imodesuffix>}\t%0";
5665       else
5666         {
5667           gcc_assert (operands[2] == constm1_rtx);
5668           return "dec{<imodesuffix>}\t%0";
5669         }
5671     default:
5672       if (which_alternative == 1)
5673         {
5674           rtx tmp;
5675           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5676         }
5678       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5679       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5680         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5682       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5683     }
5685   [(set (attr "type")
5686      (if_then_else (match_operand:SWI 2 "incdec_operand")
5687         (const_string "incdec")
5688         (const_string "alu")))
5689    (set (attr "length_immediate")
5690       (if_then_else
5691         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5692         (const_string "1")
5693         (const_string "*")))
5694    (set_attr "mode" "<MODE>")])
5696 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5697 (define_insn "*addsi_3_zext"
5698   [(set (reg FLAGS_REG)
5699         (compare
5700           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5701           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5702    (set (match_operand:DI 0 "register_operand" "=r,r")
5703         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5704   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5705    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5707   switch (get_attr_type (insn))
5708     {
5709     case TYPE_INCDEC:
5710       if (operands[2] == const1_rtx)
5711         return "inc{l}\t%k0";
5712       else
5713         {
5714           gcc_assert (operands[2] == constm1_rtx);
5715           return "dec{l}\t%k0";
5716         }
5718     default:
5719       if (which_alternative == 1)
5720         {
5721           rtx tmp;
5722           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5723         }
5725       if (x86_maybe_negate_const_int (&operands[2], SImode))
5726         return "sub{l}\t{%2, %k0|%k0, %2}";
5728       return "add{l}\t{%2, %k0|%k0, %2}";
5729     }
5731   [(set (attr "type")
5732      (if_then_else (match_operand:SI 2 "incdec_operand")
5733         (const_string "incdec")
5734         (const_string "alu")))
5735    (set (attr "length_immediate")
5736       (if_then_else
5737         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5738         (const_string "1")
5739         (const_string "*")))
5740    (set_attr "mode" "SI")])
5742 ; For comparisons against 1, -1 and 128, we may generate better code
5743 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5744 ; is matched then.  We can't accept general immediate, because for
5745 ; case of overflows,  the result is messed up.
5746 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5747 ; only for comparisons not depending on it.
5749 (define_insn "*adddi_4"
5750   [(set (reg FLAGS_REG)
5751         (compare
5752           (match_operand:DI 1 "nonimmediate_operand" "0")
5753           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5754    (clobber (match_scratch:DI 0 "=rm"))]
5755   "TARGET_64BIT
5756    && ix86_match_ccmode (insn, CCGCmode)"
5758   switch (get_attr_type (insn))
5759     {
5760     case TYPE_INCDEC:
5761       if (operands[2] == constm1_rtx)
5762         return "inc{q}\t%0";
5763       else
5764         {
5765           gcc_assert (operands[2] == const1_rtx);
5766           return "dec{q}\t%0";
5767         }
5769     default:
5770       if (x86_maybe_negate_const_int (&operands[2], DImode))
5771         return "add{q}\t{%2, %0|%0, %2}";
5773       return "sub{q}\t{%2, %0|%0, %2}";
5774     }
5776   [(set (attr "type")
5777      (if_then_else (match_operand:DI 2 "incdec_operand")
5778         (const_string "incdec")
5779         (const_string "alu")))
5780    (set (attr "length_immediate")
5781       (if_then_else
5782         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5783         (const_string "1")
5784         (const_string "*")))
5785    (set_attr "mode" "DI")])
5787 ; For comparisons against 1, -1 and 128, we may generate better code
5788 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5789 ; is matched then.  We can't accept general immediate, because for
5790 ; case of overflows,  the result is messed up.
5791 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5792 ; only for comparisons not depending on it.
5794 (define_insn "*add<mode>_4"
5795   [(set (reg FLAGS_REG)
5796         (compare
5797           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5798           (match_operand:SWI124 2 "const_int_operand" "n")))
5799    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5800   "ix86_match_ccmode (insn, CCGCmode)"
5802   switch (get_attr_type (insn))
5803     {
5804     case TYPE_INCDEC:
5805       if (operands[2] == constm1_rtx)
5806         return "inc{<imodesuffix>}\t%0";
5807       else
5808         {
5809           gcc_assert (operands[2] == const1_rtx);
5810           return "dec{<imodesuffix>}\t%0";
5811         }
5813     default:
5814       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5815         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5817       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5818     }
5820   [(set (attr "type")
5821      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5822         (const_string "incdec")
5823         (const_string "alu")))
5824    (set (attr "length_immediate")
5825       (if_then_else
5826         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5827         (const_string "1")
5828         (const_string "*")))
5829    (set_attr "mode" "<MODE>")])
5831 (define_insn "*add<mode>_5"
5832   [(set (reg FLAGS_REG)
5833         (compare
5834           (plus:SWI
5835             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5836             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5837           (const_int 0)))
5838    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5839   "ix86_match_ccmode (insn, CCGOCmode)
5840    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5842   switch (get_attr_type (insn))
5843     {
5844     case TYPE_INCDEC:
5845       if (operands[2] == const1_rtx)
5846         return "inc{<imodesuffix>}\t%0";
5847       else
5848         {
5849           gcc_assert (operands[2] == constm1_rtx);
5850           return "dec{<imodesuffix>}\t%0";
5851         }
5853     default:
5854       if (which_alternative == 1)
5855         {
5856           rtx tmp;
5857           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5858         }
5860       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5861       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5862         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5864       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5865     }
5867   [(set (attr "type")
5868      (if_then_else (match_operand:SWI 2 "incdec_operand")
5869         (const_string "incdec")
5870         (const_string "alu")))
5871    (set (attr "length_immediate")
5872       (if_then_else
5873         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5874         (const_string "1")
5875         (const_string "*")))
5876    (set_attr "mode" "<MODE>")])
5878 (define_insn "addqi_ext_1"
5879   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5880                          (const_int 8)
5881                          (const_int 8))
5882         (plus:SI
5883           (zero_extract:SI
5884             (match_operand 1 "ext_register_operand" "0,0")
5885             (const_int 8)
5886             (const_int 8))
5887           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5888    (clobber (reg:CC FLAGS_REG))]
5889   ""
5891   switch (get_attr_type (insn))
5892     {
5893     case TYPE_INCDEC:
5894       if (operands[2] == const1_rtx)
5895         return "inc{b}\t%h0";
5896       else
5897         {
5898           gcc_assert (operands[2] == constm1_rtx);
5899           return "dec{b}\t%h0";
5900         }
5902     default:
5903       return "add{b}\t{%2, %h0|%h0, %2}";
5904     }
5906   [(set_attr "isa" "*,nox64")
5907    (set (attr "type")
5908      (if_then_else (match_operand:QI 2 "incdec_operand")
5909         (const_string "incdec")
5910         (const_string "alu")))
5911    (set_attr "modrm" "1")
5912    (set_attr "mode" "QI")])
5914 (define_insn "*addqi_ext_2"
5915   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5916                          (const_int 8)
5917                          (const_int 8))
5918         (plus:SI
5919           (zero_extract:SI
5920             (match_operand 1 "ext_register_operand" "%0")
5921             (const_int 8)
5922             (const_int 8))
5923           (zero_extract:SI
5924             (match_operand 2 "ext_register_operand" "Q")
5925             (const_int 8)
5926             (const_int 8))))
5927    (clobber (reg:CC FLAGS_REG))]
5928   ""
5929   "add{b}\t{%h2, %h0|%h0, %h2}"
5930   [(set_attr "type" "alu")
5931    (set_attr "mode" "QI")])
5933 ;; The lea patterns for modes less than 32 bits need to be matched by
5934 ;; several insns converted to real lea by splitters.
5936 (define_insn_and_split "*lea_general_1"
5937   [(set (match_operand 0 "register_operand" "=r")
5938         (plus (plus (match_operand 1 "index_register_operand" "l")
5939                     (match_operand 2 "register_operand" "r"))
5940               (match_operand 3 "immediate_operand" "i")))]
5941   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5942    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5943    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5944    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5945    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5946        || GET_MODE (operands[3]) == VOIDmode)"
5947   "#"
5948   "&& reload_completed"
5949   [(const_int 0)]
5951   enum machine_mode mode = SImode;
5952   rtx pat;
5954   operands[0] = gen_lowpart (mode, operands[0]);
5955   operands[1] = gen_lowpart (mode, operands[1]);
5956   operands[2] = gen_lowpart (mode, operands[2]);
5957   operands[3] = gen_lowpart (mode, operands[3]);
5959   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5960                       operands[3]);
5962   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5963   DONE;
5965   [(set_attr "type" "lea")
5966    (set_attr "mode" "SI")])
5968 (define_insn_and_split "*lea_general_2"
5969   [(set (match_operand 0 "register_operand" "=r")
5970         (plus (mult (match_operand 1 "index_register_operand" "l")
5971                     (match_operand 2 "const248_operand" "n"))
5972               (match_operand 3 "nonmemory_operand" "ri")))]
5973   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5974    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5975    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5976    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5977        || GET_MODE (operands[3]) == VOIDmode)"
5978   "#"
5979   "&& reload_completed"
5980   [(const_int 0)]
5982   enum machine_mode mode = SImode;
5983   rtx pat;
5985   operands[0] = gen_lowpart (mode, operands[0]);
5986   operands[1] = gen_lowpart (mode, operands[1]);
5987   operands[3] = gen_lowpart (mode, operands[3]);
5989   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5990                       operands[3]);
5992   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5993   DONE;
5995   [(set_attr "type" "lea")
5996    (set_attr "mode" "SI")])
5998 (define_insn_and_split "*lea_general_3"
5999   [(set (match_operand 0 "register_operand" "=r")
6000         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6001                           (match_operand 2 "const248_operand" "n"))
6002                     (match_operand 3 "register_operand" "r"))
6003               (match_operand 4 "immediate_operand" "i")))]
6004   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6005    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6006    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6007    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6008   "#"
6009   "&& reload_completed"
6010   [(const_int 0)]
6012   enum machine_mode mode = SImode;
6013   rtx pat;
6015   operands[0] = gen_lowpart (mode, operands[0]);
6016   operands[1] = gen_lowpart (mode, operands[1]);
6017   operands[3] = gen_lowpart (mode, operands[3]);
6018   operands[4] = gen_lowpart (mode, operands[4]);
6020   pat = gen_rtx_PLUS (mode,
6021                       gen_rtx_PLUS (mode,
6022                                     gen_rtx_MULT (mode, operands[1],
6023                                                         operands[2]),
6024                                     operands[3]),
6025                       operands[4]);
6027   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6028   DONE;
6030   [(set_attr "type" "lea")
6031    (set_attr "mode" "SI")])
6033 (define_insn_and_split "*lea_general_4"
6034   [(set (match_operand 0 "register_operand" "=r")
6035         (any_or (ashift
6036                   (match_operand 1 "index_register_operand" "l")
6037                   (match_operand 2 "const_int_operand" "n"))
6038                 (match_operand 3 "const_int_operand" "n")))]
6039   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6040       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6041     || GET_MODE (operands[0]) == SImode
6042     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6043    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6044    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6045    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6046        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6047   "#"
6048   "&& reload_completed"
6049   [(const_int 0)]
6051   enum machine_mode mode = GET_MODE (operands[0]);
6052   rtx pat;
6054   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6055     { 
6056       mode = SImode; 
6057       operands[0] = gen_lowpart (mode, operands[0]);
6058       operands[1] = gen_lowpart (mode, operands[1]);
6059     }
6061   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6063   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6064                        INTVAL (operands[3]));
6066   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6067   DONE;
6069   [(set_attr "type" "lea")
6070    (set (attr "mode")
6071       (if_then_else (match_operand:DI 0)
6072         (const_string "DI")
6073         (const_string "SI")))])
6075 ;; Subtract instructions
6077 (define_expand "sub<mode>3"
6078   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6079         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6080                      (match_operand:SDWIM 2 "<general_operand>")))]
6081   ""
6082   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6084 (define_insn_and_split "*sub<dwi>3_doubleword"
6085   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6086         (minus:<DWI>
6087           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6088           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6089    (clobber (reg:CC FLAGS_REG))]
6090   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6091   "#"
6092   "reload_completed"
6093   [(parallel [(set (reg:CC FLAGS_REG)
6094                    (compare:CC (match_dup 1) (match_dup 2)))
6095               (set (match_dup 0)
6096                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6097    (parallel [(set (match_dup 3)
6098                    (minus:DWIH
6099                      (match_dup 4)
6100                      (plus:DWIH
6101                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6102                        (match_dup 5))))
6103               (clobber (reg:CC FLAGS_REG))])]
6104   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6106 (define_insn "*sub<mode>_1"
6107   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6108         (minus:SWI
6109           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6110           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6111    (clobber (reg:CC FLAGS_REG))]
6112   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6113   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6114   [(set_attr "type" "alu")
6115    (set_attr "mode" "<MODE>")])
6117 (define_insn "*subsi_1_zext"
6118   [(set (match_operand:DI 0 "register_operand" "=r")
6119         (zero_extend:DI
6120           (minus:SI (match_operand:SI 1 "register_operand" "0")
6121                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6122    (clobber (reg:CC FLAGS_REG))]
6123   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6124   "sub{l}\t{%2, %k0|%k0, %2}"
6125   [(set_attr "type" "alu")
6126    (set_attr "mode" "SI")])
6128 (define_insn "*subqi_1_slp"
6129   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6130         (minus:QI (match_dup 0)
6131                   (match_operand:QI 1 "general_operand" "qn,qm")))
6132    (clobber (reg:CC FLAGS_REG))]
6133   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6134    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6135   "sub{b}\t{%1, %0|%0, %1}"
6136   [(set_attr "type" "alu1")
6137    (set_attr "mode" "QI")])
6139 (define_insn "*sub<mode>_2"
6140   [(set (reg FLAGS_REG)
6141         (compare
6142           (minus:SWI
6143             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6144             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6145           (const_int 0)))
6146    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6147         (minus:SWI (match_dup 1) (match_dup 2)))]
6148   "ix86_match_ccmode (insn, CCGOCmode)
6149    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6150   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6151   [(set_attr "type" "alu")
6152    (set_attr "mode" "<MODE>")])
6154 (define_insn "*subsi_2_zext"
6155   [(set (reg FLAGS_REG)
6156         (compare
6157           (minus:SI (match_operand:SI 1 "register_operand" "0")
6158                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6159           (const_int 0)))
6160    (set (match_operand:DI 0 "register_operand" "=r")
6161         (zero_extend:DI
6162           (minus:SI (match_dup 1)
6163                     (match_dup 2))))]
6164   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6165    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6166   "sub{l}\t{%2, %k0|%k0, %2}"
6167   [(set_attr "type" "alu")
6168    (set_attr "mode" "SI")])
6170 (define_insn "*sub<mode>_3"
6171   [(set (reg FLAGS_REG)
6172         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6173                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6174    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6175         (minus:SWI (match_dup 1) (match_dup 2)))]
6176   "ix86_match_ccmode (insn, CCmode)
6177    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6178   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6179   [(set_attr "type" "alu")
6180    (set_attr "mode" "<MODE>")])
6182 (define_insn "*subsi_3_zext"
6183   [(set (reg FLAGS_REG)
6184         (compare (match_operand:SI 1 "register_operand" "0")
6185                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6186    (set (match_operand:DI 0 "register_operand" "=r")
6187         (zero_extend:DI
6188           (minus:SI (match_dup 1)
6189                     (match_dup 2))))]
6190   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6191    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6192   "sub{l}\t{%2, %1|%1, %2}"
6193   [(set_attr "type" "alu")
6194    (set_attr "mode" "SI")])
6196 ;; Add with carry and subtract with borrow
6198 (define_expand "<plusminus_insn><mode>3_carry"
6199   [(parallel
6200     [(set (match_operand:SWI 0 "nonimmediate_operand")
6201           (plusminus:SWI
6202             (match_operand:SWI 1 "nonimmediate_operand")
6203             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6204                        [(match_operand 3 "flags_reg_operand")
6205                         (const_int 0)])
6206                       (match_operand:SWI 2 "<general_operand>"))))
6207      (clobber (reg:CC FLAGS_REG))])]
6208   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6210 (define_insn "*<plusminus_insn><mode>3_carry"
6211   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6212         (plusminus:SWI
6213           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6214           (plus:SWI
6215             (match_operator 3 "ix86_carry_flag_operator"
6216              [(reg FLAGS_REG) (const_int 0)])
6217             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6218    (clobber (reg:CC FLAGS_REG))]
6219   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6220   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6221   [(set_attr "type" "alu")
6222    (set_attr "use_carry" "1")
6223    (set_attr "pent_pair" "pu")
6224    (set_attr "mode" "<MODE>")])
6226 (define_insn "*addsi3_carry_zext"
6227   [(set (match_operand:DI 0 "register_operand" "=r")
6228         (zero_extend:DI
6229           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6230                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6231                              [(reg FLAGS_REG) (const_int 0)])
6232                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6233    (clobber (reg:CC FLAGS_REG))]
6234   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6235   "adc{l}\t{%2, %k0|%k0, %2}"
6236   [(set_attr "type" "alu")
6237    (set_attr "use_carry" "1")
6238    (set_attr "pent_pair" "pu")
6239    (set_attr "mode" "SI")])
6241 (define_insn "*subsi3_carry_zext"
6242   [(set (match_operand:DI 0 "register_operand" "=r")
6243         (zero_extend:DI
6244           (minus:SI (match_operand:SI 1 "register_operand" "0")
6245                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6246                               [(reg FLAGS_REG) (const_int 0)])
6247                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6248    (clobber (reg:CC FLAGS_REG))]
6249   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6250   "sbb{l}\t{%2, %k0|%k0, %2}"
6251   [(set_attr "type" "alu")
6252    (set_attr "pent_pair" "pu")
6253    (set_attr "mode" "SI")])
6255 ;; ADCX instruction
6257 (define_insn "adcx<mode>3"
6258   [(set (reg:CCC FLAGS_REG)
6259         (compare:CCC
6260           (plus:SWI48
6261             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6262             (plus:SWI48
6263               (match_operator 4 "ix86_carry_flag_operator"
6264                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6265               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6266           (const_int 0)))
6267    (set (match_operand:SWI48 0 "register_operand" "=r")
6268         (plus:SWI48 (match_dup 1)
6269                     (plus:SWI48 (match_op_dup 4
6270                                  [(match_dup 3) (const_int 0)])
6271                                 (match_dup 2))))]
6272   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6273   "adcx\t{%2, %0|%0, %2}"
6274   [(set_attr "type" "alu")
6275    (set_attr "use_carry" "1")
6276    (set_attr "mode" "<MODE>")])
6278 ;; Overflow setting add and subtract instructions
6280 (define_insn "*add<mode>3_cconly_overflow"
6281   [(set (reg:CCC FLAGS_REG)
6282         (compare:CCC
6283           (plus:SWI
6284             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6285             (match_operand:SWI 2 "<general_operand>" "<g>"))
6286           (match_dup 1)))
6287    (clobber (match_scratch:SWI 0 "=<r>"))]
6288   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6289   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6290   [(set_attr "type" "alu")
6291    (set_attr "mode" "<MODE>")])
6293 (define_insn "*sub<mode>3_cconly_overflow"
6294   [(set (reg:CCC FLAGS_REG)
6295         (compare:CCC
6296           (minus:SWI
6297             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6298             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6299           (match_dup 0)))]
6300   ""
6301   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6302   [(set_attr "type" "icmp")
6303    (set_attr "mode" "<MODE>")])
6305 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6306   [(set (reg:CCC FLAGS_REG)
6307         (compare:CCC
6308             (plusminus:SWI
6309                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6310                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6311             (match_dup 1)))
6312    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6313         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6314   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6315   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6316   [(set_attr "type" "alu")
6317    (set_attr "mode" "<MODE>")])
6319 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6320   [(set (reg:CCC FLAGS_REG)
6321         (compare:CCC
6322           (plusminus:SI
6323             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6324             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6325           (match_dup 1)))
6326    (set (match_operand:DI 0 "register_operand" "=r")
6327         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6328   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6329   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6330   [(set_attr "type" "alu")
6331    (set_attr "mode" "SI")])
6333 ;; The patterns that match these are at the end of this file.
6335 (define_expand "<plusminus_insn>xf3"
6336   [(set (match_operand:XF 0 "register_operand")
6337         (plusminus:XF
6338           (match_operand:XF 1 "register_operand")
6339           (match_operand:XF 2 "register_operand")))]
6340   "TARGET_80387")
6342 (define_expand "<plusminus_insn><mode>3"
6343   [(set (match_operand:MODEF 0 "register_operand")
6344         (plusminus:MODEF
6345           (match_operand:MODEF 1 "register_operand")
6346           (match_operand:MODEF 2 "nonimmediate_operand")))]
6347   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6348     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6350 ;; Multiply instructions
6352 (define_expand "mul<mode>3"
6353   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6354                    (mult:SWIM248
6355                      (match_operand:SWIM248 1 "register_operand")
6356                      (match_operand:SWIM248 2 "<general_operand>")))
6357               (clobber (reg:CC FLAGS_REG))])])
6359 (define_expand "mulqi3"
6360   [(parallel [(set (match_operand:QI 0 "register_operand")
6361                    (mult:QI
6362                      (match_operand:QI 1 "register_operand")
6363                      (match_operand:QI 2 "nonimmediate_operand")))
6364               (clobber (reg:CC FLAGS_REG))])]
6365   "TARGET_QIMODE_MATH")
6367 ;; On AMDFAM10
6368 ;; IMUL reg32/64, reg32/64, imm8        Direct
6369 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6370 ;; IMUL reg32/64, reg32/64, imm32       Direct
6371 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6372 ;; IMUL reg32/64, reg32/64              Direct
6373 ;; IMUL reg32/64, mem32/64              Direct
6375 ;; On BDVER1, all above IMULs use DirectPath
6377 (define_insn "*mul<mode>3_1"
6378   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6379         (mult:SWI48
6380           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6381           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6382    (clobber (reg:CC FLAGS_REG))]
6383   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6384   "@
6385    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6386    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6387    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6388   [(set_attr "type" "imul")
6389    (set_attr "prefix_0f" "0,0,1")
6390    (set (attr "athlon_decode")
6391         (cond [(eq_attr "cpu" "athlon")
6392                   (const_string "vector")
6393                (eq_attr "alternative" "1")
6394                   (const_string "vector")
6395                (and (eq_attr "alternative" "2")
6396                     (match_operand 1 "memory_operand"))
6397                   (const_string "vector")]
6398               (const_string "direct")))
6399    (set (attr "amdfam10_decode")
6400         (cond [(and (eq_attr "alternative" "0,1")
6401                     (match_operand 1 "memory_operand"))
6402                   (const_string "vector")]
6403               (const_string "direct")))
6404    (set_attr "bdver1_decode" "direct")
6405    (set_attr "mode" "<MODE>")])
6407 (define_insn "*mulsi3_1_zext"
6408   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6409         (zero_extend:DI
6410           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6411                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6412    (clobber (reg:CC FLAGS_REG))]
6413   "TARGET_64BIT
6414    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6415   "@
6416    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6417    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6418    imul{l}\t{%2, %k0|%k0, %2}"
6419   [(set_attr "type" "imul")
6420    (set_attr "prefix_0f" "0,0,1")
6421    (set (attr "athlon_decode")
6422         (cond [(eq_attr "cpu" "athlon")
6423                   (const_string "vector")
6424                (eq_attr "alternative" "1")
6425                   (const_string "vector")
6426                (and (eq_attr "alternative" "2")
6427                     (match_operand 1 "memory_operand"))
6428                   (const_string "vector")]
6429               (const_string "direct")))
6430    (set (attr "amdfam10_decode")
6431         (cond [(and (eq_attr "alternative" "0,1")
6432                     (match_operand 1 "memory_operand"))
6433                   (const_string "vector")]
6434               (const_string "direct")))
6435    (set_attr "bdver1_decode" "direct")
6436    (set_attr "mode" "SI")])
6438 ;; On AMDFAM10
6439 ;; IMUL reg16, reg16, imm8      VectorPath
6440 ;; IMUL reg16, mem16, imm8      VectorPath
6441 ;; IMUL reg16, reg16, imm16     VectorPath
6442 ;; IMUL reg16, mem16, imm16     VectorPath
6443 ;; IMUL reg16, reg16            Direct
6444 ;; IMUL reg16, mem16            Direct
6446 ;; On BDVER1, all HI MULs use DoublePath
6448 (define_insn "*mulhi3_1"
6449   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6450         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6451                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6452    (clobber (reg:CC FLAGS_REG))]
6453   "TARGET_HIMODE_MATH
6454    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6455   "@
6456    imul{w}\t{%2, %1, %0|%0, %1, %2}
6457    imul{w}\t{%2, %1, %0|%0, %1, %2}
6458    imul{w}\t{%2, %0|%0, %2}"
6459   [(set_attr "type" "imul")
6460    (set_attr "prefix_0f" "0,0,1")
6461    (set (attr "athlon_decode")
6462         (cond [(eq_attr "cpu" "athlon")
6463                   (const_string "vector")
6464                (eq_attr "alternative" "1,2")
6465                   (const_string "vector")]
6466               (const_string "direct")))
6467    (set (attr "amdfam10_decode")
6468         (cond [(eq_attr "alternative" "0,1")
6469                   (const_string "vector")]
6470               (const_string "direct")))
6471    (set_attr "bdver1_decode" "double")
6472    (set_attr "mode" "HI")])
6474 ;;On AMDFAM10 and BDVER1
6475 ;; MUL reg8     Direct
6476 ;; MUL mem8     Direct
6478 (define_insn "*mulqi3_1"
6479   [(set (match_operand:QI 0 "register_operand" "=a")
6480         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6481                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6482    (clobber (reg:CC FLAGS_REG))]
6483   "TARGET_QIMODE_MATH
6484    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6485   "mul{b}\t%2"
6486   [(set_attr "type" "imul")
6487    (set_attr "length_immediate" "0")
6488    (set (attr "athlon_decode")
6489      (if_then_else (eq_attr "cpu" "athlon")
6490         (const_string "vector")
6491         (const_string "direct")))
6492    (set_attr "amdfam10_decode" "direct")
6493    (set_attr "bdver1_decode" "direct")
6494    (set_attr "mode" "QI")])
6496 (define_expand "<u>mul<mode><dwi>3"
6497   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6498                    (mult:<DWI>
6499                      (any_extend:<DWI>
6500                        (match_operand:DWIH 1 "nonimmediate_operand"))
6501                      (any_extend:<DWI>
6502                        (match_operand:DWIH 2 "register_operand"))))
6503               (clobber (reg:CC FLAGS_REG))])])
6505 (define_expand "<u>mulqihi3"
6506   [(parallel [(set (match_operand:HI 0 "register_operand")
6507                    (mult:HI
6508                      (any_extend:HI
6509                        (match_operand:QI 1 "nonimmediate_operand"))
6510                      (any_extend:HI
6511                        (match_operand:QI 2 "register_operand"))))
6512               (clobber (reg:CC FLAGS_REG))])]
6513   "TARGET_QIMODE_MATH")
6515 (define_insn "*bmi2_umulditi3_1"
6516   [(set (match_operand:DI 0 "register_operand" "=r")
6517         (mult:DI
6518           (match_operand:DI 2 "nonimmediate_operand" "%d")
6519           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6520    (set (match_operand:DI 1 "register_operand" "=r")
6521         (truncate:DI
6522           (lshiftrt:TI
6523             (mult:TI (zero_extend:TI (match_dup 2))
6524                      (zero_extend:TI (match_dup 3)))
6525             (const_int 64))))]
6526   "TARGET_64BIT && TARGET_BMI2
6527    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6528   "mulx\t{%3, %0, %1|%1, %0, %3}"
6529   [(set_attr "type" "imulx")
6530    (set_attr "prefix" "vex")
6531    (set_attr "mode" "DI")])
6533 (define_insn "*bmi2_umulsidi3_1"
6534   [(set (match_operand:SI 0 "register_operand" "=r")
6535         (mult:SI
6536           (match_operand:SI 2 "nonimmediate_operand" "%d")
6537           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6538    (set (match_operand:SI 1 "register_operand" "=r")
6539         (truncate:SI
6540           (lshiftrt:DI
6541             (mult:DI (zero_extend:DI (match_dup 2))
6542                      (zero_extend:DI (match_dup 3)))
6543             (const_int 32))))]
6544   "!TARGET_64BIT && TARGET_BMI2
6545    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6546   "mulx\t{%3, %0, %1|%1, %0, %3}"
6547   [(set_attr "type" "imulx")
6548    (set_attr "prefix" "vex")
6549    (set_attr "mode" "SI")])
6551 (define_insn "*umul<mode><dwi>3_1"
6552   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6553         (mult:<DWI>
6554           (zero_extend:<DWI>
6555             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6556           (zero_extend:<DWI>
6557             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6558    (clobber (reg:CC FLAGS_REG))]
6559   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6560   "@
6561    #
6562    mul{<imodesuffix>}\t%2"
6563   [(set_attr "isa" "bmi2,*")
6564    (set_attr "type" "imulx,imul")
6565    (set_attr "length_immediate" "*,0")
6566    (set (attr "athlon_decode")
6567         (cond [(eq_attr "alternative" "1")
6568                  (if_then_else (eq_attr "cpu" "athlon")
6569                    (const_string "vector")
6570                    (const_string "double"))]
6571               (const_string "*")))
6572    (set_attr "amdfam10_decode" "*,double")
6573    (set_attr "bdver1_decode" "*,direct")
6574    (set_attr "prefix" "vex,orig")
6575    (set_attr "mode" "<MODE>")])
6577 ;; Convert mul to the mulx pattern to avoid flags dependency.
6578 (define_split
6579  [(set (match_operand:<DWI> 0 "register_operand")
6580        (mult:<DWI>
6581          (zero_extend:<DWI>
6582            (match_operand:DWIH 1 "register_operand"))
6583          (zero_extend:<DWI>
6584            (match_operand:DWIH 2 "nonimmediate_operand"))))
6585   (clobber (reg:CC FLAGS_REG))]
6586  "TARGET_BMI2 && reload_completed
6587   && true_regnum (operands[1]) == DX_REG"
6588   [(parallel [(set (match_dup 3)
6589                    (mult:DWIH (match_dup 1) (match_dup 2)))
6590               (set (match_dup 4)
6591                    (truncate:DWIH
6592                      (lshiftrt:<DWI>
6593                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6594                                    (zero_extend:<DWI> (match_dup 2)))
6595                        (match_dup 5))))])]
6597   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6599   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6602 (define_insn "*mul<mode><dwi>3_1"
6603   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6604         (mult:<DWI>
6605           (sign_extend:<DWI>
6606             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6607           (sign_extend:<DWI>
6608             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6609    (clobber (reg:CC FLAGS_REG))]
6610   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6611   "imul{<imodesuffix>}\t%2"
6612   [(set_attr "type" "imul")
6613    (set_attr "length_immediate" "0")
6614    (set (attr "athlon_decode")
6615      (if_then_else (eq_attr "cpu" "athlon")
6616         (const_string "vector")
6617         (const_string "double")))
6618    (set_attr "amdfam10_decode" "double")
6619    (set_attr "bdver1_decode" "direct")
6620    (set_attr "mode" "<MODE>")])
6622 (define_insn "*<u>mulqihi3_1"
6623   [(set (match_operand:HI 0 "register_operand" "=a")
6624         (mult:HI
6625           (any_extend:HI
6626             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6627           (any_extend:HI
6628             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6629    (clobber (reg:CC FLAGS_REG))]
6630   "TARGET_QIMODE_MATH
6631    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6632   "<sgnprefix>mul{b}\t%2"
6633   [(set_attr "type" "imul")
6634    (set_attr "length_immediate" "0")
6635    (set (attr "athlon_decode")
6636      (if_then_else (eq_attr "cpu" "athlon")
6637         (const_string "vector")
6638         (const_string "direct")))
6639    (set_attr "amdfam10_decode" "direct")
6640    (set_attr "bdver1_decode" "direct")
6641    (set_attr "mode" "QI")])
6643 (define_expand "<s>mul<mode>3_highpart"
6644   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6645                    (truncate:SWI48
6646                      (lshiftrt:<DWI>
6647                        (mult:<DWI>
6648                          (any_extend:<DWI>
6649                            (match_operand:SWI48 1 "nonimmediate_operand"))
6650                          (any_extend:<DWI>
6651                            (match_operand:SWI48 2 "register_operand")))
6652                        (match_dup 4))))
6653               (clobber (match_scratch:SWI48 3))
6654               (clobber (reg:CC FLAGS_REG))])]
6655   ""
6656   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6658 (define_insn "*<s>muldi3_highpart_1"
6659   [(set (match_operand:DI 0 "register_operand" "=d")
6660         (truncate:DI
6661           (lshiftrt:TI
6662             (mult:TI
6663               (any_extend:TI
6664                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6665               (any_extend:TI
6666                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6667             (const_int 64))))
6668    (clobber (match_scratch:DI 3 "=1"))
6669    (clobber (reg:CC FLAGS_REG))]
6670   "TARGET_64BIT
6671    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6672   "<sgnprefix>mul{q}\t%2"
6673   [(set_attr "type" "imul")
6674    (set_attr "length_immediate" "0")
6675    (set (attr "athlon_decode")
6676      (if_then_else (eq_attr "cpu" "athlon")
6677         (const_string "vector")
6678         (const_string "double")))
6679    (set_attr "amdfam10_decode" "double")
6680    (set_attr "bdver1_decode" "direct")
6681    (set_attr "mode" "DI")])
6683 (define_insn "*<s>mulsi3_highpart_1"
6684   [(set (match_operand:SI 0 "register_operand" "=d")
6685         (truncate:SI
6686           (lshiftrt:DI
6687             (mult:DI
6688               (any_extend:DI
6689                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6690               (any_extend:DI
6691                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6692             (const_int 32))))
6693    (clobber (match_scratch:SI 3 "=1"))
6694    (clobber (reg:CC FLAGS_REG))]
6695   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6696   "<sgnprefix>mul{l}\t%2"
6697   [(set_attr "type" "imul")
6698    (set_attr "length_immediate" "0")
6699    (set (attr "athlon_decode")
6700      (if_then_else (eq_attr "cpu" "athlon")
6701         (const_string "vector")
6702         (const_string "double")))
6703    (set_attr "amdfam10_decode" "double")
6704    (set_attr "bdver1_decode" "direct")
6705    (set_attr "mode" "SI")])
6707 (define_insn "*<s>mulsi3_highpart_zext"
6708   [(set (match_operand:DI 0 "register_operand" "=d")
6709         (zero_extend:DI (truncate:SI
6710           (lshiftrt:DI
6711             (mult:DI (any_extend:DI
6712                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6713                      (any_extend:DI
6714                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6715             (const_int 32)))))
6716    (clobber (match_scratch:SI 3 "=1"))
6717    (clobber (reg:CC FLAGS_REG))]
6718   "TARGET_64BIT
6719    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6720   "<sgnprefix>mul{l}\t%2"
6721   [(set_attr "type" "imul")
6722    (set_attr "length_immediate" "0")
6723    (set (attr "athlon_decode")
6724      (if_then_else (eq_attr "cpu" "athlon")
6725         (const_string "vector")
6726         (const_string "double")))
6727    (set_attr "amdfam10_decode" "double")
6728    (set_attr "bdver1_decode" "direct")
6729    (set_attr "mode" "SI")])
6731 ;; The patterns that match these are at the end of this file.
6733 (define_expand "mulxf3"
6734   [(set (match_operand:XF 0 "register_operand")
6735         (mult:XF (match_operand:XF 1 "register_operand")
6736                  (match_operand:XF 2 "register_operand")))]
6737   "TARGET_80387")
6739 (define_expand "mul<mode>3"
6740   [(set (match_operand:MODEF 0 "register_operand")
6741         (mult:MODEF (match_operand:MODEF 1 "register_operand")
6742                     (match_operand:MODEF 2 "nonimmediate_operand")))]
6743   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6744     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6746 ;; Divide instructions
6748 ;; The patterns that match these are at the end of this file.
6750 (define_expand "divxf3"
6751   [(set (match_operand:XF 0 "register_operand")
6752         (div:XF (match_operand:XF 1 "register_operand")
6753                 (match_operand:XF 2 "register_operand")))]
6754   "TARGET_80387")
6756 (define_expand "divdf3"
6757   [(set (match_operand:DF 0 "register_operand")
6758         (div:DF (match_operand:DF 1 "register_operand")
6759                 (match_operand:DF 2 "nonimmediate_operand")))]
6760    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6761     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6763 (define_expand "divsf3"
6764   [(set (match_operand:SF 0 "register_operand")
6765         (div:SF (match_operand:SF 1 "register_operand")
6766                 (match_operand:SF 2 "nonimmediate_operand")))]
6767   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6768     || TARGET_SSE_MATH"
6770   if (TARGET_SSE_MATH
6771       && TARGET_RECIP_DIV
6772       && optimize_insn_for_speed_p ()
6773       && flag_finite_math_only && !flag_trapping_math
6774       && flag_unsafe_math_optimizations)
6775     {
6776       ix86_emit_swdivsf (operands[0], operands[1],
6777                          operands[2], SFmode);
6778       DONE;
6779     }
6782 ;; Divmod instructions.
6784 (define_expand "divmod<mode>4"
6785   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6786                    (div:SWIM248
6787                      (match_operand:SWIM248 1 "register_operand")
6788                      (match_operand:SWIM248 2 "nonimmediate_operand")))
6789               (set (match_operand:SWIM248 3 "register_operand")
6790                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
6791               (clobber (reg:CC FLAGS_REG))])])
6793 ;; Split with 8bit unsigned divide:
6794 ;;      if (dividend an divisor are in [0-255])
6795 ;;         use 8bit unsigned integer divide
6796 ;;       else
6797 ;;         use original integer divide
6798 (define_split
6799   [(set (match_operand:SWI48 0 "register_operand")
6800         (div:SWI48 (match_operand:SWI48 2 "register_operand")
6801                     (match_operand:SWI48 3 "nonimmediate_operand")))
6802    (set (match_operand:SWI48 1 "register_operand")
6803         (mod:SWI48 (match_dup 2) (match_dup 3)))
6804    (clobber (reg:CC FLAGS_REG))]
6805   "TARGET_USE_8BIT_IDIV
6806    && TARGET_QIMODE_MATH
6807    && can_create_pseudo_p ()
6808    && !optimize_insn_for_size_p ()"
6809   [(const_int 0)]
6810   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6812 (define_insn_and_split "divmod<mode>4_1"
6813   [(set (match_operand:SWI48 0 "register_operand" "=a")
6814         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6815                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6816    (set (match_operand:SWI48 1 "register_operand" "=&d")
6817         (mod:SWI48 (match_dup 2) (match_dup 3)))
6818    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6819    (clobber (reg:CC FLAGS_REG))]
6820   ""
6821   "#"
6822   "reload_completed"
6823   [(parallel [(set (match_dup 1)
6824                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6825               (clobber (reg:CC FLAGS_REG))])
6826    (parallel [(set (match_dup 0)
6827                    (div:SWI48 (match_dup 2) (match_dup 3)))
6828               (set (match_dup 1)
6829                    (mod:SWI48 (match_dup 2) (match_dup 3)))
6830               (use (match_dup 1))
6831               (clobber (reg:CC FLAGS_REG))])]
6833   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6835   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6836     operands[4] = operands[2];
6837   else
6838     {
6839       /* Avoid use of cltd in favor of a mov+shift.  */
6840       emit_move_insn (operands[1], operands[2]);
6841       operands[4] = operands[1];
6842     }
6844   [(set_attr "type" "multi")
6845    (set_attr "mode" "<MODE>")])
6847 (define_insn_and_split "*divmod<mode>4"
6848   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6849         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6850                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6851    (set (match_operand:SWIM248 1 "register_operand" "=&d")
6852         (mod:SWIM248 (match_dup 2) (match_dup 3)))
6853    (clobber (reg:CC FLAGS_REG))]
6854   ""
6855   "#"
6856   "reload_completed"
6857   [(parallel [(set (match_dup 1)
6858                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6859               (clobber (reg:CC FLAGS_REG))])
6860    (parallel [(set (match_dup 0)
6861                    (div:SWIM248 (match_dup 2) (match_dup 3)))
6862               (set (match_dup 1)
6863                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
6864               (use (match_dup 1))
6865               (clobber (reg:CC FLAGS_REG))])]
6867   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6869   if (<MODE>mode != HImode
6870       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6871     operands[4] = operands[2];
6872   else
6873     {
6874       /* Avoid use of cltd in favor of a mov+shift.  */
6875       emit_move_insn (operands[1], operands[2]);
6876       operands[4] = operands[1];
6877     }
6879   [(set_attr "type" "multi")
6880    (set_attr "mode" "<MODE>")])
6882 (define_insn "*divmod<mode>4_noext"
6883   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6884         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6885                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6886    (set (match_operand:SWIM248 1 "register_operand" "=d")
6887         (mod:SWIM248 (match_dup 2) (match_dup 3)))
6888    (use (match_operand:SWIM248 4 "register_operand" "1"))
6889    (clobber (reg:CC FLAGS_REG))]
6890   ""
6891   "idiv{<imodesuffix>}\t%3"
6892   [(set_attr "type" "idiv")
6893    (set_attr "mode" "<MODE>")])
6895 (define_expand "divmodqi4"
6896   [(parallel [(set (match_operand:QI 0 "register_operand")
6897                    (div:QI
6898                      (match_operand:QI 1 "register_operand")
6899                      (match_operand:QI 2 "nonimmediate_operand")))
6900               (set (match_operand:QI 3 "register_operand")
6901                    (mod:QI (match_dup 1) (match_dup 2)))
6902               (clobber (reg:CC FLAGS_REG))])]
6903   "TARGET_QIMODE_MATH"
6905   rtx div, mod, insn;
6906   rtx tmp0, tmp1;
6907   
6908   tmp0 = gen_reg_rtx (HImode);
6909   tmp1 = gen_reg_rtx (HImode);
6911   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
6912      in AX.  */
6913   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
6914   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
6916   /* Extract remainder from AH.  */
6917   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
6918   insn = emit_move_insn (operands[3], tmp1);
6920   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
6921   set_unique_reg_note (insn, REG_EQUAL, mod);
6923   /* Extract quotient from AL.  */
6924   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
6926   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
6927   set_unique_reg_note (insn, REG_EQUAL, div);
6929   DONE;
6932 ;; Divide AX by r/m8, with result stored in
6933 ;; AL <- Quotient
6934 ;; AH <- Remainder
6935 ;; Change div/mod to HImode and extend the second argument to HImode
6936 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
6937 ;; combine may fail.
6938 (define_insn "divmodhiqi3"
6939   [(set (match_operand:HI 0 "register_operand" "=a")
6940         (ior:HI
6941           (ashift:HI
6942             (zero_extend:HI
6943               (truncate:QI
6944                 (mod:HI (match_operand:HI 1 "register_operand" "0")
6945                         (sign_extend:HI
6946                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
6947             (const_int 8))
6948           (zero_extend:HI
6949             (truncate:QI
6950               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
6951    (clobber (reg:CC FLAGS_REG))]
6952   "TARGET_QIMODE_MATH"
6953   "idiv{b}\t%2"
6954   [(set_attr "type" "idiv")
6955    (set_attr "mode" "QI")])
6957 (define_expand "udivmod<mode>4"
6958   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6959                    (udiv:SWIM248
6960                      (match_operand:SWIM248 1 "register_operand")
6961                      (match_operand:SWIM248 2 "nonimmediate_operand")))
6962               (set (match_operand:SWIM248 3 "register_operand")
6963                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
6964               (clobber (reg:CC FLAGS_REG))])])
6966 ;; Split with 8bit unsigned divide:
6967 ;;      if (dividend an divisor are in [0-255])
6968 ;;         use 8bit unsigned integer divide
6969 ;;       else
6970 ;;         use original integer divide
6971 (define_split
6972   [(set (match_operand:SWI48 0 "register_operand")
6973         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
6974                     (match_operand:SWI48 3 "nonimmediate_operand")))
6975    (set (match_operand:SWI48 1 "register_operand")
6976         (umod:SWI48 (match_dup 2) (match_dup 3)))
6977    (clobber (reg:CC FLAGS_REG))]
6978   "TARGET_USE_8BIT_IDIV
6979    && TARGET_QIMODE_MATH
6980    && can_create_pseudo_p ()
6981    && !optimize_insn_for_size_p ()"
6982   [(const_int 0)]
6983   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
6985 (define_insn_and_split "udivmod<mode>4_1"
6986   [(set (match_operand:SWI48 0 "register_operand" "=a")
6987         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6988                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6989    (set (match_operand:SWI48 1 "register_operand" "=&d")
6990         (umod:SWI48 (match_dup 2) (match_dup 3)))
6991    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6992    (clobber (reg:CC FLAGS_REG))]
6993   ""
6994   "#"
6995   "reload_completed"
6996   [(set (match_dup 1) (const_int 0))
6997    (parallel [(set (match_dup 0)
6998                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
6999               (set (match_dup 1)
7000                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7001               (use (match_dup 1))
7002               (clobber (reg:CC FLAGS_REG))])]
7003   ""
7004   [(set_attr "type" "multi")
7005    (set_attr "mode" "<MODE>")])
7007 (define_insn_and_split "*udivmod<mode>4"
7008   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7009         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7010                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7011    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7012         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7013    (clobber (reg:CC FLAGS_REG))]
7014   ""
7015   "#"
7016   "reload_completed"
7017   [(set (match_dup 1) (const_int 0))
7018    (parallel [(set (match_dup 0)
7019                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7020               (set (match_dup 1)
7021                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7022               (use (match_dup 1))
7023               (clobber (reg:CC FLAGS_REG))])]
7024   ""
7025   [(set_attr "type" "multi")
7026    (set_attr "mode" "<MODE>")])
7028 (define_insn "*udivmod<mode>4_noext"
7029   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7030         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7031                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7032    (set (match_operand:SWIM248 1 "register_operand" "=d")
7033         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7034    (use (match_operand:SWIM248 4 "register_operand" "1"))
7035    (clobber (reg:CC FLAGS_REG))]
7036   ""
7037   "div{<imodesuffix>}\t%3"
7038   [(set_attr "type" "idiv")
7039    (set_attr "mode" "<MODE>")])
7041 (define_expand "udivmodqi4"
7042   [(parallel [(set (match_operand:QI 0 "register_operand")
7043                    (udiv:QI
7044                      (match_operand:QI 1 "register_operand")
7045                      (match_operand:QI 2 "nonimmediate_operand")))
7046               (set (match_operand:QI 3 "register_operand")
7047                    (umod:QI (match_dup 1) (match_dup 2)))
7048               (clobber (reg:CC FLAGS_REG))])]
7049   "TARGET_QIMODE_MATH"
7051   rtx div, mod, insn;
7052   rtx tmp0, tmp1;
7053   
7054   tmp0 = gen_reg_rtx (HImode);
7055   tmp1 = gen_reg_rtx (HImode);
7057   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7058      in AX.  */
7059   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7060   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7062   /* Extract remainder from AH.  */
7063   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7064   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7065   insn = emit_move_insn (operands[3], tmp1);
7067   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7068   set_unique_reg_note (insn, REG_EQUAL, mod);
7070   /* Extract quotient from AL.  */
7071   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7073   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7074   set_unique_reg_note (insn, REG_EQUAL, div);
7076   DONE;
7079 (define_insn "udivmodhiqi3"
7080   [(set (match_operand:HI 0 "register_operand" "=a")
7081         (ior:HI
7082           (ashift:HI
7083             (zero_extend:HI
7084               (truncate:QI
7085                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7086                         (zero_extend:HI
7087                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7088             (const_int 8))
7089           (zero_extend:HI
7090             (truncate:QI
7091               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7092    (clobber (reg:CC FLAGS_REG))]
7093   "TARGET_QIMODE_MATH"
7094   "div{b}\t%2"
7095   [(set_attr "type" "idiv")
7096    (set_attr "mode" "QI")])
7098 ;; We cannot use div/idiv for double division, because it causes
7099 ;; "division by zero" on the overflow and that's not what we expect
7100 ;; from truncate.  Because true (non truncating) double division is
7101 ;; never generated, we can't create this insn anyway.
7103 ;(define_insn ""
7104 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7105 ;       (truncate:SI
7106 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7107 ;                  (zero_extend:DI
7108 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7109 ;   (set (match_operand:SI 3 "register_operand" "=d")
7110 ;       (truncate:SI
7111 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7112 ;   (clobber (reg:CC FLAGS_REG))]
7113 ;  ""
7114 ;  "div{l}\t{%2, %0|%0, %2}"
7115 ;  [(set_attr "type" "idiv")])
7117 ;;- Logical AND instructions
7119 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7120 ;; Note that this excludes ah.
7122 (define_expand "testsi_ccno_1"
7123   [(set (reg:CCNO FLAGS_REG)
7124         (compare:CCNO
7125           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7126                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7127           (const_int 0)))])
7129 (define_expand "testqi_ccz_1"
7130   [(set (reg:CCZ FLAGS_REG)
7131         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7132                              (match_operand:QI 1 "nonmemory_operand"))
7133                  (const_int 0)))])
7135 (define_expand "testdi_ccno_1"
7136   [(set (reg:CCNO FLAGS_REG)
7137         (compare:CCNO
7138           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7139                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7140           (const_int 0)))]
7141   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7143 (define_insn "*testdi_1"
7144   [(set (reg FLAGS_REG)
7145         (compare
7146          (and:DI
7147           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7148           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7149          (const_int 0)))]
7150   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7151    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7152   "@
7153    test{l}\t{%k1, %k0|%k0, %k1}
7154    test{l}\t{%k1, %k0|%k0, %k1}
7155    test{q}\t{%1, %0|%0, %1}
7156    test{q}\t{%1, %0|%0, %1}
7157    test{q}\t{%1, %0|%0, %1}"
7158   [(set_attr "type" "test")
7159    (set_attr "modrm" "0,1,0,1,1")
7160    (set_attr "mode" "SI,SI,DI,DI,DI")])
7162 (define_insn "*testqi_1_maybe_si"
7163   [(set (reg FLAGS_REG)
7164         (compare
7165           (and:QI
7166             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7167             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7168           (const_int 0)))]
7169    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7170     && ix86_match_ccmode (insn,
7171                          CONST_INT_P (operands[1])
7172                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7174   if (which_alternative == 3)
7175     {
7176       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7177         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7178       return "test{l}\t{%1, %k0|%k0, %1}";
7179     }
7180   return "test{b}\t{%1, %0|%0, %1}";
7182   [(set_attr "type" "test")
7183    (set_attr "modrm" "0,1,1,1")
7184    (set_attr "mode" "QI,QI,QI,SI")
7185    (set_attr "pent_pair" "uv,np,uv,np")])
7187 (define_insn "*test<mode>_1"
7188   [(set (reg FLAGS_REG)
7189         (compare
7190          (and:SWI124
7191           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7192           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7193          (const_int 0)))]
7194   "ix86_match_ccmode (insn, CCNOmode)
7195    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7196   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7197   [(set_attr "type" "test")
7198    (set_attr "modrm" "0,1,1")
7199    (set_attr "mode" "<MODE>")
7200    (set_attr "pent_pair" "uv,np,uv")])
7202 (define_expand "testqi_ext_ccno_0"
7203   [(set (reg:CCNO FLAGS_REG)
7204         (compare:CCNO
7205           (and:SI
7206             (zero_extract:SI
7207               (match_operand 0 "ext_register_operand")
7208               (const_int 8)
7209               (const_int 8))
7210             (match_operand 1 "const_int_operand"))
7211           (const_int 0)))])
7213 (define_insn "*testqi_ext_0"
7214   [(set (reg FLAGS_REG)
7215         (compare
7216           (and:SI
7217             (zero_extract:SI
7218               (match_operand 0 "ext_register_operand" "Q")
7219               (const_int 8)
7220               (const_int 8))
7221             (match_operand 1 "const_int_operand" "n"))
7222           (const_int 0)))]
7223   "ix86_match_ccmode (insn, CCNOmode)"
7224   "test{b}\t{%1, %h0|%h0, %1}"
7225   [(set_attr "type" "test")
7226    (set_attr "mode" "QI")
7227    (set_attr "length_immediate" "1")
7228    (set_attr "modrm" "1")
7229    (set_attr "pent_pair" "np")])
7231 (define_insn "*testqi_ext_1"
7232   [(set (reg FLAGS_REG)
7233         (compare
7234           (and:SI
7235             (zero_extract:SI
7236               (match_operand 0 "ext_register_operand" "Q,Q")
7237               (const_int 8)
7238               (const_int 8))
7239             (zero_extend:SI
7240               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7241           (const_int 0)))]
7242   "ix86_match_ccmode (insn, CCNOmode)"
7243   "test{b}\t{%1, %h0|%h0, %1}"
7244   [(set_attr "isa" "*,nox64")
7245    (set_attr "type" "test")
7246    (set_attr "mode" "QI")])
7248 (define_insn "*testqi_ext_2"
7249   [(set (reg FLAGS_REG)
7250         (compare
7251           (and:SI
7252             (zero_extract:SI
7253               (match_operand 0 "ext_register_operand" "Q")
7254               (const_int 8)
7255               (const_int 8))
7256             (zero_extract:SI
7257               (match_operand 1 "ext_register_operand" "Q")
7258               (const_int 8)
7259               (const_int 8)))
7260           (const_int 0)))]
7261   "ix86_match_ccmode (insn, CCNOmode)"
7262   "test{b}\t{%h1, %h0|%h0, %h1}"
7263   [(set_attr "type" "test")
7264    (set_attr "mode" "QI")])
7266 ;; Combine likes to form bit extractions for some tests.  Humor it.
7267 (define_insn "*testqi_ext_3"
7268   [(set (reg FLAGS_REG)
7269         (compare (zero_extract:SWI48
7270                    (match_operand 0 "nonimmediate_operand" "rm")
7271                    (match_operand:SWI48 1 "const_int_operand")
7272                    (match_operand:SWI48 2 "const_int_operand"))
7273                  (const_int 0)))]
7274   "ix86_match_ccmode (insn, CCNOmode)
7275    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7276        || GET_MODE (operands[0]) == SImode
7277        || GET_MODE (operands[0]) == HImode
7278        || GET_MODE (operands[0]) == QImode)
7279    /* Ensure that resulting mask is zero or sign extended operand.  */
7280    && INTVAL (operands[2]) >= 0
7281    && ((INTVAL (operands[1]) > 0
7282         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7283        || (<MODE>mode == DImode
7284            && INTVAL (operands[1]) > 32
7285            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7286   "#")
7288 (define_split
7289   [(set (match_operand 0 "flags_reg_operand")
7290         (match_operator 1 "compare_operator"
7291           [(zero_extract
7292              (match_operand 2 "nonimmediate_operand")
7293              (match_operand 3 "const_int_operand")
7294              (match_operand 4 "const_int_operand"))
7295            (const_int 0)]))]
7296   "ix86_match_ccmode (insn, CCNOmode)"
7297   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7299   rtx val = operands[2];
7300   HOST_WIDE_INT len = INTVAL (operands[3]);
7301   HOST_WIDE_INT pos = INTVAL (operands[4]);
7302   HOST_WIDE_INT mask;
7303   enum machine_mode mode, submode;
7305   mode = GET_MODE (val);
7306   if (MEM_P (val))
7307     {
7308       /* ??? Combine likes to put non-volatile mem extractions in QImode
7309          no matter the size of the test.  So find a mode that works.  */
7310       if (! MEM_VOLATILE_P (val))
7311         {
7312           mode = smallest_mode_for_size (pos + len, MODE_INT);
7313           val = adjust_address (val, mode, 0);
7314         }
7315     }
7316   else if (GET_CODE (val) == SUBREG
7317            && (submode = GET_MODE (SUBREG_REG (val)),
7318                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7319            && pos + len <= GET_MODE_BITSIZE (submode)
7320            && GET_MODE_CLASS (submode) == MODE_INT)
7321     {
7322       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7323       mode = submode;
7324       val = SUBREG_REG (val);
7325     }
7326   else if (mode == HImode && pos + len <= 8)
7327     {
7328       /* Small HImode tests can be converted to QImode.  */
7329       mode = QImode;
7330       val = gen_lowpart (QImode, val);
7331     }
7333   if (len == HOST_BITS_PER_WIDE_INT)
7334     mask = -1;
7335   else
7336     mask = ((HOST_WIDE_INT)1 << len) - 1;
7337   mask <<= pos;
7339   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7342 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7343 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7344 ;; this is relatively important trick.
7345 ;; Do the conversion only post-reload to avoid limiting of the register class
7346 ;; to QI regs.
7347 (define_split
7348   [(set (match_operand 0 "flags_reg_operand")
7349         (match_operator 1 "compare_operator"
7350           [(and (match_operand 2 "register_operand")
7351                 (match_operand 3 "const_int_operand"))
7352            (const_int 0)]))]
7353    "reload_completed
7354     && QI_REG_P (operands[2])
7355     && GET_MODE (operands[2]) != QImode
7356     && ((ix86_match_ccmode (insn, CCZmode)
7357          && !(INTVAL (operands[3]) & ~(255 << 8)))
7358         || (ix86_match_ccmode (insn, CCNOmode)
7359             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7360   [(set (match_dup 0)
7361         (match_op_dup 1
7362           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7363                    (match_dup 3))
7364            (const_int 0)]))]
7366   operands[2] = gen_lowpart (SImode, operands[2]);
7367   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7370 (define_split
7371   [(set (match_operand 0 "flags_reg_operand")
7372         (match_operator 1 "compare_operator"
7373           [(and (match_operand 2 "nonimmediate_operand")
7374                 (match_operand 3 "const_int_operand"))
7375            (const_int 0)]))]
7376    "reload_completed
7377     && GET_MODE (operands[2]) != QImode
7378     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7379     && ((ix86_match_ccmode (insn, CCZmode)
7380          && !(INTVAL (operands[3]) & ~255))
7381         || (ix86_match_ccmode (insn, CCNOmode)
7382             && !(INTVAL (operands[3]) & ~127)))"
7383   [(set (match_dup 0)
7384         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7385                          (const_int 0)]))]
7387   operands[2] = gen_lowpart (QImode, operands[2]);
7388   operands[3] = gen_lowpart (QImode, operands[3]);
7391 ;; %%% This used to optimize known byte-wide and operations to memory,
7392 ;; and sometimes to QImode registers.  If this is considered useful,
7393 ;; it should be done with splitters.
7395 (define_expand "and<mode>3"
7396   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7397         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7398                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7399   ""
7401   enum machine_mode mode = <MODE>mode;
7402   rtx (*insn) (rtx, rtx);
7404   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7405     {
7406       HOST_WIDE_INT ival = INTVAL (operands[2]);
7408       if (ival == (HOST_WIDE_INT) 0xffffffff)
7409         mode = SImode;
7410       else if (ival == 0xffff)
7411         mode = HImode;
7412       else if (ival == 0xff)
7413         mode = QImode;
7414       }
7416   if (mode == <MODE>mode)
7417     {
7418       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7419       DONE;
7420     }
7422   if (<MODE>mode == DImode)
7423     insn = (mode == SImode)
7424            ? gen_zero_extendsidi2
7425            : (mode == HImode)
7426            ? gen_zero_extendhidi2
7427            : gen_zero_extendqidi2;
7428   else if (<MODE>mode == SImode)
7429     insn = (mode == HImode)
7430            ? gen_zero_extendhisi2
7431            : gen_zero_extendqisi2;
7432   else if (<MODE>mode == HImode)
7433     insn = gen_zero_extendqihi2;
7434   else
7435     gcc_unreachable ();
7437   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7438   DONE;
7441 (define_insn "*anddi_1"
7442   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7443         (and:DI
7444          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7445          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7446    (clobber (reg:CC FLAGS_REG))]
7447   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7449   switch (get_attr_type (insn))
7450     {
7451     case TYPE_IMOVX:
7452       return "#";
7454     default:
7455       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7456       if (get_attr_mode (insn) == MODE_SI)
7457         return "and{l}\t{%k2, %k0|%k0, %k2}";
7458       else
7459         return "and{q}\t{%2, %0|%0, %2}";
7460     }
7462   [(set_attr "type" "alu,alu,alu,imovx")
7463    (set_attr "length_immediate" "*,*,*,0")
7464    (set (attr "prefix_rex")
7465      (if_then_else
7466        (and (eq_attr "type" "imovx")
7467             (and (match_test "INTVAL (operands[2]) == 0xff")
7468                  (match_operand 1 "ext_QIreg_operand")))
7469        (const_string "1")
7470        (const_string "*")))
7471    (set_attr "mode" "SI,DI,DI,SI")])
7473 (define_insn "*andsi_1"
7474   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7475         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7476                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7477    (clobber (reg:CC FLAGS_REG))]
7478   "ix86_binary_operator_ok (AND, SImode, operands)"
7480   switch (get_attr_type (insn))
7481     {
7482     case TYPE_IMOVX:
7483       return "#";
7485     default:
7486       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7487       return "and{l}\t{%2, %0|%0, %2}";
7488     }
7490   [(set_attr "type" "alu,alu,imovx")
7491    (set (attr "prefix_rex")
7492      (if_then_else
7493        (and (eq_attr "type" "imovx")
7494             (and (match_test "INTVAL (operands[2]) == 0xff")
7495                  (match_operand 1 "ext_QIreg_operand")))
7496        (const_string "1")
7497        (const_string "*")))
7498    (set_attr "length_immediate" "*,*,0")
7499    (set_attr "mode" "SI")])
7501 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7502 (define_insn "*andsi_1_zext"
7503   [(set (match_operand:DI 0 "register_operand" "=r")
7504         (zero_extend:DI
7505           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7506                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7507    (clobber (reg:CC FLAGS_REG))]
7508   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7509   "and{l}\t{%2, %k0|%k0, %2}"
7510   [(set_attr "type" "alu")
7511    (set_attr "mode" "SI")])
7513 (define_insn "*andhi_1"
7514   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7515         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7516                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7517    (clobber (reg:CC FLAGS_REG))]
7518   "ix86_binary_operator_ok (AND, HImode, operands)"
7520   switch (get_attr_type (insn))
7521     {
7522     case TYPE_IMOVX:
7523       return "#";
7525     default:
7526       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7527       return "and{w}\t{%2, %0|%0, %2}";
7528     }
7530   [(set_attr "type" "alu,alu,imovx")
7531    (set_attr "length_immediate" "*,*,0")
7532    (set (attr "prefix_rex")
7533      (if_then_else
7534        (and (eq_attr "type" "imovx")
7535             (match_operand 1 "ext_QIreg_operand"))
7536        (const_string "1")
7537        (const_string "*")))
7538    (set_attr "mode" "HI,HI,SI")])
7540 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7541 (define_insn "*andqi_1"
7542   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7543         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7544                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7545    (clobber (reg:CC FLAGS_REG))]
7546   "ix86_binary_operator_ok (AND, QImode, operands)"
7547   "@
7548    and{b}\t{%2, %0|%0, %2}
7549    and{b}\t{%2, %0|%0, %2}
7550    and{l}\t{%k2, %k0|%k0, %k2}"
7551   [(set_attr "type" "alu")
7552    (set_attr "mode" "QI,QI,SI")])
7554 (define_insn "*andqi_1_slp"
7555   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7556         (and:QI (match_dup 0)
7557                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7558    (clobber (reg:CC FLAGS_REG))]
7559   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7560    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7561   "and{b}\t{%1, %0|%0, %1}"
7562   [(set_attr "type" "alu1")
7563    (set_attr "mode" "QI")])
7565 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7566 (define_split
7567   [(set (match_operand:DI 0 "register_operand")
7568         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7569                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7570    (clobber (reg:CC FLAGS_REG))]
7571   "TARGET_64BIT"
7572   [(parallel [(set (match_dup 0)
7573                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7574               (clobber (reg:CC FLAGS_REG))])]
7575   "operands[2] = gen_lowpart (SImode, operands[2]);")
7577 (define_split
7578   [(set (match_operand:SWI248 0 "register_operand")
7579         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7580                     (match_operand:SWI248 2 "const_int_operand")))
7581    (clobber (reg:CC FLAGS_REG))]
7582   "reload_completed
7583    && true_regnum (operands[0]) != true_regnum (operands[1])"
7584   [(const_int 0)]
7586   HOST_WIDE_INT ival = INTVAL (operands[2]);
7587   enum machine_mode mode;
7588   rtx (*insn) (rtx, rtx);
7590   if (ival == (HOST_WIDE_INT) 0xffffffff)
7591     mode = SImode;
7592   else if (ival == 0xffff)
7593     mode = HImode;
7594   else
7595     {
7596       gcc_assert (ival == 0xff);
7597       mode = QImode;
7598     }
7600   if (<MODE>mode == DImode)
7601     insn = (mode == SImode)
7602            ? gen_zero_extendsidi2
7603            : (mode == HImode)
7604            ? gen_zero_extendhidi2
7605            : gen_zero_extendqidi2;
7606   else
7607     {
7608       if (<MODE>mode != SImode)
7609         /* Zero extend to SImode to avoid partial register stalls.  */
7610         operands[0] = gen_lowpart (SImode, operands[0]);
7612       insn = (mode == HImode)
7613              ? gen_zero_extendhisi2
7614              : gen_zero_extendqisi2;
7615     }
7616   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7617   DONE;
7620 (define_split
7621   [(set (match_operand 0 "register_operand")
7622         (and (match_dup 0)
7623              (const_int -65536)))
7624    (clobber (reg:CC FLAGS_REG))]
7625   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7626     || optimize_function_for_size_p (cfun)"
7627   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7628   "operands[1] = gen_lowpart (HImode, operands[0]);")
7630 (define_split
7631   [(set (match_operand 0 "ext_register_operand")
7632         (and (match_dup 0)
7633              (const_int -256)))
7634    (clobber (reg:CC FLAGS_REG))]
7635   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7636    && reload_completed"
7637   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7638   "operands[1] = gen_lowpart (QImode, operands[0]);")
7640 (define_split
7641   [(set (match_operand 0 "ext_register_operand")
7642         (and (match_dup 0)
7643              (const_int -65281)))
7644    (clobber (reg:CC FLAGS_REG))]
7645   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7646    && reload_completed"
7647   [(parallel [(set (zero_extract:SI (match_dup 0)
7648                                     (const_int 8)
7649                                     (const_int 8))
7650                    (xor:SI
7651                      (zero_extract:SI (match_dup 0)
7652                                       (const_int 8)
7653                                       (const_int 8))
7654                      (zero_extract:SI (match_dup 0)
7655                                       (const_int 8)
7656                                       (const_int 8))))
7657               (clobber (reg:CC FLAGS_REG))])]
7658   "operands[0] = gen_lowpart (SImode, operands[0]);")
7660 (define_insn "*anddi_2"
7661   [(set (reg FLAGS_REG)
7662         (compare
7663          (and:DI
7664           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7665           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7666          (const_int 0)))
7667    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7668         (and:DI (match_dup 1) (match_dup 2)))]
7669   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7670    && ix86_binary_operator_ok (AND, DImode, operands)"
7671   "@
7672    and{l}\t{%k2, %k0|%k0, %k2}
7673    and{q}\t{%2, %0|%0, %2}
7674    and{q}\t{%2, %0|%0, %2}"
7675   [(set_attr "type" "alu")
7676    (set_attr "mode" "SI,DI,DI")])
7678 (define_insn "*andqi_2_maybe_si"
7679   [(set (reg FLAGS_REG)
7680         (compare (and:QI
7681                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7682                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7683                  (const_int 0)))
7684    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7685         (and:QI (match_dup 1) (match_dup 2)))]
7686   "ix86_binary_operator_ok (AND, QImode, operands)
7687    && ix86_match_ccmode (insn,
7688                          CONST_INT_P (operands[2])
7689                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7691   if (which_alternative == 2)
7692     {
7693       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7694         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7695       return "and{l}\t{%2, %k0|%k0, %2}";
7696     }
7697   return "and{b}\t{%2, %0|%0, %2}";
7699   [(set_attr "type" "alu")
7700    (set_attr "mode" "QI,QI,SI")])
7702 (define_insn "*and<mode>_2"
7703   [(set (reg FLAGS_REG)
7704         (compare (and:SWI124
7705                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7706                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7707                  (const_int 0)))
7708    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7709         (and:SWI124 (match_dup 1) (match_dup 2)))]
7710   "ix86_match_ccmode (insn, CCNOmode)
7711    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7712   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7713   [(set_attr "type" "alu")
7714    (set_attr "mode" "<MODE>")])
7716 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7717 (define_insn "*andsi_2_zext"
7718   [(set (reg FLAGS_REG)
7719         (compare (and:SI
7720                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7721                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7722                  (const_int 0)))
7723    (set (match_operand:DI 0 "register_operand" "=r")
7724         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7725   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7726    && ix86_binary_operator_ok (AND, SImode, operands)"
7727   "and{l}\t{%2, %k0|%k0, %2}"
7728   [(set_attr "type" "alu")
7729    (set_attr "mode" "SI")])
7731 (define_insn "*andqi_2_slp"
7732   [(set (reg FLAGS_REG)
7733         (compare (and:QI
7734                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7735                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7736                  (const_int 0)))
7737    (set (strict_low_part (match_dup 0))
7738         (and:QI (match_dup 0) (match_dup 1)))]
7739   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7740    && ix86_match_ccmode (insn, CCNOmode)
7741    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7742   "and{b}\t{%1, %0|%0, %1}"
7743   [(set_attr "type" "alu1")
7744    (set_attr "mode" "QI")])
7746 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7747 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7748 ;; for a QImode operand, which of course failed.
7749 (define_insn "andqi_ext_0"
7750   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7751                          (const_int 8)
7752                          (const_int 8))
7753         (and:SI
7754           (zero_extract:SI
7755             (match_operand 1 "ext_register_operand" "0")
7756             (const_int 8)
7757             (const_int 8))
7758           (match_operand 2 "const_int_operand" "n")))
7759    (clobber (reg:CC FLAGS_REG))]
7760   ""
7761   "and{b}\t{%2, %h0|%h0, %2}"
7762   [(set_attr "type" "alu")
7763    (set_attr "length_immediate" "1")
7764    (set_attr "modrm" "1")
7765    (set_attr "mode" "QI")])
7767 ;; Generated by peephole translating test to and.  This shows up
7768 ;; often in fp comparisons.
7769 (define_insn "*andqi_ext_0_cc"
7770   [(set (reg FLAGS_REG)
7771         (compare
7772           (and:SI
7773             (zero_extract:SI
7774               (match_operand 1 "ext_register_operand" "0")
7775               (const_int 8)
7776               (const_int 8))
7777             (match_operand 2 "const_int_operand" "n"))
7778           (const_int 0)))
7779    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7780                          (const_int 8)
7781                          (const_int 8))
7782         (and:SI
7783           (zero_extract:SI
7784             (match_dup 1)
7785             (const_int 8)
7786             (const_int 8))
7787           (match_dup 2)))]
7788   "ix86_match_ccmode (insn, CCNOmode)"
7789   "and{b}\t{%2, %h0|%h0, %2}"
7790   [(set_attr "type" "alu")
7791    (set_attr "length_immediate" "1")
7792    (set_attr "modrm" "1")
7793    (set_attr "mode" "QI")])
7795 (define_insn "*andqi_ext_1"
7796   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
7797                          (const_int 8)
7798                          (const_int 8))
7799         (and:SI
7800           (zero_extract:SI
7801             (match_operand 1 "ext_register_operand" "0,0")
7802             (const_int 8)
7803             (const_int 8))
7804           (zero_extend:SI
7805             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
7806    (clobber (reg:CC FLAGS_REG))]
7807   ""
7808   "and{b}\t{%2, %h0|%h0, %2}"
7809   [(set_attr "isa" "*,nox64")
7810    (set_attr "type" "alu")
7811    (set_attr "length_immediate" "0")
7812    (set_attr "mode" "QI")])
7814 (define_insn "*andqi_ext_2"
7815   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7816                          (const_int 8)
7817                          (const_int 8))
7818         (and:SI
7819           (zero_extract:SI
7820             (match_operand 1 "ext_register_operand" "%0")
7821             (const_int 8)
7822             (const_int 8))
7823           (zero_extract:SI
7824             (match_operand 2 "ext_register_operand" "Q")
7825             (const_int 8)
7826             (const_int 8))))
7827    (clobber (reg:CC FLAGS_REG))]
7828   ""
7829   "and{b}\t{%h2, %h0|%h0, %h2}"
7830   [(set_attr "type" "alu")
7831    (set_attr "length_immediate" "0")
7832    (set_attr "mode" "QI")])
7834 ;; Convert wide AND instructions with immediate operand to shorter QImode
7835 ;; equivalents when possible.
7836 ;; Don't do the splitting with memory operands, since it introduces risk
7837 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
7838 ;; for size, but that can (should?) be handled by generic code instead.
7839 (define_split
7840   [(set (match_operand 0 "register_operand")
7841         (and (match_operand 1 "register_operand")
7842              (match_operand 2 "const_int_operand")))
7843    (clobber (reg:CC FLAGS_REG))]
7844    "reload_completed
7845     && QI_REG_P (operands[0])
7846     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7847     && !(~INTVAL (operands[2]) & ~(255 << 8))
7848     && GET_MODE (operands[0]) != QImode"
7849   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7850                    (and:SI (zero_extract:SI (match_dup 1)
7851                                             (const_int 8) (const_int 8))
7852                            (match_dup 2)))
7853               (clobber (reg:CC FLAGS_REG))])]
7855   operands[0] = gen_lowpart (SImode, operands[0]);
7856   operands[1] = gen_lowpart (SImode, operands[1]);
7857   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
7860 ;; Since AND can be encoded with sign extended immediate, this is only
7861 ;; profitable when 7th bit is not set.
7862 (define_split
7863   [(set (match_operand 0 "register_operand")
7864         (and (match_operand 1 "general_operand")
7865              (match_operand 2 "const_int_operand")))
7866    (clobber (reg:CC FLAGS_REG))]
7867    "reload_completed
7868     && ANY_QI_REG_P (operands[0])
7869     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7870     && !(~INTVAL (operands[2]) & ~255)
7871     && !(INTVAL (operands[2]) & 128)
7872     && GET_MODE (operands[0]) != QImode"
7873   [(parallel [(set (strict_low_part (match_dup 0))
7874                    (and:QI (match_dup 1)
7875                            (match_dup 2)))
7876               (clobber (reg:CC FLAGS_REG))])]
7878   operands[0] = gen_lowpart (QImode, operands[0]);
7879   operands[1] = gen_lowpart (QImode, operands[1]);
7880   operands[2] = gen_lowpart (QImode, operands[2]);
7883 ;; Logical inclusive and exclusive OR instructions
7885 ;; %%% This used to optimize known byte-wide and operations to memory.
7886 ;; If this is considered useful, it should be done with splitters.
7888 (define_expand "<code><mode>3"
7889   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7890         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7891                      (match_operand:SWIM 2 "<general_operand>")))]
7892   ""
7893   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
7895 (define_insn "*<code><mode>_1"
7896   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
7897         (any_or:SWI248
7898          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
7899          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
7900    (clobber (reg:CC FLAGS_REG))]
7901   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7902   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7903   [(set_attr "type" "alu")
7904    (set_attr "mode" "<MODE>")])
7906 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7907 (define_insn "*<code>qi_1"
7908   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
7909         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7910                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
7911    (clobber (reg:CC FLAGS_REG))]
7912   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
7913   "@
7914    <logic>{b}\t{%2, %0|%0, %2}
7915    <logic>{b}\t{%2, %0|%0, %2}
7916    <logic>{l}\t{%k2, %k0|%k0, %k2}"
7917   [(set_attr "type" "alu")
7918    (set_attr "mode" "QI,QI,SI")])
7920 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7921 (define_insn "*<code>si_1_zext"
7922   [(set (match_operand:DI 0 "register_operand" "=r")
7923         (zero_extend:DI
7924          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7925                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7926    (clobber (reg:CC FLAGS_REG))]
7927   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7928   "<logic>{l}\t{%2, %k0|%k0, %2}"
7929   [(set_attr "type" "alu")
7930    (set_attr "mode" "SI")])
7932 (define_insn "*<code>si_1_zext_imm"
7933   [(set (match_operand:DI 0 "register_operand" "=r")
7934         (any_or:DI
7935          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7936          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
7937    (clobber (reg:CC FLAGS_REG))]
7938   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7939   "<logic>{l}\t{%2, %k0|%k0, %2}"
7940   [(set_attr "type" "alu")
7941    (set_attr "mode" "SI")])
7943 (define_insn "*<code>qi_1_slp"
7944   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
7945         (any_or:QI (match_dup 0)
7946                    (match_operand:QI 1 "general_operand" "qmn,qn")))
7947    (clobber (reg:CC FLAGS_REG))]
7948   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7949    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7950   "<logic>{b}\t{%1, %0|%0, %1}"
7951   [(set_attr "type" "alu1")
7952    (set_attr "mode" "QI")])
7954 (define_insn "*<code><mode>_2"
7955   [(set (reg FLAGS_REG)
7956         (compare (any_or:SWI
7957                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7958                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
7959                  (const_int 0)))
7960    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
7961         (any_or:SWI (match_dup 1) (match_dup 2)))]
7962   "ix86_match_ccmode (insn, CCNOmode)
7963    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7964   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7965   [(set_attr "type" "alu")
7966    (set_attr "mode" "<MODE>")])
7968 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7969 ;; ??? Special case for immediate operand is missing - it is tricky.
7970 (define_insn "*<code>si_2_zext"
7971   [(set (reg FLAGS_REG)
7972         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7973                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7974                  (const_int 0)))
7975    (set (match_operand:DI 0 "register_operand" "=r")
7976         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
7977   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7978    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7979   "<logic>{l}\t{%2, %k0|%k0, %2}"
7980   [(set_attr "type" "alu")
7981    (set_attr "mode" "SI")])
7983 (define_insn "*<code>si_2_zext_imm"
7984   [(set (reg FLAGS_REG)
7985         (compare (any_or:SI
7986                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7987                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
7988                  (const_int 0)))
7989    (set (match_operand:DI 0 "register_operand" "=r")
7990         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
7991   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7992    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7993   "<logic>{l}\t{%2, %k0|%k0, %2}"
7994   [(set_attr "type" "alu")
7995    (set_attr "mode" "SI")])
7997 (define_insn "*<code>qi_2_slp"
7998   [(set (reg FLAGS_REG)
7999         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8000                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8001                  (const_int 0)))
8002    (set (strict_low_part (match_dup 0))
8003         (any_or:QI (match_dup 0) (match_dup 1)))]
8004   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8005    && ix86_match_ccmode (insn, CCNOmode)
8006    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8007   "<logic>{b}\t{%1, %0|%0, %1}"
8008   [(set_attr "type" "alu1")
8009    (set_attr "mode" "QI")])
8011 (define_insn "*<code><mode>_3"
8012   [(set (reg FLAGS_REG)
8013         (compare (any_or:SWI
8014                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8015                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8016                  (const_int 0)))
8017    (clobber (match_scratch:SWI 0 "=<r>"))]
8018   "ix86_match_ccmode (insn, CCNOmode)
8019    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8020   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8021   [(set_attr "type" "alu")
8022    (set_attr "mode" "<MODE>")])
8024 (define_insn "*<code>qi_ext_0"
8025   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8026                          (const_int 8)
8027                          (const_int 8))
8028         (any_or:SI
8029           (zero_extract:SI
8030             (match_operand 1 "ext_register_operand" "0")
8031             (const_int 8)
8032             (const_int 8))
8033           (match_operand 2 "const_int_operand" "n")))
8034    (clobber (reg:CC FLAGS_REG))]
8035   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8036   "<logic>{b}\t{%2, %h0|%h0, %2}"
8037   [(set_attr "type" "alu")
8038    (set_attr "length_immediate" "1")
8039    (set_attr "modrm" "1")
8040    (set_attr "mode" "QI")])
8042 (define_insn "*<code>qi_ext_1"
8043   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8044                          (const_int 8)
8045                          (const_int 8))
8046         (any_or:SI
8047           (zero_extract:SI
8048             (match_operand 1 "ext_register_operand" "0,0")
8049             (const_int 8)
8050             (const_int 8))
8051           (zero_extend:SI
8052             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8053    (clobber (reg:CC FLAGS_REG))]
8054   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8055   "<logic>{b}\t{%2, %h0|%h0, %2}"
8056   [(set_attr "isa" "*,nox64")
8057    (set_attr "type" "alu")
8058    (set_attr "length_immediate" "0")
8059    (set_attr "mode" "QI")])
8061 (define_insn "*<code>qi_ext_2"
8062   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8063                          (const_int 8)
8064                          (const_int 8))
8065         (any_or:SI
8066           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8067                            (const_int 8)
8068                            (const_int 8))
8069           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8070                            (const_int 8)
8071                            (const_int 8))))
8072    (clobber (reg:CC FLAGS_REG))]
8073   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8074   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8075   [(set_attr "type" "alu")
8076    (set_attr "length_immediate" "0")
8077    (set_attr "mode" "QI")])
8079 (define_split
8080   [(set (match_operand 0 "register_operand")
8081         (any_or (match_operand 1 "register_operand")
8082                 (match_operand 2 "const_int_operand")))
8083    (clobber (reg:CC FLAGS_REG))]
8084    "reload_completed
8085     && QI_REG_P (operands[0])
8086     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8087     && !(INTVAL (operands[2]) & ~(255 << 8))
8088     && GET_MODE (operands[0]) != QImode"
8089   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8090                    (any_or:SI (zero_extract:SI (match_dup 1)
8091                                                (const_int 8) (const_int 8))
8092                               (match_dup 2)))
8093               (clobber (reg:CC FLAGS_REG))])]
8095   operands[0] = gen_lowpart (SImode, operands[0]);
8096   operands[1] = gen_lowpart (SImode, operands[1]);
8097   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8100 ;; Since OR can be encoded with sign extended immediate, this is only
8101 ;; profitable when 7th bit is set.
8102 (define_split
8103   [(set (match_operand 0 "register_operand")
8104         (any_or (match_operand 1 "general_operand")
8105                 (match_operand 2 "const_int_operand")))
8106    (clobber (reg:CC FLAGS_REG))]
8107    "reload_completed
8108     && ANY_QI_REG_P (operands[0])
8109     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8110     && !(INTVAL (operands[2]) & ~255)
8111     && (INTVAL (operands[2]) & 128)
8112     && GET_MODE (operands[0]) != QImode"
8113   [(parallel [(set (strict_low_part (match_dup 0))
8114                    (any_or:QI (match_dup 1)
8115                               (match_dup 2)))
8116               (clobber (reg:CC FLAGS_REG))])]
8118   operands[0] = gen_lowpart (QImode, operands[0]);
8119   operands[1] = gen_lowpart (QImode, operands[1]);
8120   operands[2] = gen_lowpart (QImode, operands[2]);
8123 (define_expand "xorqi_cc_ext_1"
8124   [(parallel [
8125      (set (reg:CCNO FLAGS_REG)
8126           (compare:CCNO
8127             (xor:SI
8128               (zero_extract:SI
8129                 (match_operand 1 "ext_register_operand")
8130                 (const_int 8)
8131                 (const_int 8))
8132               (match_operand:QI 2 "const_int_operand"))
8133             (const_int 0)))
8134      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8135                            (const_int 8)
8136                            (const_int 8))
8137           (xor:SI
8138             (zero_extract:SI
8139              (match_dup 1)
8140              (const_int 8)
8141              (const_int 8))
8142             (match_dup 2)))])])
8144 (define_insn "*xorqi_cc_ext_1"
8145   [(set (reg FLAGS_REG)
8146         (compare
8147           (xor:SI
8148             (zero_extract:SI
8149               (match_operand 1 "ext_register_operand" "0,0")
8150               (const_int 8)
8151               (const_int 8))
8152             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8153           (const_int 0)))
8154    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8155                          (const_int 8)
8156                          (const_int 8))
8157         (xor:SI
8158           (zero_extract:SI
8159            (match_dup 1)
8160            (const_int 8)
8161            (const_int 8))
8162           (match_dup 2)))]
8163   "ix86_match_ccmode (insn, CCNOmode)"
8164   "xor{b}\t{%2, %h0|%h0, %2}"
8165   [(set_attr "isa" "*,nox64")
8166    (set_attr "type" "alu")
8167    (set_attr "modrm" "1")
8168    (set_attr "mode" "QI")])
8170 ;; Negation instructions
8172 (define_expand "neg<mode>2"
8173   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8174         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8175   ""
8176   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8178 (define_insn_and_split "*neg<dwi>2_doubleword"
8179   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8180         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8181    (clobber (reg:CC FLAGS_REG))]
8182   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8183   "#"
8184   "reload_completed"
8185   [(parallel
8186     [(set (reg:CCZ FLAGS_REG)
8187           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8188      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8189    (parallel
8190     [(set (match_dup 2)
8191           (plus:DWIH (match_dup 3)
8192                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8193                                 (const_int 0))))
8194      (clobber (reg:CC FLAGS_REG))])
8195    (parallel
8196     [(set (match_dup 2)
8197           (neg:DWIH (match_dup 2)))
8198      (clobber (reg:CC FLAGS_REG))])]
8199   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8201 (define_insn "*neg<mode>2_1"
8202   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8203         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8204    (clobber (reg:CC FLAGS_REG))]
8205   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8206   "neg{<imodesuffix>}\t%0"
8207   [(set_attr "type" "negnot")
8208    (set_attr "mode" "<MODE>")])
8210 ;; Combine is quite creative about this pattern.
8211 (define_insn "*negsi2_1_zext"
8212   [(set (match_operand:DI 0 "register_operand" "=r")
8213         (lshiftrt:DI
8214           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8215                              (const_int 32)))
8216         (const_int 32)))
8217    (clobber (reg:CC FLAGS_REG))]
8218   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8219   "neg{l}\t%k0"
8220   [(set_attr "type" "negnot")
8221    (set_attr "mode" "SI")])
8223 ;; The problem with neg is that it does not perform (compare x 0),
8224 ;; it really performs (compare 0 x), which leaves us with the zero
8225 ;; flag being the only useful item.
8227 (define_insn "*neg<mode>2_cmpz"
8228   [(set (reg:CCZ FLAGS_REG)
8229         (compare:CCZ
8230           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8231                    (const_int 0)))
8232    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8233         (neg:SWI (match_dup 1)))]
8234   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8235   "neg{<imodesuffix>}\t%0"
8236   [(set_attr "type" "negnot")
8237    (set_attr "mode" "<MODE>")])
8239 (define_insn "*negsi2_cmpz_zext"
8240   [(set (reg:CCZ FLAGS_REG)
8241         (compare:CCZ
8242           (lshiftrt:DI
8243             (neg:DI (ashift:DI
8244                       (match_operand:DI 1 "register_operand" "0")
8245                       (const_int 32)))
8246             (const_int 32))
8247           (const_int 0)))
8248    (set (match_operand:DI 0 "register_operand" "=r")
8249         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8250                                         (const_int 32)))
8251                      (const_int 32)))]
8252   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8253   "neg{l}\t%k0"
8254   [(set_attr "type" "negnot")
8255    (set_attr "mode" "SI")])
8257 ;; Changing of sign for FP values is doable using integer unit too.
8259 (define_expand "<code><mode>2"
8260   [(set (match_operand:X87MODEF 0 "register_operand")
8261         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8262   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8263   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8265 (define_insn "*absneg<mode>2_mixed"
8266   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8267         (match_operator:MODEF 3 "absneg_operator"
8268           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8269    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8270    (clobber (reg:CC FLAGS_REG))]
8271   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8272   "#")
8274 (define_insn "*absneg<mode>2_sse"
8275   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8276         (match_operator:MODEF 3 "absneg_operator"
8277           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8278    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8279    (clobber (reg:CC FLAGS_REG))]
8280   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8281   "#")
8283 (define_insn "*absneg<mode>2_i387"
8284   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8285         (match_operator:X87MODEF 3 "absneg_operator"
8286           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8287    (use (match_operand 2))
8288    (clobber (reg:CC FLAGS_REG))]
8289   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8290   "#")
8292 (define_expand "<code>tf2"
8293   [(set (match_operand:TF 0 "register_operand")
8294         (absneg:TF (match_operand:TF 1 "register_operand")))]
8295   "TARGET_SSE"
8296   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8298 (define_insn "*absnegtf2_sse"
8299   [(set (match_operand:TF 0 "register_operand" "=x,x")
8300         (match_operator:TF 3 "absneg_operator"
8301           [(match_operand:TF 1 "register_operand" "0,x")]))
8302    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8303    (clobber (reg:CC FLAGS_REG))]
8304   "TARGET_SSE"
8305   "#")
8307 ;; Splitters for fp abs and neg.
8309 (define_split
8310   [(set (match_operand 0 "fp_register_operand")
8311         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8312    (use (match_operand 2))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "reload_completed"
8315   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8317 (define_split
8318   [(set (match_operand 0 "register_operand")
8319         (match_operator 3 "absneg_operator"
8320           [(match_operand 1 "register_operand")]))
8321    (use (match_operand 2 "nonimmediate_operand"))
8322    (clobber (reg:CC FLAGS_REG))]
8323   "reload_completed && SSE_REG_P (operands[0])"
8324   [(set (match_dup 0) (match_dup 3))]
8326   enum machine_mode mode = GET_MODE (operands[0]);
8327   enum machine_mode vmode = GET_MODE (operands[2]);
8328   rtx tmp;
8330   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8331   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8332   if (operands_match_p (operands[0], operands[2]))
8333     {
8334       tmp = operands[1];
8335       operands[1] = operands[2];
8336       operands[2] = tmp;
8337     }
8338   if (GET_CODE (operands[3]) == ABS)
8339     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8340   else
8341     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8342   operands[3] = tmp;
8345 (define_split
8346   [(set (match_operand:SF 0 "register_operand")
8347         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8348    (use (match_operand:V4SF 2))
8349    (clobber (reg:CC FLAGS_REG))]
8350   "reload_completed"
8351   [(parallel [(set (match_dup 0) (match_dup 1))
8352               (clobber (reg:CC FLAGS_REG))])]
8354   rtx tmp;
8355   operands[0] = gen_lowpart (SImode, operands[0]);
8356   if (GET_CODE (operands[1]) == ABS)
8357     {
8358       tmp = gen_int_mode (0x7fffffff, SImode);
8359       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8360     }
8361   else
8362     {
8363       tmp = gen_int_mode (0x80000000, SImode);
8364       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8365     }
8366   operands[1] = tmp;
8369 (define_split
8370   [(set (match_operand:DF 0 "register_operand")
8371         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8372    (use (match_operand 2))
8373    (clobber (reg:CC FLAGS_REG))]
8374   "reload_completed"
8375   [(parallel [(set (match_dup 0) (match_dup 1))
8376               (clobber (reg:CC FLAGS_REG))])]
8378   rtx tmp;
8379   if (TARGET_64BIT)
8380     {
8381       tmp = gen_lowpart (DImode, operands[0]);
8382       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8383       operands[0] = tmp;
8385       if (GET_CODE (operands[1]) == ABS)
8386         tmp = const0_rtx;
8387       else
8388         tmp = gen_rtx_NOT (DImode, tmp);
8389     }
8390   else
8391     {
8392       operands[0] = gen_highpart (SImode, operands[0]);
8393       if (GET_CODE (operands[1]) == ABS)
8394         {
8395           tmp = gen_int_mode (0x7fffffff, SImode);
8396           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8397         }
8398       else
8399         {
8400           tmp = gen_int_mode (0x80000000, SImode);
8401           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8402         }
8403     }
8404   operands[1] = tmp;
8407 (define_split
8408   [(set (match_operand:XF 0 "register_operand")
8409         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8410    (use (match_operand 2))
8411    (clobber (reg:CC FLAGS_REG))]
8412   "reload_completed"
8413   [(parallel [(set (match_dup 0) (match_dup 1))
8414               (clobber (reg:CC FLAGS_REG))])]
8416   rtx tmp;
8417   operands[0] = gen_rtx_REG (SImode,
8418                              true_regnum (operands[0])
8419                              + (TARGET_64BIT ? 1 : 2));
8420   if (GET_CODE (operands[1]) == ABS)
8421     {
8422       tmp = GEN_INT (0x7fff);
8423       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8424     }
8425   else
8426     {
8427       tmp = GEN_INT (0x8000);
8428       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8429     }
8430   operands[1] = tmp;
8433 ;; Conditionalize these after reload. If they match before reload, we
8434 ;; lose the clobber and ability to use integer instructions.
8436 (define_insn "*<code><mode>2_1"
8437   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8438         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8439   "TARGET_80387
8440    && (reload_completed
8441        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8442   "f<absneg_mnemonic>"
8443   [(set_attr "type" "fsgn")
8444    (set_attr "mode" "<MODE>")])
8446 (define_insn "*<code>extendsfdf2"
8447   [(set (match_operand:DF 0 "register_operand" "=f")
8448         (absneg:DF (float_extend:DF
8449                      (match_operand:SF 1 "register_operand" "0"))))]
8450   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8451   "f<absneg_mnemonic>"
8452   [(set_attr "type" "fsgn")
8453    (set_attr "mode" "DF")])
8455 (define_insn "*<code>extendsfxf2"
8456   [(set (match_operand:XF 0 "register_operand" "=f")
8457         (absneg:XF (float_extend:XF
8458                      (match_operand:SF 1 "register_operand" "0"))))]
8459   "TARGET_80387"
8460   "f<absneg_mnemonic>"
8461   [(set_attr "type" "fsgn")
8462    (set_attr "mode" "XF")])
8464 (define_insn "*<code>extenddfxf2"
8465   [(set (match_operand:XF 0 "register_operand" "=f")
8466         (absneg:XF (float_extend:XF
8467                      (match_operand:DF 1 "register_operand" "0"))))]
8468   "TARGET_80387"
8469   "f<absneg_mnemonic>"
8470   [(set_attr "type" "fsgn")
8471    (set_attr "mode" "XF")])
8473 ;; Copysign instructions
8475 (define_mode_iterator CSGNMODE [SF DF TF])
8476 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8478 (define_expand "copysign<mode>3"
8479   [(match_operand:CSGNMODE 0 "register_operand")
8480    (match_operand:CSGNMODE 1 "nonmemory_operand")
8481    (match_operand:CSGNMODE 2 "register_operand")]
8482   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8483    || (TARGET_SSE && (<MODE>mode == TFmode))"
8484   "ix86_expand_copysign (operands); DONE;")
8486 (define_insn_and_split "copysign<mode>3_const"
8487   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8488         (unspec:CSGNMODE
8489           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8490            (match_operand:CSGNMODE 2 "register_operand" "0")
8491            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8492           UNSPEC_COPYSIGN))]
8493   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8494    || (TARGET_SSE && (<MODE>mode == TFmode))"
8495   "#"
8496   "&& reload_completed"
8497   [(const_int 0)]
8498   "ix86_split_copysign_const (operands); DONE;")
8500 (define_insn "copysign<mode>3_var"
8501   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8502         (unspec:CSGNMODE
8503           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8504            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8505            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8506            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8507           UNSPEC_COPYSIGN))
8508    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8509   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8510    || (TARGET_SSE && (<MODE>mode == TFmode))"
8511   "#")
8513 (define_split
8514   [(set (match_operand:CSGNMODE 0 "register_operand")
8515         (unspec:CSGNMODE
8516           [(match_operand:CSGNMODE 2 "register_operand")
8517            (match_operand:CSGNMODE 3 "register_operand")
8518            (match_operand:<CSGNVMODE> 4)
8519            (match_operand:<CSGNVMODE> 5)]
8520           UNSPEC_COPYSIGN))
8521    (clobber (match_scratch:<CSGNVMODE> 1))]
8522   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8523     || (TARGET_SSE && (<MODE>mode == TFmode)))
8524    && reload_completed"
8525   [(const_int 0)]
8526   "ix86_split_copysign_var (operands); DONE;")
8528 ;; One complement instructions
8530 (define_expand "one_cmpl<mode>2"
8531   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8532         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8533   ""
8534   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8536 (define_insn "*one_cmpl<mode>2_1"
8537   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8538         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8539   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8540   "not{<imodesuffix>}\t%0"
8541   [(set_attr "type" "negnot")
8542    (set_attr "mode" "<MODE>")])
8544 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8545 (define_insn "*one_cmplqi2_1"
8546   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8547         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8548   "ix86_unary_operator_ok (NOT, QImode, operands)"
8549   "@
8550    not{b}\t%0
8551    not{l}\t%k0"
8552   [(set_attr "type" "negnot")
8553    (set_attr "mode" "QI,SI")])
8555 ;; ??? Currently never generated - xor is used instead.
8556 (define_insn "*one_cmplsi2_1_zext"
8557   [(set (match_operand:DI 0 "register_operand" "=r")
8558         (zero_extend:DI
8559           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8560   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8561   "not{l}\t%k0"
8562   [(set_attr "type" "negnot")
8563    (set_attr "mode" "SI")])
8565 (define_insn "*one_cmpl<mode>2_2"
8566   [(set (reg FLAGS_REG)
8567         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8568                  (const_int 0)))
8569    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8570         (not:SWI (match_dup 1)))]
8571   "ix86_match_ccmode (insn, CCNOmode)
8572    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8573   "#"
8574   [(set_attr "type" "alu1")
8575    (set_attr "mode" "<MODE>")])
8577 (define_split
8578   [(set (match_operand 0 "flags_reg_operand")
8579         (match_operator 2 "compare_operator"
8580           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8581            (const_int 0)]))
8582    (set (match_operand:SWI 1 "nonimmediate_operand")
8583         (not:SWI (match_dup 3)))]
8584   "ix86_match_ccmode (insn, CCNOmode)"
8585   [(parallel [(set (match_dup 0)
8586                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8587                                     (const_int 0)]))
8588               (set (match_dup 1)
8589                    (xor:SWI (match_dup 3) (const_int -1)))])])
8591 ;; ??? Currently never generated - xor is used instead.
8592 (define_insn "*one_cmplsi2_2_zext"
8593   [(set (reg FLAGS_REG)
8594         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8595                  (const_int 0)))
8596    (set (match_operand:DI 0 "register_operand" "=r")
8597         (zero_extend:DI (not:SI (match_dup 1))))]
8598   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8599    && ix86_unary_operator_ok (NOT, SImode, operands)"
8600   "#"
8601   [(set_attr "type" "alu1")
8602    (set_attr "mode" "SI")])
8604 (define_split
8605   [(set (match_operand 0 "flags_reg_operand")
8606         (match_operator 2 "compare_operator"
8607           [(not:SI (match_operand:SI 3 "register_operand"))
8608            (const_int 0)]))
8609    (set (match_operand:DI 1 "register_operand")
8610         (zero_extend:DI (not:SI (match_dup 3))))]
8611   "ix86_match_ccmode (insn, CCNOmode)"
8612   [(parallel [(set (match_dup 0)
8613                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8614                                     (const_int 0)]))
8615               (set (match_dup 1)
8616                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8618 ;; Shift instructions
8620 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8621 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8622 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8623 ;; from the assembler input.
8625 ;; This instruction shifts the target reg/mem as usual, but instead of
8626 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8627 ;; is a left shift double, bits are taken from the high order bits of
8628 ;; reg, else if the insn is a shift right double, bits are taken from the
8629 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8630 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8632 ;; Since sh[lr]d does not change the `reg' operand, that is done
8633 ;; separately, making all shifts emit pairs of shift double and normal
8634 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8635 ;; support a 63 bit shift, each shift where the count is in a reg expands
8636 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8638 ;; If the shift count is a constant, we need never emit more than one
8639 ;; shift pair, instead using moves and sign extension for counts greater
8640 ;; than 31.
8642 (define_expand "ashl<mode>3"
8643   [(set (match_operand:SDWIM 0 "<shift_operand>")
8644         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8645                       (match_operand:QI 2 "nonmemory_operand")))]
8646   ""
8647   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8649 (define_insn "*ashl<mode>3_doubleword"
8650   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8651         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8652                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8653    (clobber (reg:CC FLAGS_REG))]
8654   ""
8655   "#"
8656   [(set_attr "type" "multi")])
8658 (define_split
8659   [(set (match_operand:DWI 0 "register_operand")
8660         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8661                     (match_operand:QI 2 "nonmemory_operand")))
8662    (clobber (reg:CC FLAGS_REG))]
8663   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8664   [(const_int 0)]
8665   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8667 ;; By default we don't ask for a scratch register, because when DWImode
8668 ;; values are manipulated, registers are already at a premium.  But if
8669 ;; we have one handy, we won't turn it away.
8671 (define_peephole2
8672   [(match_scratch:DWIH 3 "r")
8673    (parallel [(set (match_operand:<DWI> 0 "register_operand")
8674                    (ashift:<DWI>
8675                      (match_operand:<DWI> 1 "nonmemory_operand")
8676                      (match_operand:QI 2 "nonmemory_operand")))
8677               (clobber (reg:CC FLAGS_REG))])
8678    (match_dup 3)]
8679   "TARGET_CMOVE"
8680   [(const_int 0)]
8681   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8683 (define_insn "x86_64_shld"
8684   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8685         (ior:DI (ashift:DI (match_dup 0)
8686                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8687                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8688                   (minus:QI (const_int 64) (match_dup 2)))))
8689    (clobber (reg:CC FLAGS_REG))]
8690   "TARGET_64BIT"
8691   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8692   [(set_attr "type" "ishift")
8693    (set_attr "prefix_0f" "1")
8694    (set_attr "mode" "DI")
8695    (set_attr "athlon_decode" "vector")
8696    (set_attr "amdfam10_decode" "vector")
8697    (set_attr "bdver1_decode" "vector")])
8699 (define_insn "x86_shld"
8700   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8701         (ior:SI (ashift:SI (match_dup 0)
8702                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8703                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8704                   (minus:QI (const_int 32) (match_dup 2)))))
8705    (clobber (reg:CC FLAGS_REG))]
8706   ""
8707   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8708   [(set_attr "type" "ishift")
8709    (set_attr "prefix_0f" "1")
8710    (set_attr "mode" "SI")
8711    (set_attr "pent_pair" "np")
8712    (set_attr "athlon_decode" "vector")
8713    (set_attr "amdfam10_decode" "vector")
8714    (set_attr "bdver1_decode" "vector")])
8716 (define_expand "x86_shift<mode>_adj_1"
8717   [(set (reg:CCZ FLAGS_REG)
8718         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
8719                              (match_dup 4))
8720                      (const_int 0)))
8721    (set (match_operand:SWI48 0 "register_operand")
8722         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8723                             (match_operand:SWI48 1 "register_operand")
8724                             (match_dup 0)))
8725    (set (match_dup 1)
8726         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8727                             (match_operand:SWI48 3 "register_operand")
8728                             (match_dup 1)))]
8729   "TARGET_CMOVE"
8730   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8732 (define_expand "x86_shift<mode>_adj_2"
8733   [(use (match_operand:SWI48 0 "register_operand"))
8734    (use (match_operand:SWI48 1 "register_operand"))
8735    (use (match_operand:QI 2 "register_operand"))]
8736   ""
8738   rtx label = gen_label_rtx ();
8739   rtx tmp;
8741   emit_insn (gen_testqi_ccz_1 (operands[2],
8742                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8744   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8745   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8746   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8747                               gen_rtx_LABEL_REF (VOIDmode, label),
8748                               pc_rtx);
8749   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8750   JUMP_LABEL (tmp) = label;
8752   emit_move_insn (operands[0], operands[1]);
8753   ix86_expand_clear (operands[1]);
8755   emit_label (label);
8756   LABEL_NUSES (label) = 1;
8758   DONE;
8761 ;; Avoid useless masking of count operand.
8762 (define_insn "*ashl<mode>3_mask"
8763   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8764         (ashift:SWI48
8765           (match_operand:SWI48 1 "nonimmediate_operand" "0")
8766           (subreg:QI
8767             (and:SI
8768               (match_operand:SI 2 "register_operand" "c")
8769               (match_operand:SI 3 "const_int_operand" "n")) 0)))
8770    (clobber (reg:CC FLAGS_REG))]
8771   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8772    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8773       == GET_MODE_BITSIZE (<MODE>mode)-1"
8775   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
8777   [(set_attr "type" "ishift")
8778    (set_attr "mode" "<MODE>")])
8780 (define_insn "*bmi2_ashl<mode>3_1"
8781   [(set (match_operand:SWI48 0 "register_operand" "=r")
8782         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
8783                       (match_operand:SWI48 2 "register_operand" "r")))]
8784   "TARGET_BMI2"
8785   "shlx\t{%2, %1, %0|%0, %1, %2}"
8786   [(set_attr "type" "ishiftx")
8787    (set_attr "mode" "<MODE>")])
8789 (define_insn "*ashl<mode>3_1"
8790   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
8791         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
8792                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
8793    (clobber (reg:CC FLAGS_REG))]
8794   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8796   switch (get_attr_type (insn))
8797     {
8798     case TYPE_LEA:
8799     case TYPE_ISHIFTX:
8800       return "#";
8802     case TYPE_ALU:
8803       gcc_assert (operands[2] == const1_rtx);
8804       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8805       return "add{<imodesuffix>}\t%0, %0";
8807     default:
8808       if (operands[2] == const1_rtx
8809           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8810         return "sal{<imodesuffix>}\t%0";
8811       else
8812         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
8813     }
8815   [(set_attr "isa" "*,*,bmi2")
8816    (set (attr "type")
8817      (cond [(eq_attr "alternative" "1")
8818               (const_string "lea")
8819             (eq_attr "alternative" "2")
8820               (const_string "ishiftx")
8821             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8822                       (match_operand 0 "register_operand"))
8823                  (match_operand 2 "const1_operand"))
8824               (const_string "alu")
8825            ]
8826            (const_string "ishift")))
8827    (set (attr "length_immediate")
8828      (if_then_else
8829        (ior (eq_attr "type" "alu")
8830             (and (eq_attr "type" "ishift")
8831                  (and (match_operand 2 "const1_operand")
8832                       (ior (match_test "TARGET_SHIFT1")
8833                            (match_test "optimize_function_for_size_p (cfun)")))))
8834        (const_string "0")
8835        (const_string "*")))
8836    (set_attr "mode" "<MODE>")])
8838 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8839 (define_split
8840   [(set (match_operand:SWI48 0 "register_operand")
8841         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
8842                       (match_operand:QI 2 "register_operand")))
8843    (clobber (reg:CC FLAGS_REG))]
8844   "TARGET_BMI2 && reload_completed"
8845   [(set (match_dup 0)
8846         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
8847   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
8849 (define_insn "*bmi2_ashlsi3_1_zext"
8850   [(set (match_operand:DI 0 "register_operand" "=r")
8851         (zero_extend:DI
8852           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
8853                      (match_operand:SI 2 "register_operand" "r"))))]
8854   "TARGET_64BIT && TARGET_BMI2"
8855   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
8856   [(set_attr "type" "ishiftx")
8857    (set_attr "mode" "SI")])
8859 (define_insn "*ashlsi3_1_zext"
8860   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8861         (zero_extend:DI
8862           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
8863                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
8864    (clobber (reg:CC FLAGS_REG))]
8865   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
8867   switch (get_attr_type (insn))
8868     {
8869     case TYPE_LEA:
8870     case TYPE_ISHIFTX:
8871       return "#";
8873     case TYPE_ALU:
8874       gcc_assert (operands[2] == const1_rtx);
8875       return "add{l}\t%k0, %k0";
8877     default:
8878       if (operands[2] == const1_rtx
8879           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8880         return "sal{l}\t%k0";
8881       else
8882         return "sal{l}\t{%2, %k0|%k0, %2}";
8883     }
8885   [(set_attr "isa" "*,*,bmi2")
8886    (set (attr "type")
8887      (cond [(eq_attr "alternative" "1")
8888               (const_string "lea")
8889             (eq_attr "alternative" "2")
8890               (const_string "ishiftx")
8891             (and (match_test "TARGET_DOUBLE_WITH_ADD")
8892                  (match_operand 2 "const1_operand"))
8893               (const_string "alu")
8894            ]
8895            (const_string "ishift")))
8896    (set (attr "length_immediate")
8897      (if_then_else
8898        (ior (eq_attr "type" "alu")
8899             (and (eq_attr "type" "ishift")
8900                  (and (match_operand 2 "const1_operand")
8901                       (ior (match_test "TARGET_SHIFT1")
8902                            (match_test "optimize_function_for_size_p (cfun)")))))
8903        (const_string "0")
8904        (const_string "*")))
8905    (set_attr "mode" "SI")])
8907 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8908 (define_split
8909   [(set (match_operand:DI 0 "register_operand")
8910         (zero_extend:DI
8911           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
8912                      (match_operand:QI 2 "register_operand"))))
8913    (clobber (reg:CC FLAGS_REG))]
8914   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
8915   [(set (match_dup 0)
8916         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
8917   "operands[2] = gen_lowpart (SImode, operands[2]);")
8919 (define_insn "*ashlhi3_1"
8920   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
8921         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
8922                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8923    (clobber (reg:CC FLAGS_REG))]
8924   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8926   switch (get_attr_type (insn))
8927     {
8928     case TYPE_LEA:
8929       return "#";
8931     case TYPE_ALU:
8932       gcc_assert (operands[2] == const1_rtx);
8933       return "add{w}\t%0, %0";
8935     default:
8936       if (operands[2] == const1_rtx
8937           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8938         return "sal{w}\t%0";
8939       else
8940         return "sal{w}\t{%2, %0|%0, %2}";
8941     }
8943   [(set (attr "type")
8944      (cond [(eq_attr "alternative" "1")
8945               (const_string "lea")
8946             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8947                       (match_operand 0 "register_operand"))
8948                  (match_operand 2 "const1_operand"))
8949               (const_string "alu")
8950            ]
8951            (const_string "ishift")))
8952    (set (attr "length_immediate")
8953      (if_then_else
8954        (ior (eq_attr "type" "alu")
8955             (and (eq_attr "type" "ishift")
8956                  (and (match_operand 2 "const1_operand")
8957                       (ior (match_test "TARGET_SHIFT1")
8958                            (match_test "optimize_function_for_size_p (cfun)")))))
8959        (const_string "0")
8960        (const_string "*")))
8961    (set_attr "mode" "HI,SI")])
8963 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8964 (define_insn "*ashlqi3_1"
8965   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
8966         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
8967                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8968    (clobber (reg:CC FLAGS_REG))]
8969   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8971   switch (get_attr_type (insn))
8972     {
8973     case TYPE_LEA:
8974       return "#";
8976     case TYPE_ALU:
8977       gcc_assert (operands[2] == const1_rtx);
8978       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
8979         return "add{l}\t%k0, %k0";
8980       else
8981         return "add{b}\t%0, %0";
8983     default:
8984       if (operands[2] == const1_rtx
8985           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8986         {
8987           if (get_attr_mode (insn) == MODE_SI)
8988             return "sal{l}\t%k0";
8989           else
8990             return "sal{b}\t%0";
8991         }
8992       else
8993         {
8994           if (get_attr_mode (insn) == MODE_SI)
8995             return "sal{l}\t{%2, %k0|%k0, %2}";
8996           else
8997             return "sal{b}\t{%2, %0|%0, %2}";
8998         }
8999     }
9001   [(set (attr "type")
9002      (cond [(eq_attr "alternative" "2")
9003               (const_string "lea")
9004             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9005                       (match_operand 0 "register_operand"))
9006                  (match_operand 2 "const1_operand"))
9007               (const_string "alu")
9008            ]
9009            (const_string "ishift")))
9010    (set (attr "length_immediate")
9011      (if_then_else
9012        (ior (eq_attr "type" "alu")
9013             (and (eq_attr "type" "ishift")
9014                  (and (match_operand 2 "const1_operand")
9015                       (ior (match_test "TARGET_SHIFT1")
9016                            (match_test "optimize_function_for_size_p (cfun)")))))
9017        (const_string "0")
9018        (const_string "*")))
9019    (set_attr "mode" "QI,SI,SI")])
9021 (define_insn "*ashlqi3_1_slp"
9022   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9023         (ashift:QI (match_dup 0)
9024                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9025    (clobber (reg:CC FLAGS_REG))]
9026   "(optimize_function_for_size_p (cfun)
9027     || !TARGET_PARTIAL_FLAG_REG_STALL
9028     || (operands[1] == const1_rtx
9029         && (TARGET_SHIFT1
9030             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9032   switch (get_attr_type (insn))
9033     {
9034     case TYPE_ALU:
9035       gcc_assert (operands[1] == const1_rtx);
9036       return "add{b}\t%0, %0";
9038     default:
9039       if (operands[1] == const1_rtx
9040           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9041         return "sal{b}\t%0";
9042       else
9043         return "sal{b}\t{%1, %0|%0, %1}";
9044     }
9046   [(set (attr "type")
9047      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9048                       (match_operand 0 "register_operand"))
9049                  (match_operand 1 "const1_operand"))
9050               (const_string "alu")
9051            ]
9052            (const_string "ishift1")))
9053    (set (attr "length_immediate")
9054      (if_then_else
9055        (ior (eq_attr "type" "alu")
9056             (and (eq_attr "type" "ishift1")
9057                  (and (match_operand 1 "const1_operand")
9058                       (ior (match_test "TARGET_SHIFT1")
9059                            (match_test "optimize_function_for_size_p (cfun)")))))
9060        (const_string "0")
9061        (const_string "*")))
9062    (set_attr "mode" "QI")])
9064 ;; Convert ashift to the lea pattern to avoid flags dependency.
9065 (define_split
9066   [(set (match_operand 0 "register_operand")
9067         (ashift (match_operand 1 "index_register_operand")
9068                 (match_operand:QI 2 "const_int_operand")))
9069    (clobber (reg:CC FLAGS_REG))]
9070   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9071    && reload_completed
9072    && true_regnum (operands[0]) != true_regnum (operands[1])"
9073   [(const_int 0)]
9075   enum machine_mode mode = GET_MODE (operands[0]);
9076   rtx pat;
9078   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9079     { 
9080       mode = SImode; 
9081       operands[0] = gen_lowpart (mode, operands[0]);
9082       operands[1] = gen_lowpart (mode, operands[1]);
9083     }
9085   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9087   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9089   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9090   DONE;
9093 ;; Convert ashift to the lea pattern to avoid flags dependency.
9094 (define_split
9095   [(set (match_operand:DI 0 "register_operand")
9096         (zero_extend:DI
9097           (ashift:SI (match_operand:SI 1 "index_register_operand")
9098                      (match_operand:QI 2 "const_int_operand"))))
9099    (clobber (reg:CC FLAGS_REG))]
9100   "TARGET_64BIT && reload_completed
9101    && true_regnum (operands[0]) != true_regnum (operands[1])"
9102   [(set (match_dup 0)
9103         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9105   operands[1] = gen_lowpart (SImode, operands[1]);
9106   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9109 ;; This pattern can't accept a variable shift count, since shifts by
9110 ;; zero don't affect the flags.  We assume that shifts by constant
9111 ;; zero are optimized away.
9112 (define_insn "*ashl<mode>3_cmp"
9113   [(set (reg FLAGS_REG)
9114         (compare
9115           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9116                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9117           (const_int 0)))
9118    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9119         (ashift:SWI (match_dup 1) (match_dup 2)))]
9120   "(optimize_function_for_size_p (cfun)
9121     || !TARGET_PARTIAL_FLAG_REG_STALL
9122     || (operands[2] == const1_rtx
9123         && (TARGET_SHIFT1
9124             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9125    && ix86_match_ccmode (insn, CCGOCmode)
9126    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9128   switch (get_attr_type (insn))
9129     {
9130     case TYPE_ALU:
9131       gcc_assert (operands[2] == const1_rtx);
9132       return "add{<imodesuffix>}\t%0, %0";
9134     default:
9135       if (operands[2] == const1_rtx
9136           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9137         return "sal{<imodesuffix>}\t%0";
9138       else
9139         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9140     }
9142   [(set (attr "type")
9143      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9144                       (match_operand 0 "register_operand"))
9145                  (match_operand 2 "const1_operand"))
9146               (const_string "alu")
9147            ]
9148            (const_string "ishift")))
9149    (set (attr "length_immediate")
9150      (if_then_else
9151        (ior (eq_attr "type" "alu")
9152             (and (eq_attr "type" "ishift")
9153                  (and (match_operand 2 "const1_operand")
9154                       (ior (match_test "TARGET_SHIFT1")
9155                            (match_test "optimize_function_for_size_p (cfun)")))))
9156        (const_string "0")
9157        (const_string "*")))
9158    (set_attr "mode" "<MODE>")])
9160 (define_insn "*ashlsi3_cmp_zext"
9161   [(set (reg FLAGS_REG)
9162         (compare
9163           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9164                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9165           (const_int 0)))
9166    (set (match_operand:DI 0 "register_operand" "=r")
9167         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9168   "TARGET_64BIT
9169    && (optimize_function_for_size_p (cfun)
9170        || !TARGET_PARTIAL_FLAG_REG_STALL
9171        || (operands[2] == const1_rtx
9172            && (TARGET_SHIFT1
9173                || TARGET_DOUBLE_WITH_ADD)))
9174    && ix86_match_ccmode (insn, CCGOCmode)
9175    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9177   switch (get_attr_type (insn))
9178     {
9179     case TYPE_ALU:
9180       gcc_assert (operands[2] == const1_rtx);
9181       return "add{l}\t%k0, %k0";
9183     default:
9184       if (operands[2] == const1_rtx
9185           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9186         return "sal{l}\t%k0";
9187       else
9188         return "sal{l}\t{%2, %k0|%k0, %2}";
9189     }
9191   [(set (attr "type")
9192      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9193                  (match_operand 2 "const1_operand"))
9194               (const_string "alu")
9195            ]
9196            (const_string "ishift")))
9197    (set (attr "length_immediate")
9198      (if_then_else
9199        (ior (eq_attr "type" "alu")
9200             (and (eq_attr "type" "ishift")
9201                  (and (match_operand 2 "const1_operand")
9202                       (ior (match_test "TARGET_SHIFT1")
9203                            (match_test "optimize_function_for_size_p (cfun)")))))
9204        (const_string "0")
9205        (const_string "*")))
9206    (set_attr "mode" "SI")])
9208 (define_insn "*ashl<mode>3_cconly"
9209   [(set (reg FLAGS_REG)
9210         (compare
9211           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9212                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9213           (const_int 0)))
9214    (clobber (match_scratch:SWI 0 "=<r>"))]
9215   "(optimize_function_for_size_p (cfun)
9216     || !TARGET_PARTIAL_FLAG_REG_STALL
9217     || (operands[2] == const1_rtx
9218         && (TARGET_SHIFT1
9219             || TARGET_DOUBLE_WITH_ADD)))
9220    && ix86_match_ccmode (insn, CCGOCmode)"
9222   switch (get_attr_type (insn))
9223     {
9224     case TYPE_ALU:
9225       gcc_assert (operands[2] == const1_rtx);
9226       return "add{<imodesuffix>}\t%0, %0";
9228     default:
9229       if (operands[2] == const1_rtx
9230           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9231         return "sal{<imodesuffix>}\t%0";
9232       else
9233         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9234     }
9236   [(set (attr "type")
9237      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9238                       (match_operand 0 "register_operand"))
9239                  (match_operand 2 "const1_operand"))
9240               (const_string "alu")
9241            ]
9242            (const_string "ishift")))
9243    (set (attr "length_immediate")
9244      (if_then_else
9245        (ior (eq_attr "type" "alu")
9246             (and (eq_attr "type" "ishift")
9247                  (and (match_operand 2 "const1_operand")
9248                       (ior (match_test "TARGET_SHIFT1")
9249                            (match_test "optimize_function_for_size_p (cfun)")))))
9250        (const_string "0")
9251        (const_string "*")))
9252    (set_attr "mode" "<MODE>")])
9254 ;; See comment above `ashl<mode>3' about how this works.
9256 (define_expand "<shift_insn><mode>3"
9257   [(set (match_operand:SDWIM 0 "<shift_operand>")
9258         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9259                            (match_operand:QI 2 "nonmemory_operand")))]
9260   ""
9261   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9263 ;; Avoid useless masking of count operand.
9264 (define_insn "*<shift_insn><mode>3_mask"
9265   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9266         (any_shiftrt:SWI48
9267           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9268           (subreg:QI
9269             (and:SI
9270               (match_operand:SI 2 "register_operand" "c")
9271               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9272    (clobber (reg:CC FLAGS_REG))]
9273   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9274    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9275       == GET_MODE_BITSIZE (<MODE>mode)-1"
9277   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9279   [(set_attr "type" "ishift")
9280    (set_attr "mode" "<MODE>")])
9282 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9283   [(set (match_operand:DWI 0 "register_operand" "=r")
9284         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9285                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9286    (clobber (reg:CC FLAGS_REG))]
9287   ""
9288   "#"
9289   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9290   [(const_int 0)]
9291   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9292   [(set_attr "type" "multi")])
9294 ;; By default we don't ask for a scratch register, because when DWImode
9295 ;; values are manipulated, registers are already at a premium.  But if
9296 ;; we have one handy, we won't turn it away.
9298 (define_peephole2
9299   [(match_scratch:DWIH 3 "r")
9300    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9301                    (any_shiftrt:<DWI>
9302                      (match_operand:<DWI> 1 "register_operand")
9303                      (match_operand:QI 2 "nonmemory_operand")))
9304               (clobber (reg:CC FLAGS_REG))])
9305    (match_dup 3)]
9306   "TARGET_CMOVE"
9307   [(const_int 0)]
9308   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9310 (define_insn "x86_64_shrd"
9311   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9312         (ior:DI (ashiftrt:DI (match_dup 0)
9313                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9314                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9315                   (minus:QI (const_int 64) (match_dup 2)))))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "TARGET_64BIT"
9318   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9319   [(set_attr "type" "ishift")
9320    (set_attr "prefix_0f" "1")
9321    (set_attr "mode" "DI")
9322    (set_attr "athlon_decode" "vector")
9323    (set_attr "amdfam10_decode" "vector")
9324    (set_attr "bdver1_decode" "vector")])
9326 (define_insn "x86_shrd"
9327   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9328         (ior:SI (ashiftrt:SI (match_dup 0)
9329                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9330                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9331                   (minus:QI (const_int 32) (match_dup 2)))))
9332    (clobber (reg:CC FLAGS_REG))]
9333   ""
9334   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9335   [(set_attr "type" "ishift")
9336    (set_attr "prefix_0f" "1")
9337    (set_attr "mode" "SI")
9338    (set_attr "pent_pair" "np")
9339    (set_attr "athlon_decode" "vector")
9340    (set_attr "amdfam10_decode" "vector")
9341    (set_attr "bdver1_decode" "vector")])
9343 (define_insn "ashrdi3_cvt"
9344   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9345         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9346                      (match_operand:QI 2 "const_int_operand")))
9347    (clobber (reg:CC FLAGS_REG))]
9348   "TARGET_64BIT && INTVAL (operands[2]) == 63
9349    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9350    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9351   "@
9352    {cqto|cqo}
9353    sar{q}\t{%2, %0|%0, %2}"
9354   [(set_attr "type" "imovx,ishift")
9355    (set_attr "prefix_0f" "0,*")
9356    (set_attr "length_immediate" "0,*")
9357    (set_attr "modrm" "0,1")
9358    (set_attr "mode" "DI")])
9360 (define_insn "ashrsi3_cvt"
9361   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9362         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9363                      (match_operand:QI 2 "const_int_operand")))
9364    (clobber (reg:CC FLAGS_REG))]
9365   "INTVAL (operands[2]) == 31
9366    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9367    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9368   "@
9369    {cltd|cdq}
9370    sar{l}\t{%2, %0|%0, %2}"
9371   [(set_attr "type" "imovx,ishift")
9372    (set_attr "prefix_0f" "0,*")
9373    (set_attr "length_immediate" "0,*")
9374    (set_attr "modrm" "0,1")
9375    (set_attr "mode" "SI")])
9377 (define_insn "*ashrsi3_cvt_zext"
9378   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9379         (zero_extend:DI
9380           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9381                        (match_operand:QI 2 "const_int_operand"))))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "TARGET_64BIT && INTVAL (operands[2]) == 31
9384    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9385    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9386   "@
9387    {cltd|cdq}
9388    sar{l}\t{%2, %k0|%k0, %2}"
9389   [(set_attr "type" "imovx,ishift")
9390    (set_attr "prefix_0f" "0,*")
9391    (set_attr "length_immediate" "0,*")
9392    (set_attr "modrm" "0,1")
9393    (set_attr "mode" "SI")])
9395 (define_expand "x86_shift<mode>_adj_3"
9396   [(use (match_operand:SWI48 0 "register_operand"))
9397    (use (match_operand:SWI48 1 "register_operand"))
9398    (use (match_operand:QI 2 "register_operand"))]
9399   ""
9401   rtx label = gen_label_rtx ();
9402   rtx tmp;
9404   emit_insn (gen_testqi_ccz_1 (operands[2],
9405                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9407   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9408   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9409   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9410                               gen_rtx_LABEL_REF (VOIDmode, label),
9411                               pc_rtx);
9412   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9413   JUMP_LABEL (tmp) = label;
9415   emit_move_insn (operands[0], operands[1]);
9416   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9417                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9418   emit_label (label);
9419   LABEL_NUSES (label) = 1;
9421   DONE;
9424 (define_insn "*bmi2_<shift_insn><mode>3_1"
9425   [(set (match_operand:SWI48 0 "register_operand" "=r")
9426         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9427                            (match_operand:SWI48 2 "register_operand" "r")))]
9428   "TARGET_BMI2"
9429   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9430   [(set_attr "type" "ishiftx")
9431    (set_attr "mode" "<MODE>")])
9433 (define_insn "*<shift_insn><mode>3_1"
9434   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9435         (any_shiftrt:SWI48
9436           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9437           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9438    (clobber (reg:CC FLAGS_REG))]
9439   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9441   switch (get_attr_type (insn))
9442     {
9443     case TYPE_ISHIFTX:
9444       return "#";
9446     default:
9447       if (operands[2] == const1_rtx
9448           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9449         return "<shift>{<imodesuffix>}\t%0";
9450       else
9451         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9452     }
9454   [(set_attr "isa" "*,bmi2")
9455    (set_attr "type" "ishift,ishiftx")
9456    (set (attr "length_immediate")
9457      (if_then_else
9458        (and (match_operand 2 "const1_operand")
9459             (ior (match_test "TARGET_SHIFT1")
9460                  (match_test "optimize_function_for_size_p (cfun)")))
9461        (const_string "0")
9462        (const_string "*")))
9463    (set_attr "mode" "<MODE>")])
9465 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9466 (define_split
9467   [(set (match_operand:SWI48 0 "register_operand")
9468         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9469                            (match_operand:QI 2 "register_operand")))
9470    (clobber (reg:CC FLAGS_REG))]
9471   "TARGET_BMI2 && reload_completed"
9472   [(set (match_dup 0)
9473         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9474   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9476 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9477   [(set (match_operand:DI 0 "register_operand" "=r")
9478         (zero_extend:DI
9479           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9480                           (match_operand:SI 2 "register_operand" "r"))))]
9481   "TARGET_64BIT && TARGET_BMI2"
9482   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9483   [(set_attr "type" "ishiftx")
9484    (set_attr "mode" "SI")])
9486 (define_insn "*<shift_insn>si3_1_zext"
9487   [(set (match_operand:DI 0 "register_operand" "=r,r")
9488         (zero_extend:DI
9489           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9490                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9491    (clobber (reg:CC FLAGS_REG))]
9492   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9494   switch (get_attr_type (insn))
9495     {
9496     case TYPE_ISHIFTX:
9497       return "#";
9499     default:
9500       if (operands[2] == const1_rtx
9501           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9502         return "<shift>{l}\t%k0";
9503       else
9504         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9505     }
9507   [(set_attr "isa" "*,bmi2")
9508    (set_attr "type" "ishift,ishiftx")
9509    (set (attr "length_immediate")
9510      (if_then_else
9511        (and (match_operand 2 "const1_operand")
9512             (ior (match_test "TARGET_SHIFT1")
9513                  (match_test "optimize_function_for_size_p (cfun)")))
9514        (const_string "0")
9515        (const_string "*")))
9516    (set_attr "mode" "SI")])
9518 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9519 (define_split
9520   [(set (match_operand:DI 0 "register_operand")
9521         (zero_extend:DI
9522           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9523                           (match_operand:QI 2 "register_operand"))))
9524    (clobber (reg:CC FLAGS_REG))]
9525   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9526   [(set (match_dup 0)
9527         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9528   "operands[2] = gen_lowpart (SImode, operands[2]);")
9530 (define_insn "*<shift_insn><mode>3_1"
9531   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9532         (any_shiftrt:SWI12
9533           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9534           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9535    (clobber (reg:CC FLAGS_REG))]
9536   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9538   if (operands[2] == const1_rtx
9539       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9540     return "<shift>{<imodesuffix>}\t%0";
9541   else
9542     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9544   [(set_attr "type" "ishift")
9545    (set (attr "length_immediate")
9546      (if_then_else
9547        (and (match_operand 2 "const1_operand")
9548             (ior (match_test "TARGET_SHIFT1")
9549                  (match_test "optimize_function_for_size_p (cfun)")))
9550        (const_string "0")
9551        (const_string "*")))
9552    (set_attr "mode" "<MODE>")])
9554 (define_insn "*<shift_insn>qi3_1_slp"
9555   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9556         (any_shiftrt:QI (match_dup 0)
9557                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9558    (clobber (reg:CC FLAGS_REG))]
9559   "(optimize_function_for_size_p (cfun)
9560     || !TARGET_PARTIAL_REG_STALL
9561     || (operands[1] == const1_rtx
9562         && TARGET_SHIFT1))"
9564   if (operands[1] == const1_rtx
9565       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9566     return "<shift>{b}\t%0";
9567   else
9568     return "<shift>{b}\t{%1, %0|%0, %1}";
9570   [(set_attr "type" "ishift1")
9571    (set (attr "length_immediate")
9572      (if_then_else
9573        (and (match_operand 1 "const1_operand")
9574             (ior (match_test "TARGET_SHIFT1")
9575                  (match_test "optimize_function_for_size_p (cfun)")))
9576        (const_string "0")
9577        (const_string "*")))
9578    (set_attr "mode" "QI")])
9580 ;; This pattern can't accept a variable shift count, since shifts by
9581 ;; zero don't affect the flags.  We assume that shifts by constant
9582 ;; zero are optimized away.
9583 (define_insn "*<shift_insn><mode>3_cmp"
9584   [(set (reg FLAGS_REG)
9585         (compare
9586           (any_shiftrt:SWI
9587             (match_operand:SWI 1 "nonimmediate_operand" "0")
9588             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9589           (const_int 0)))
9590    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9591         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9592   "(optimize_function_for_size_p (cfun)
9593     || !TARGET_PARTIAL_FLAG_REG_STALL
9594     || (operands[2] == const1_rtx
9595         && TARGET_SHIFT1))
9596    && ix86_match_ccmode (insn, CCGOCmode)
9597    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9599   if (operands[2] == const1_rtx
9600       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9601     return "<shift>{<imodesuffix>}\t%0";
9602   else
9603     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9605   [(set_attr "type" "ishift")
9606    (set (attr "length_immediate")
9607      (if_then_else
9608        (and (match_operand 2 "const1_operand")
9609             (ior (match_test "TARGET_SHIFT1")
9610                  (match_test "optimize_function_for_size_p (cfun)")))
9611        (const_string "0")
9612        (const_string "*")))
9613    (set_attr "mode" "<MODE>")])
9615 (define_insn "*<shift_insn>si3_cmp_zext"
9616   [(set (reg FLAGS_REG)
9617         (compare
9618           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9619                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9620           (const_int 0)))
9621    (set (match_operand:DI 0 "register_operand" "=r")
9622         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9623   "TARGET_64BIT
9624    && (optimize_function_for_size_p (cfun)
9625        || !TARGET_PARTIAL_FLAG_REG_STALL
9626        || (operands[2] == const1_rtx
9627            && TARGET_SHIFT1))
9628    && ix86_match_ccmode (insn, CCGOCmode)
9629    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9631   if (operands[2] == const1_rtx
9632       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9633     return "<shift>{l}\t%k0";
9634   else
9635     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9637   [(set_attr "type" "ishift")
9638    (set (attr "length_immediate")
9639      (if_then_else
9640        (and (match_operand 2 "const1_operand")
9641             (ior (match_test "TARGET_SHIFT1")
9642                  (match_test "optimize_function_for_size_p (cfun)")))
9643        (const_string "0")
9644        (const_string "*")))
9645    (set_attr "mode" "SI")])
9647 (define_insn "*<shift_insn><mode>3_cconly"
9648   [(set (reg FLAGS_REG)
9649         (compare
9650           (any_shiftrt:SWI
9651             (match_operand:SWI 1 "register_operand" "0")
9652             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9653           (const_int 0)))
9654    (clobber (match_scratch:SWI 0 "=<r>"))]
9655   "(optimize_function_for_size_p (cfun)
9656     || !TARGET_PARTIAL_FLAG_REG_STALL
9657     || (operands[2] == const1_rtx
9658         && TARGET_SHIFT1))
9659    && ix86_match_ccmode (insn, CCGOCmode)"
9661   if (operands[2] == const1_rtx
9662       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9663     return "<shift>{<imodesuffix>}\t%0";
9664   else
9665     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9667   [(set_attr "type" "ishift")
9668    (set (attr "length_immediate")
9669      (if_then_else
9670        (and (match_operand 2 "const1_operand")
9671             (ior (match_test "TARGET_SHIFT1")
9672                  (match_test "optimize_function_for_size_p (cfun)")))
9673        (const_string "0")
9674        (const_string "*")))
9675    (set_attr "mode" "<MODE>")])
9677 ;; Rotate instructions
9679 (define_expand "<rotate_insn>ti3"
9680   [(set (match_operand:TI 0 "register_operand")
9681         (any_rotate:TI (match_operand:TI 1 "register_operand")
9682                        (match_operand:QI 2 "nonmemory_operand")))]
9683   "TARGET_64BIT"
9685   if (const_1_to_63_operand (operands[2], VOIDmode))
9686     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9687                 (operands[0], operands[1], operands[2]));
9688   else
9689     FAIL;
9691   DONE;
9694 (define_expand "<rotate_insn>di3"
9695   [(set (match_operand:DI 0 "shiftdi_operand")
9696         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
9697                        (match_operand:QI 2 "nonmemory_operand")))]
9698  ""
9700   if (TARGET_64BIT)
9701     ix86_expand_binary_operator (<CODE>, DImode, operands);
9702   else if (const_1_to_31_operand (operands[2], VOIDmode))
9703     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9704                 (operands[0], operands[1], operands[2]));
9705   else
9706     FAIL;
9708   DONE;
9711 (define_expand "<rotate_insn><mode>3"
9712   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
9713         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
9714                             (match_operand:QI 2 "nonmemory_operand")))]
9715   ""
9716   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9718 ;; Avoid useless masking of count operand.
9719 (define_insn "*<rotate_insn><mode>3_mask"
9720   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9721         (any_rotate:SWI48
9722           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9723           (subreg:QI
9724             (and:SI
9725               (match_operand:SI 2 "register_operand" "c")
9726               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9727    (clobber (reg:CC FLAGS_REG))]
9728   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9729    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9730       == GET_MODE_BITSIZE (<MODE>mode)-1"
9732   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9734   [(set_attr "type" "rotate")
9735    (set_attr "mode" "<MODE>")])
9737 ;; Implement rotation using two double-precision
9738 ;; shift instructions and a scratch register.
9740 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9741  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9742        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9743                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9744   (clobber (reg:CC FLAGS_REG))
9745   (clobber (match_scratch:DWIH 3 "=&r"))]
9746  ""
9747  "#"
9748  "reload_completed"
9749  [(set (match_dup 3) (match_dup 4))
9750   (parallel
9751    [(set (match_dup 4)
9752          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9753                    (lshiftrt:DWIH (match_dup 5)
9754                                   (minus:QI (match_dup 6) (match_dup 2)))))
9755     (clobber (reg:CC FLAGS_REG))])
9756   (parallel
9757    [(set (match_dup 5)
9758          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9759                    (lshiftrt:DWIH (match_dup 3)
9760                                   (minus:QI (match_dup 6) (match_dup 2)))))
9761     (clobber (reg:CC FLAGS_REG))])]
9763   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9765   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9768 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9769  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9770        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9771                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9772   (clobber (reg:CC FLAGS_REG))
9773   (clobber (match_scratch:DWIH 3 "=&r"))]
9774  ""
9775  "#"
9776  "reload_completed"
9777  [(set (match_dup 3) (match_dup 4))
9778   (parallel
9779    [(set (match_dup 4)
9780          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9781                    (ashift:DWIH (match_dup 5)
9782                                 (minus:QI (match_dup 6) (match_dup 2)))))
9783     (clobber (reg:CC FLAGS_REG))])
9784   (parallel
9785    [(set (match_dup 5)
9786          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9787                    (ashift:DWIH (match_dup 3)
9788                                 (minus:QI (match_dup 6) (match_dup 2)))))
9789     (clobber (reg:CC FLAGS_REG))])]
9791   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9793   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9796 (define_insn "*bmi2_rorx<mode>3_1"
9797   [(set (match_operand:SWI48 0 "register_operand" "=r")
9798         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9799                         (match_operand:QI 2 "immediate_operand" "<S>")))]
9800   "TARGET_BMI2"
9801   "rorx\t{%2, %1, %0|%0, %1, %2}"
9802   [(set_attr "type" "rotatex")
9803    (set_attr "mode" "<MODE>")])
9805 (define_insn "*<rotate_insn><mode>3_1"
9806   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9807         (any_rotate:SWI48
9808           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9809           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
9810    (clobber (reg:CC FLAGS_REG))]
9811   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9813   switch (get_attr_type (insn))
9814     {
9815     case TYPE_ROTATEX:
9816       return "#";
9818     default:
9819       if (operands[2] == const1_rtx
9820           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9821         return "<rotate>{<imodesuffix>}\t%0";
9822       else
9823         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9824     }
9826   [(set_attr "isa" "*,bmi2")
9827    (set_attr "type" "rotate,rotatex")
9828    (set (attr "length_immediate")
9829      (if_then_else
9830        (and (eq_attr "type" "rotate")
9831             (and (match_operand 2 "const1_operand")
9832                  (ior (match_test "TARGET_SHIFT1")
9833                       (match_test "optimize_function_for_size_p (cfun)"))))
9834        (const_string "0")
9835        (const_string "*")))
9836    (set_attr "mode" "<MODE>")])
9838 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9839 (define_split
9840   [(set (match_operand:SWI48 0 "register_operand")
9841         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9842                       (match_operand:QI 2 "immediate_operand")))
9843    (clobber (reg:CC FLAGS_REG))]
9844   "TARGET_BMI2 && reload_completed"
9845   [(set (match_dup 0)
9846         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
9848   operands[2]
9849     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
9852 (define_split
9853   [(set (match_operand:SWI48 0 "register_operand")
9854         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9855                         (match_operand:QI 2 "immediate_operand")))
9856    (clobber (reg:CC FLAGS_REG))]
9857   "TARGET_BMI2 && reload_completed"
9858   [(set (match_dup 0)
9859         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
9861 (define_insn "*bmi2_rorxsi3_1_zext"
9862   [(set (match_operand:DI 0 "register_operand" "=r")
9863         (zero_extend:DI
9864           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9865                        (match_operand:QI 2 "immediate_operand" "I"))))]
9866   "TARGET_64BIT && TARGET_BMI2"
9867   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
9868   [(set_attr "type" "rotatex")
9869    (set_attr "mode" "SI")])
9871 (define_insn "*<rotate_insn>si3_1_zext"
9872   [(set (match_operand:DI 0 "register_operand" "=r,r")
9873         (zero_extend:DI
9874           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9875                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
9876    (clobber (reg:CC FLAGS_REG))]
9877   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9879   switch (get_attr_type (insn))
9880     {
9881     case TYPE_ROTATEX:
9882       return "#";
9884     default:
9885       if (operands[2] == const1_rtx
9886           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887         return "<rotate>{l}\t%k0";
9888       else
9889         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
9890     }
9892   [(set_attr "isa" "*,bmi2")
9893    (set_attr "type" "rotate,rotatex")
9894    (set (attr "length_immediate")
9895      (if_then_else
9896        (and (eq_attr "type" "rotate")
9897             (and (match_operand 2 "const1_operand")
9898                  (ior (match_test "TARGET_SHIFT1")
9899                       (match_test "optimize_function_for_size_p (cfun)"))))
9900        (const_string "0")
9901        (const_string "*")))
9902    (set_attr "mode" "SI")])
9904 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9905 (define_split
9906   [(set (match_operand:DI 0 "register_operand")
9907         (zero_extend:DI
9908           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
9909                      (match_operand:QI 2 "immediate_operand"))))
9910    (clobber (reg:CC FLAGS_REG))]
9911   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9912   [(set (match_dup 0)
9913         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
9915   operands[2]
9916     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
9919 (define_split
9920   [(set (match_operand:DI 0 "register_operand")
9921         (zero_extend:DI
9922           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
9923                        (match_operand:QI 2 "immediate_operand"))))
9924    (clobber (reg:CC FLAGS_REG))]
9925   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9926   [(set (match_dup 0)
9927         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
9929 (define_insn "*<rotate_insn><mode>3_1"
9930   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9931         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9932                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9933    (clobber (reg:CC FLAGS_REG))]
9934   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9936   if (operands[2] == const1_rtx
9937       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9938     return "<rotate>{<imodesuffix>}\t%0";
9939   else
9940     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9942   [(set_attr "type" "rotate")
9943    (set (attr "length_immediate")
9944      (if_then_else
9945        (and (match_operand 2 "const1_operand")
9946             (ior (match_test "TARGET_SHIFT1")
9947                  (match_test "optimize_function_for_size_p (cfun)")))
9948        (const_string "0")
9949        (const_string "*")))
9950    (set_attr "mode" "<MODE>")])
9952 (define_insn "*<rotate_insn>qi3_1_slp"
9953   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9954         (any_rotate:QI (match_dup 0)
9955                        (match_operand:QI 1 "nonmemory_operand" "cI")))
9956    (clobber (reg:CC FLAGS_REG))]
9957   "(optimize_function_for_size_p (cfun)
9958     || !TARGET_PARTIAL_REG_STALL
9959     || (operands[1] == const1_rtx
9960         && TARGET_SHIFT1))"
9962   if (operands[1] == const1_rtx
9963       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9964     return "<rotate>{b}\t%0";
9965   else
9966     return "<rotate>{b}\t{%1, %0|%0, %1}";
9968   [(set_attr "type" "rotate1")
9969    (set (attr "length_immediate")
9970      (if_then_else
9971        (and (match_operand 1 "const1_operand")
9972             (ior (match_test "TARGET_SHIFT1")
9973                  (match_test "optimize_function_for_size_p (cfun)")))
9974        (const_string "0")
9975        (const_string "*")))
9976    (set_attr "mode" "QI")])
9978 (define_split
9979  [(set (match_operand:HI 0 "register_operand")
9980        (any_rotate:HI (match_dup 0) (const_int 8)))
9981   (clobber (reg:CC FLAGS_REG))]
9982  "reload_completed
9983   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
9984  [(parallel [(set (strict_low_part (match_dup 0))
9985                   (bswap:HI (match_dup 0)))
9986              (clobber (reg:CC FLAGS_REG))])])
9988 ;; Bit set / bit test instructions
9990 (define_expand "extv"
9991   [(set (match_operand:SI 0 "register_operand")
9992         (sign_extract:SI (match_operand:SI 1 "register_operand")
9993                          (match_operand:SI 2 "const8_operand")
9994                          (match_operand:SI 3 "const8_operand")))]
9995   ""
9997   /* Handle extractions from %ah et al.  */
9998   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9999     FAIL;
10001   /* From mips.md: extract_bit_field doesn't verify that our source
10002      matches the predicate, so check it again here.  */
10003   if (! ext_register_operand (operands[1], VOIDmode))
10004     FAIL;
10007 (define_expand "extzv"
10008   [(set (match_operand:SI 0 "register_operand")
10009         (zero_extract:SI (match_operand 1 "ext_register_operand")
10010                          (match_operand:SI 2 "const8_operand")
10011                          (match_operand:SI 3 "const8_operand")))]
10012   ""
10014   /* Handle extractions from %ah et al.  */
10015   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10016     FAIL;
10018   /* From mips.md: extract_bit_field doesn't verify that our source
10019      matches the predicate, so check it again here.  */
10020   if (! ext_register_operand (operands[1], VOIDmode))
10021     FAIL;
10024 (define_expand "insv"
10025   [(set (zero_extract (match_operand 0 "register_operand")
10026                       (match_operand 1 "const_int_operand")
10027                       (match_operand 2 "const_int_operand"))
10028         (match_operand 3 "register_operand"))]
10029   ""
10031   rtx (*gen_mov_insv_1) (rtx, rtx);
10033   if (ix86_expand_pinsr (operands))
10034     DONE;
10036   /* Handle insertions to %ah et al.  */
10037   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10038     FAIL;
10040   /* From mips.md: insert_bit_field doesn't verify that our source
10041      matches the predicate, so check it again here.  */
10042   if (! ext_register_operand (operands[0], VOIDmode))
10043     FAIL;
10045   gen_mov_insv_1 = (TARGET_64BIT
10046                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10048   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10049   DONE;
10052 ;; %%% bts, btr, btc, bt.
10053 ;; In general these instructions are *slow* when applied to memory,
10054 ;; since they enforce atomic operation.  When applied to registers,
10055 ;; it depends on the cpu implementation.  They're never faster than
10056 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10057 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10058 ;; within the instruction itself, so operating on bits in the high
10059 ;; 32-bits of a register becomes easier.
10061 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10062 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10063 ;; negdf respectively, so they can never be disabled entirely.
10065 (define_insn "*btsq"
10066   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10067                          (const_int 1)
10068                          (match_operand:DI 1 "const_0_to_63_operand"))
10069         (const_int 1))
10070    (clobber (reg:CC FLAGS_REG))]
10071   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10072   "bts{q}\t{%1, %0|%0, %1}"
10073   [(set_attr "type" "alu1")
10074    (set_attr "prefix_0f" "1")
10075    (set_attr "mode" "DI")])
10077 (define_insn "*btrq"
10078   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10079                          (const_int 1)
10080                          (match_operand:DI 1 "const_0_to_63_operand"))
10081         (const_int 0))
10082    (clobber (reg:CC FLAGS_REG))]
10083   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10084   "btr{q}\t{%1, %0|%0, %1}"
10085   [(set_attr "type" "alu1")
10086    (set_attr "prefix_0f" "1")
10087    (set_attr "mode" "DI")])
10089 (define_insn "*btcq"
10090   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10091                          (const_int 1)
10092                          (match_operand:DI 1 "const_0_to_63_operand"))
10093         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10094    (clobber (reg:CC FLAGS_REG))]
10095   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10096   "btc{q}\t{%1, %0|%0, %1}"
10097   [(set_attr "type" "alu1")
10098    (set_attr "prefix_0f" "1")
10099    (set_attr "mode" "DI")])
10101 ;; Allow Nocona to avoid these instructions if a register is available.
10103 (define_peephole2
10104   [(match_scratch:DI 2 "r")
10105    (parallel [(set (zero_extract:DI
10106                      (match_operand:DI 0 "register_operand")
10107                      (const_int 1)
10108                      (match_operand:DI 1 "const_0_to_63_operand"))
10109                    (const_int 1))
10110               (clobber (reg:CC FLAGS_REG))])]
10111   "TARGET_64BIT && !TARGET_USE_BT"
10112   [(const_int 0)]
10114   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10115   rtx op1;
10117   if (HOST_BITS_PER_WIDE_INT >= 64)
10118     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10119   else if (i < HOST_BITS_PER_WIDE_INT)
10120     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10121   else
10122     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10124   op1 = immed_double_const (lo, hi, DImode);
10125   if (i >= 31)
10126     {
10127       emit_move_insn (operands[2], op1);
10128       op1 = operands[2];
10129     }
10131   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10132   DONE;
10135 (define_peephole2
10136   [(match_scratch:DI 2 "r")
10137    (parallel [(set (zero_extract:DI
10138                      (match_operand:DI 0 "register_operand")
10139                      (const_int 1)
10140                      (match_operand:DI 1 "const_0_to_63_operand"))
10141                    (const_int 0))
10142               (clobber (reg:CC FLAGS_REG))])]
10143   "TARGET_64BIT && !TARGET_USE_BT"
10144   [(const_int 0)]
10146   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10147   rtx op1;
10149   if (HOST_BITS_PER_WIDE_INT >= 64)
10150     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10151   else if (i < HOST_BITS_PER_WIDE_INT)
10152     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10153   else
10154     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10156   op1 = immed_double_const (~lo, ~hi, DImode);
10157   if (i >= 32)
10158     {
10159       emit_move_insn (operands[2], op1);
10160       op1 = operands[2];
10161     }
10163   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10164   DONE;
10167 (define_peephole2
10168   [(match_scratch:DI 2 "r")
10169    (parallel [(set (zero_extract:DI
10170                      (match_operand:DI 0 "register_operand")
10171                      (const_int 1)
10172                      (match_operand:DI 1 "const_0_to_63_operand"))
10173               (not:DI (zero_extract:DI
10174                         (match_dup 0) (const_int 1) (match_dup 1))))
10175               (clobber (reg:CC FLAGS_REG))])]
10176   "TARGET_64BIT && !TARGET_USE_BT"
10177   [(const_int 0)]
10179   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10180   rtx op1;
10182   if (HOST_BITS_PER_WIDE_INT >= 64)
10183     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10184   else if (i < HOST_BITS_PER_WIDE_INT)
10185     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10186   else
10187     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10189   op1 = immed_double_const (lo, hi, DImode);
10190   if (i >= 31)
10191     {
10192       emit_move_insn (operands[2], op1);
10193       op1 = operands[2];
10194     }
10196   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10197   DONE;
10200 (define_insn "*bt<mode>"
10201   [(set (reg:CCC FLAGS_REG)
10202         (compare:CCC
10203           (zero_extract:SWI48
10204             (match_operand:SWI48 0 "register_operand" "r")
10205             (const_int 1)
10206             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10207           (const_int 0)))]
10208   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10209   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10210   [(set_attr "type" "alu1")
10211    (set_attr "prefix_0f" "1")
10212    (set_attr "mode" "<MODE>")])
10214 ;; Store-flag instructions.
10216 ;; For all sCOND expanders, also expand the compare or test insn that
10217 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10219 (define_insn_and_split "*setcc_di_1"
10220   [(set (match_operand:DI 0 "register_operand" "=q")
10221         (match_operator:DI 1 "ix86_comparison_operator"
10222           [(reg FLAGS_REG) (const_int 0)]))]
10223   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10224   "#"
10225   "&& reload_completed"
10226   [(set (match_dup 2) (match_dup 1))
10227    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10229   PUT_MODE (operands[1], QImode);
10230   operands[2] = gen_lowpart (QImode, operands[0]);
10233 (define_insn_and_split "*setcc_si_1_and"
10234   [(set (match_operand:SI 0 "register_operand" "=q")
10235         (match_operator:SI 1 "ix86_comparison_operator"
10236           [(reg FLAGS_REG) (const_int 0)]))
10237    (clobber (reg:CC FLAGS_REG))]
10238   "!TARGET_PARTIAL_REG_STALL
10239    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10240   "#"
10241   "&& reload_completed"
10242   [(set (match_dup 2) (match_dup 1))
10243    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10244               (clobber (reg:CC FLAGS_REG))])]
10246   PUT_MODE (operands[1], QImode);
10247   operands[2] = gen_lowpart (QImode, operands[0]);
10250 (define_insn_and_split "*setcc_si_1_movzbl"
10251   [(set (match_operand:SI 0 "register_operand" "=q")
10252         (match_operator:SI 1 "ix86_comparison_operator"
10253           [(reg FLAGS_REG) (const_int 0)]))]
10254   "!TARGET_PARTIAL_REG_STALL
10255    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10256   "#"
10257   "&& reload_completed"
10258   [(set (match_dup 2) (match_dup 1))
10259    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10261   PUT_MODE (operands[1], QImode);
10262   operands[2] = gen_lowpart (QImode, operands[0]);
10265 (define_insn "*setcc_qi"
10266   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10267         (match_operator:QI 1 "ix86_comparison_operator"
10268           [(reg FLAGS_REG) (const_int 0)]))]
10269   ""
10270   "set%C1\t%0"
10271   [(set_attr "type" "setcc")
10272    (set_attr "mode" "QI")])
10274 (define_insn "*setcc_qi_slp"
10275   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10276         (match_operator:QI 1 "ix86_comparison_operator"
10277           [(reg FLAGS_REG) (const_int 0)]))]
10278   ""
10279   "set%C1\t%0"
10280   [(set_attr "type" "setcc")
10281    (set_attr "mode" "QI")])
10283 ;; In general it is not safe to assume too much about CCmode registers,
10284 ;; so simplify-rtx stops when it sees a second one.  Under certain
10285 ;; conditions this is safe on x86, so help combine not create
10287 ;;      seta    %al
10288 ;;      testb   %al, %al
10289 ;;      sete    %al
10291 (define_split
10292   [(set (match_operand:QI 0 "nonimmediate_operand")
10293         (ne:QI (match_operator 1 "ix86_comparison_operator"
10294                  [(reg FLAGS_REG) (const_int 0)])
10295             (const_int 0)))]
10296   ""
10297   [(set (match_dup 0) (match_dup 1))]
10298   "PUT_MODE (operands[1], QImode);")
10300 (define_split
10301   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10302         (ne:QI (match_operator 1 "ix86_comparison_operator"
10303                  [(reg FLAGS_REG) (const_int 0)])
10304             (const_int 0)))]
10305   ""
10306   [(set (match_dup 0) (match_dup 1))]
10307   "PUT_MODE (operands[1], QImode);")
10309 (define_split
10310   [(set (match_operand:QI 0 "nonimmediate_operand")
10311         (eq:QI (match_operator 1 "ix86_comparison_operator"
10312                  [(reg FLAGS_REG) (const_int 0)])
10313             (const_int 0)))]
10314   ""
10315   [(set (match_dup 0) (match_dup 1))]
10317   rtx new_op1 = copy_rtx (operands[1]);
10318   operands[1] = new_op1;
10319   PUT_MODE (new_op1, QImode);
10320   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10321                                              GET_MODE (XEXP (new_op1, 0))));
10323   /* Make sure that (a) the CCmode we have for the flags is strong
10324      enough for the reversed compare or (b) we have a valid FP compare.  */
10325   if (! ix86_comparison_operator (new_op1, VOIDmode))
10326     FAIL;
10329 (define_split
10330   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10331         (eq:QI (match_operator 1 "ix86_comparison_operator"
10332                  [(reg FLAGS_REG) (const_int 0)])
10333             (const_int 0)))]
10334   ""
10335   [(set (match_dup 0) (match_dup 1))]
10337   rtx new_op1 = copy_rtx (operands[1]);
10338   operands[1] = new_op1;
10339   PUT_MODE (new_op1, QImode);
10340   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10341                                              GET_MODE (XEXP (new_op1, 0))));
10343   /* Make sure that (a) the CCmode we have for the flags is strong
10344      enough for the reversed compare or (b) we have a valid FP compare.  */
10345   if (! ix86_comparison_operator (new_op1, VOIDmode))
10346     FAIL;
10349 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10350 ;; subsequent logical operations are used to imitate conditional moves.
10351 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10352 ;; it directly.
10354 (define_insn "setcc_<mode>_sse"
10355   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10356         (match_operator:MODEF 3 "sse_comparison_operator"
10357           [(match_operand:MODEF 1 "register_operand" "0,x")
10358            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10359   "SSE_FLOAT_MODE_P (<MODE>mode)"
10360   "@
10361    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10362    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10363   [(set_attr "isa" "noavx,avx")
10364    (set_attr "type" "ssecmp")
10365    (set_attr "length_immediate" "1")
10366    (set_attr "prefix" "orig,vex")
10367    (set_attr "mode" "<MODE>")])
10369 ;; Basic conditional jump instructions.
10370 ;; We ignore the overflow flag for signed branch instructions.
10372 (define_insn "*jcc_1"
10373   [(set (pc)
10374         (if_then_else (match_operator 1 "ix86_comparison_operator"
10375                                       [(reg FLAGS_REG) (const_int 0)])
10376                       (label_ref (match_operand 0))
10377                       (pc)))]
10378   ""
10379   "%+j%C1\t%l0"
10380   [(set_attr "type" "ibr")
10381    (set_attr "modrm" "0")
10382    (set (attr "length")
10383            (if_then_else (and (ge (minus (match_dup 0) (pc))
10384                                   (const_int -126))
10385                               (lt (minus (match_dup 0) (pc))
10386                                   (const_int 128)))
10387              (const_int 2)
10388              (const_int 6)))])
10390 (define_insn "*jcc_2"
10391   [(set (pc)
10392         (if_then_else (match_operator 1 "ix86_comparison_operator"
10393                                       [(reg FLAGS_REG) (const_int 0)])
10394                       (pc)
10395                       (label_ref (match_operand 0))))]
10396   ""
10397   "%+j%c1\t%l0"
10398   [(set_attr "type" "ibr")
10399    (set_attr "modrm" "0")
10400    (set (attr "length")
10401            (if_then_else (and (ge (minus (match_dup 0) (pc))
10402                                   (const_int -126))
10403                               (lt (minus (match_dup 0) (pc))
10404                                   (const_int 128)))
10405              (const_int 2)
10406              (const_int 6)))])
10408 ;; In general it is not safe to assume too much about CCmode registers,
10409 ;; so simplify-rtx stops when it sees a second one.  Under certain
10410 ;; conditions this is safe on x86, so help combine not create
10412 ;;      seta    %al
10413 ;;      testb   %al, %al
10414 ;;      je      Lfoo
10416 (define_split
10417   [(set (pc)
10418         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10419                                       [(reg FLAGS_REG) (const_int 0)])
10420                           (const_int 0))
10421                       (label_ref (match_operand 1))
10422                       (pc)))]
10423   ""
10424   [(set (pc)
10425         (if_then_else (match_dup 0)
10426                       (label_ref (match_dup 1))
10427                       (pc)))]
10428   "PUT_MODE (operands[0], VOIDmode);")
10430 (define_split
10431   [(set (pc)
10432         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10433                                       [(reg FLAGS_REG) (const_int 0)])
10434                           (const_int 0))
10435                       (label_ref (match_operand 1))
10436                       (pc)))]
10437   ""
10438   [(set (pc)
10439         (if_then_else (match_dup 0)
10440                       (label_ref (match_dup 1))
10441                       (pc)))]
10443   rtx new_op0 = copy_rtx (operands[0]);
10444   operands[0] = new_op0;
10445   PUT_MODE (new_op0, VOIDmode);
10446   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10447                                              GET_MODE (XEXP (new_op0, 0))));
10449   /* Make sure that (a) the CCmode we have for the flags is strong
10450      enough for the reversed compare or (b) we have a valid FP compare.  */
10451   if (! ix86_comparison_operator (new_op0, VOIDmode))
10452     FAIL;
10455 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10456 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10457 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10458 ;; appropriate modulo of the bit offset value.
10460 (define_insn_and_split "*jcc_bt<mode>"
10461   [(set (pc)
10462         (if_then_else (match_operator 0 "bt_comparison_operator"
10463                         [(zero_extract:SWI48
10464                            (match_operand:SWI48 1 "register_operand" "r")
10465                            (const_int 1)
10466                            (zero_extend:SI
10467                              (match_operand:QI 2 "register_operand" "r")))
10468                          (const_int 0)])
10469                       (label_ref (match_operand 3))
10470                       (pc)))
10471    (clobber (reg:CC FLAGS_REG))]
10472   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10473   "#"
10474   "&& 1"
10475   [(set (reg:CCC FLAGS_REG)
10476         (compare:CCC
10477           (zero_extract:SWI48
10478             (match_dup 1)
10479             (const_int 1)
10480             (match_dup 2))
10481           (const_int 0)))
10482    (set (pc)
10483         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10484                       (label_ref (match_dup 3))
10485                       (pc)))]
10487   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10489   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10492 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10493 ;; zero extended to SImode.
10494 (define_insn_and_split "*jcc_bt<mode>_1"
10495   [(set (pc)
10496         (if_then_else (match_operator 0 "bt_comparison_operator"
10497                         [(zero_extract:SWI48
10498                            (match_operand:SWI48 1 "register_operand" "r")
10499                            (const_int 1)
10500                            (match_operand:SI 2 "register_operand" "r"))
10501                          (const_int 0)])
10502                       (label_ref (match_operand 3))
10503                       (pc)))
10504    (clobber (reg:CC FLAGS_REG))]
10505   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10506   "#"
10507   "&& 1"
10508   [(set (reg:CCC FLAGS_REG)
10509         (compare:CCC
10510           (zero_extract:SWI48
10511             (match_dup 1)
10512             (const_int 1)
10513             (match_dup 2))
10514           (const_int 0)))
10515    (set (pc)
10516         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10517                       (label_ref (match_dup 3))
10518                       (pc)))]
10520   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10522   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10525 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10526 ;; also for DImode, this is what combine produces.
10527 (define_insn_and_split "*jcc_bt<mode>_mask"
10528   [(set (pc)
10529         (if_then_else (match_operator 0 "bt_comparison_operator"
10530                         [(zero_extract:SWI48
10531                            (match_operand:SWI48 1 "register_operand" "r")
10532                            (const_int 1)
10533                            (and:SI
10534                              (match_operand:SI 2 "register_operand" "r")
10535                              (match_operand:SI 3 "const_int_operand" "n")))])
10536                       (label_ref (match_operand 4))
10537                       (pc)))
10538    (clobber (reg:CC FLAGS_REG))]
10539   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10540    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10541       == GET_MODE_BITSIZE (<MODE>mode)-1"
10542   "#"
10543   "&& 1"
10544   [(set (reg:CCC FLAGS_REG)
10545         (compare:CCC
10546           (zero_extract:SWI48
10547             (match_dup 1)
10548             (const_int 1)
10549             (match_dup 2))
10550           (const_int 0)))
10551    (set (pc)
10552         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10553                       (label_ref (match_dup 4))
10554                       (pc)))]
10556   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10558   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10561 (define_insn_and_split "*jcc_btsi_1"
10562   [(set (pc)
10563         (if_then_else (match_operator 0 "bt_comparison_operator"
10564                         [(and:SI
10565                            (lshiftrt:SI
10566                              (match_operand:SI 1 "register_operand" "r")
10567                              (match_operand:QI 2 "register_operand" "r"))
10568                            (const_int 1))
10569                          (const_int 0)])
10570                       (label_ref (match_operand 3))
10571                       (pc)))
10572    (clobber (reg:CC FLAGS_REG))]
10573   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10574   "#"
10575   "&& 1"
10576   [(set (reg:CCC FLAGS_REG)
10577         (compare:CCC
10578           (zero_extract:SI
10579             (match_dup 1)
10580             (const_int 1)
10581             (match_dup 2))
10582           (const_int 0)))
10583    (set (pc)
10584         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10585                       (label_ref (match_dup 3))
10586                       (pc)))]
10588   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10590   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10593 ;; avoid useless masking of bit offset operand
10594 (define_insn_and_split "*jcc_btsi_mask_1"
10595   [(set (pc)
10596         (if_then_else
10597           (match_operator 0 "bt_comparison_operator"
10598             [(and:SI
10599                (lshiftrt:SI
10600                  (match_operand:SI 1 "register_operand" "r")
10601                  (subreg:QI
10602                    (and:SI
10603                      (match_operand:SI 2 "register_operand" "r")
10604                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10605                (const_int 1))
10606              (const_int 0)])
10607           (label_ref (match_operand 4))
10608           (pc)))
10609    (clobber (reg:CC FLAGS_REG))]
10610   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10611    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10612   "#"
10613   "&& 1"
10614   [(set (reg:CCC FLAGS_REG)
10615         (compare:CCC
10616           (zero_extract:SI
10617             (match_dup 1)
10618             (const_int 1)
10619             (match_dup 2))
10620           (const_int 0)))
10621    (set (pc)
10622         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10623                       (label_ref (match_dup 4))
10624                       (pc)))]
10625   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10627 ;; Define combination compare-and-branch fp compare instructions to help
10628 ;; combine.
10630 (define_insn "*jcc<mode>_0_i387"
10631   [(set (pc)
10632         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10633                         [(match_operand:X87MODEF 1 "register_operand" "f")
10634                          (match_operand:X87MODEF 2 "const0_operand")])
10635           (label_ref (match_operand 3))
10636           (pc)))
10637    (clobber (reg:CCFP FPSR_REG))
10638    (clobber (reg:CCFP FLAGS_REG))
10639    (clobber (match_scratch:HI 4 "=a"))]
10640   "TARGET_80387 && !TARGET_CMOVE"
10641   "#")
10643 (define_insn "*jcc<mode>_0_r_i387"
10644   [(set (pc)
10645         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10646                         [(match_operand:X87MODEF 1 "register_operand" "f")
10647                          (match_operand:X87MODEF 2 "const0_operand")])
10648           (pc)
10649           (label_ref (match_operand 3))))
10650    (clobber (reg:CCFP FPSR_REG))
10651    (clobber (reg:CCFP FLAGS_REG))
10652    (clobber (match_scratch:HI 4 "=a"))]
10653   "TARGET_80387 && !TARGET_CMOVE"
10654   "#")
10656 (define_insn "*jccxf_i387"
10657   [(set (pc)
10658         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10659                         [(match_operand:XF 1 "register_operand" "f")
10660                          (match_operand:XF 2 "register_operand" "f")])
10661           (label_ref (match_operand 3))
10662           (pc)))
10663    (clobber (reg:CCFP FPSR_REG))
10664    (clobber (reg:CCFP FLAGS_REG))
10665    (clobber (match_scratch:HI 4 "=a"))]
10666   "TARGET_80387 && !TARGET_CMOVE"
10667   "#")
10669 (define_insn "*jccxf_r_i387"
10670   [(set (pc)
10671         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10672                         [(match_operand:XF 1 "register_operand" "f")
10673                          (match_operand:XF 2 "register_operand" "f")])
10674           (pc)
10675           (label_ref (match_operand 3))))
10676    (clobber (reg:CCFP FPSR_REG))
10677    (clobber (reg:CCFP FLAGS_REG))
10678    (clobber (match_scratch:HI 4 "=a"))]
10679   "TARGET_80387 && !TARGET_CMOVE"
10680   "#")
10682 (define_insn "*jcc<mode>_i387"
10683   [(set (pc)
10684         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10685                         [(match_operand:MODEF 1 "register_operand" "f")
10686                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10687           (label_ref (match_operand 3))
10688           (pc)))
10689    (clobber (reg:CCFP FPSR_REG))
10690    (clobber (reg:CCFP FLAGS_REG))
10691    (clobber (match_scratch:HI 4 "=a"))]
10692   "TARGET_80387 && !TARGET_CMOVE"
10693   "#")
10695 (define_insn "*jcc<mode>_r_i387"
10696   [(set (pc)
10697         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10698                         [(match_operand:MODEF 1 "register_operand" "f")
10699                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10700           (pc)
10701           (label_ref (match_operand 3))))
10702    (clobber (reg:CCFP FPSR_REG))
10703    (clobber (reg:CCFP FLAGS_REG))
10704    (clobber (match_scratch:HI 4 "=a"))]
10705   "TARGET_80387 && !TARGET_CMOVE"
10706   "#")
10708 (define_insn "*jccu<mode>_i387"
10709   [(set (pc)
10710         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10711                         [(match_operand:X87MODEF 1 "register_operand" "f")
10712                          (match_operand:X87MODEF 2 "register_operand" "f")])
10713           (label_ref (match_operand 3))
10714           (pc)))
10715    (clobber (reg:CCFP FPSR_REG))
10716    (clobber (reg:CCFP FLAGS_REG))
10717    (clobber (match_scratch:HI 4 "=a"))]
10718   "TARGET_80387 && !TARGET_CMOVE"
10719   "#")
10721 (define_insn "*jccu<mode>_r_i387"
10722   [(set (pc)
10723         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10724                         [(match_operand:X87MODEF 1 "register_operand" "f")
10725                          (match_operand:X87MODEF 2 "register_operand" "f")])
10726           (pc)
10727           (label_ref (match_operand 3))))
10728    (clobber (reg:CCFP FPSR_REG))
10729    (clobber (reg:CCFP FLAGS_REG))
10730    (clobber (match_scratch:HI 4 "=a"))]
10731   "TARGET_80387 && !TARGET_CMOVE"
10732   "#")
10734 (define_split
10735   [(set (pc)
10736         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10737                         [(match_operand:X87MODEF 1 "register_operand")
10738                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
10739           (match_operand 3)
10740           (match_operand 4)))
10741    (clobber (reg:CCFP FPSR_REG))
10742    (clobber (reg:CCFP FLAGS_REG))]
10743   "TARGET_80387 && !TARGET_CMOVE
10744    && reload_completed"
10745   [(const_int 0)]
10747   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10748                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10749   DONE;
10752 (define_split
10753   [(set (pc)
10754         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10755                         [(match_operand:X87MODEF 1 "register_operand")
10756                          (match_operand:X87MODEF 2 "general_operand")])
10757           (match_operand 3)
10758           (match_operand 4)))
10759    (clobber (reg:CCFP FPSR_REG))
10760    (clobber (reg:CCFP FLAGS_REG))
10761    (clobber (match_scratch:HI 5))]
10762   "TARGET_80387 && !TARGET_CMOVE
10763    && reload_completed"
10764   [(const_int 0)]
10766   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10767                         operands[3], operands[4], operands[5], NULL_RTX);
10768   DONE;
10771 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
10772 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10773 ;; with a precedence over other operators and is always put in the first
10774 ;; place. Swap condition and operands to match ficom instruction.
10776 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
10777   [(set (pc)
10778         (if_then_else
10779           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10780             [(match_operator:X87MODEF 1 "float_operator"
10781               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10782              (match_operand:X87MODEF 3 "register_operand" "f,f")])
10783           (label_ref (match_operand 4))
10784           (pc)))
10785    (clobber (reg:CCFP FPSR_REG))
10786    (clobber (reg:CCFP FLAGS_REG))
10787    (clobber (match_scratch:HI 5 "=a,a"))]
10788   "TARGET_80387 && !TARGET_CMOVE
10789    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10790        || optimize_function_for_size_p (cfun))"
10791   "#")
10793 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
10794   [(set (pc)
10795         (if_then_else
10796           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10797             [(match_operator:X87MODEF 1 "float_operator"
10798               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10799              (match_operand:X87MODEF 3 "register_operand" "f,f")])
10800           (pc)
10801           (label_ref (match_operand 4))))
10802    (clobber (reg:CCFP FPSR_REG))
10803    (clobber (reg:CCFP FLAGS_REG))
10804    (clobber (match_scratch:HI 5 "=a,a"))]
10805   "TARGET_80387 && !TARGET_CMOVE
10806    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10807        || optimize_function_for_size_p (cfun))"
10808   "#")
10810 (define_split
10811   [(set (pc)
10812         (if_then_else
10813           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10814             [(match_operator:X87MODEF 1 "float_operator"
10815               [(match_operand:SWI24 2 "memory_operand")])
10816              (match_operand:X87MODEF 3 "register_operand")])
10817           (match_operand 4)
10818           (match_operand 5)))
10819    (clobber (reg:CCFP FPSR_REG))
10820    (clobber (reg:CCFP FLAGS_REG))
10821    (clobber (match_scratch:HI 6))]
10822   "TARGET_80387 && !TARGET_CMOVE
10823    && reload_completed"
10824   [(const_int 0)]
10826   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10827                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
10828                         operands[4], operands[5], operands[6], NULL_RTX);
10829   DONE;
10832 ;; %%% Kill this when reload knows how to do it.
10833 (define_split
10834   [(set (pc)
10835         (if_then_else
10836           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10837             [(match_operator:X87MODEF 1 "float_operator"
10838               [(match_operand:SWI24 2 "register_operand")])
10839              (match_operand:X87MODEF 3 "register_operand")])
10840           (match_operand 4)
10841           (match_operand 5)))
10842    (clobber (reg:CCFP FPSR_REG))
10843    (clobber (reg:CCFP FLAGS_REG))
10844    (clobber (match_scratch:HI 6))]
10845   "TARGET_80387 && !TARGET_CMOVE
10846    && reload_completed"
10847   [(const_int 0)]
10849   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10851   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10852                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
10853                         operands[4], operands[5], operands[6], operands[2]);
10854   DONE;
10857 ;; Unconditional and other jump instructions
10859 (define_insn "jump"
10860   [(set (pc)
10861         (label_ref (match_operand 0)))]
10862   ""
10863   "jmp\t%l0"
10864   [(set_attr "type" "ibr")
10865    (set (attr "length")
10866            (if_then_else (and (ge (minus (match_dup 0) (pc))
10867                                   (const_int -126))
10868                               (lt (minus (match_dup 0) (pc))
10869                                   (const_int 128)))
10870              (const_int 2)
10871              (const_int 5)))
10872    (set_attr "modrm" "0")])
10874 (define_expand "indirect_jump"
10875   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
10876   ""
10878   if (TARGET_X32)
10879     operands[0] = convert_memory_address (word_mode, operands[0]);
10882 (define_insn "*indirect_jump"
10883   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
10884   ""
10885   "jmp\t%A0"
10886   [(set_attr "type" "ibr")
10887    (set_attr "length_immediate" "0")])
10889 (define_expand "tablejump"
10890   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
10891               (use (label_ref (match_operand 1)))])]
10892   ""
10894   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10895      relative.  Convert the relative address to an absolute address.  */
10896   if (flag_pic)
10897     {
10898       rtx op0, op1;
10899       enum rtx_code code;
10901       /* We can't use @GOTOFF for text labels on VxWorks;
10902          see gotoff_operand.  */
10903       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10904         {
10905           code = PLUS;
10906           op0 = operands[0];
10907           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10908         }
10909       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10910         {
10911           code = PLUS;
10912           op0 = operands[0];
10913           op1 = pic_offset_table_rtx;
10914         }
10915       else
10916         {
10917           code = MINUS;
10918           op0 = pic_offset_table_rtx;
10919           op1 = operands[0];
10920         }
10922       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10923                                          OPTAB_DIRECT);
10924     }
10926   if (TARGET_X32)
10927     operands[0] = convert_memory_address (word_mode, operands[0]);
10930 (define_insn "*tablejump_1"
10931   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
10932    (use (label_ref (match_operand 1)))]
10933   ""
10934   "jmp\t%A0"
10935   [(set_attr "type" "ibr")
10936    (set_attr "length_immediate" "0")])
10938 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10940 (define_peephole2
10941   [(set (reg FLAGS_REG) (match_operand 0))
10942    (set (match_operand:QI 1 "register_operand")
10943         (match_operator:QI 2 "ix86_comparison_operator"
10944           [(reg FLAGS_REG) (const_int 0)]))
10945    (set (match_operand 3 "q_regs_operand")
10946         (zero_extend (match_dup 1)))]
10947   "(peep2_reg_dead_p (3, operands[1])
10948     || operands_match_p (operands[1], operands[3]))
10949    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10950   [(set (match_dup 4) (match_dup 0))
10951    (set (strict_low_part (match_dup 5))
10952         (match_dup 2))]
10954   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10955   operands[5] = gen_lowpart (QImode, operands[3]);
10956   ix86_expand_clear (operands[3]);
10959 (define_peephole2
10960   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
10961               (match_operand 4)])
10962    (set (match_operand:QI 1 "register_operand")
10963         (match_operator:QI 2 "ix86_comparison_operator"
10964           [(reg FLAGS_REG) (const_int 0)]))
10965    (set (match_operand 3 "q_regs_operand")
10966         (zero_extend (match_dup 1)))]
10967   "(peep2_reg_dead_p (3, operands[1])
10968     || operands_match_p (operands[1], operands[3]))
10969    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10970   [(parallel [(set (match_dup 5) (match_dup 0))
10971               (match_dup 4)])
10972    (set (strict_low_part (match_dup 6))
10973         (match_dup 2))]
10975   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10976   operands[6] = gen_lowpart (QImode, operands[3]);
10977   ix86_expand_clear (operands[3]);
10980 ;; Similar, but match zero extend with andsi3.
10982 (define_peephole2
10983   [(set (reg FLAGS_REG) (match_operand 0))
10984    (set (match_operand:QI 1 "register_operand")
10985         (match_operator:QI 2 "ix86_comparison_operator"
10986           [(reg FLAGS_REG) (const_int 0)]))
10987    (parallel [(set (match_operand:SI 3 "q_regs_operand")
10988                    (and:SI (match_dup 3) (const_int 255)))
10989               (clobber (reg:CC FLAGS_REG))])]
10990   "REGNO (operands[1]) == REGNO (operands[3])
10991    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10992   [(set (match_dup 4) (match_dup 0))
10993    (set (strict_low_part (match_dup 5))
10994         (match_dup 2))]
10996   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10997   operands[5] = gen_lowpart (QImode, operands[3]);
10998   ix86_expand_clear (operands[3]);
11001 (define_peephole2
11002   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11003               (match_operand 4)])
11004    (set (match_operand:QI 1 "register_operand")
11005         (match_operator:QI 2 "ix86_comparison_operator"
11006           [(reg FLAGS_REG) (const_int 0)]))
11007    (parallel [(set (match_operand 3 "q_regs_operand")
11008                    (zero_extend (match_dup 1)))
11009               (clobber (reg:CC FLAGS_REG))])]
11010   "(peep2_reg_dead_p (3, operands[1])
11011     || operands_match_p (operands[1], operands[3]))
11012    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11013   [(parallel [(set (match_dup 5) (match_dup 0))
11014               (match_dup 4)])
11015    (set (strict_low_part (match_dup 6))
11016         (match_dup 2))]
11018   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11019   operands[6] = gen_lowpart (QImode, operands[3]);
11020   ix86_expand_clear (operands[3]);
11023 ;; Call instructions.
11025 ;; The predicates normally associated with named expanders are not properly
11026 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11027 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11029 ;; P6 processors will jump to the address after the decrement when %esp
11030 ;; is used as a call operand, so they will execute return address as a code.
11031 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11033 ;; Register constraint for call instruction.
11034 (define_mode_attr c [(SI "l") (DI "r")])
11036 ;; Call subroutine returning no value.
11038 (define_expand "call"
11039   [(call (match_operand:QI 0)
11040          (match_operand 1))
11041    (use (match_operand 2))]
11042   ""
11044   ix86_expand_call (NULL, operands[0], operands[1],
11045                     operands[2], NULL, false);
11046   DONE;
11049 (define_expand "sibcall"
11050   [(call (match_operand:QI 0)
11051          (match_operand 1))
11052    (use (match_operand 2))]
11053   ""
11055   ix86_expand_call (NULL, operands[0], operands[1],
11056                     operands[2], NULL, true);
11057   DONE;
11060 (define_insn "*call"
11061   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11062          (match_operand 1))]
11063   "!SIBLING_CALL_P (insn)"
11064   "* return ix86_output_call_insn (insn, operands[0]);"
11065   [(set_attr "type" "call")])
11067 (define_insn "*call_rex64_ms_sysv"
11068   [(match_parallel 2 "call_rex64_ms_sysv_operation"
11069     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11070            (match_operand 1))
11071      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11072   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11073   "* return ix86_output_call_insn (insn, operands[0]);"
11074   [(set_attr "type" "call")])
11076 (define_insn "*sibcall"
11077   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11078          (match_operand 1))]
11079   "SIBLING_CALL_P (insn)"
11080   "* return ix86_output_call_insn (insn, operands[0]);"
11081   [(set_attr "type" "call")])
11083 (define_expand "call_pop"
11084   [(parallel [(call (match_operand:QI 0)
11085                     (match_operand:SI 1))
11086               (set (reg:SI SP_REG)
11087                    (plus:SI (reg:SI SP_REG)
11088                             (match_operand:SI 3)))])]
11089   "!TARGET_64BIT"
11091   ix86_expand_call (NULL, operands[0], operands[1],
11092                     operands[2], operands[3], false);
11093   DONE;
11096 (define_insn "*call_pop"
11097   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11098          (match_operand 1))
11099    (set (reg:SI SP_REG)
11100         (plus:SI (reg:SI SP_REG)
11101                  (match_operand:SI 2 "immediate_operand" "i")))]
11102   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11103   "* return ix86_output_call_insn (insn, operands[0]);"
11104   [(set_attr "type" "call")])
11106 (define_insn "*sibcall_pop"
11107   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11108          (match_operand 1))
11109    (set (reg:SI SP_REG)
11110         (plus:SI (reg:SI SP_REG)
11111                  (match_operand:SI 2 "immediate_operand" "i")))]
11112   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11113   "* return ix86_output_call_insn (insn, operands[0]);"
11114   [(set_attr "type" "call")])
11116 ;; Call subroutine, returning value in operand 0
11118 (define_expand "call_value"
11119   [(set (match_operand 0)
11120         (call (match_operand:QI 1)
11121               (match_operand 2)))
11122    (use (match_operand 3))]
11123   ""
11125   ix86_expand_call (operands[0], operands[1], operands[2],
11126                     operands[3], NULL, false);
11127   DONE;
11130 (define_expand "sibcall_value"
11131   [(set (match_operand 0)
11132         (call (match_operand:QI 1)
11133               (match_operand 2)))
11134    (use (match_operand 3))]
11135   ""
11137   ix86_expand_call (operands[0], operands[1], operands[2],
11138                     operands[3], NULL, true);
11139   DONE;
11142 (define_insn "*call_value"
11143   [(set (match_operand 0)
11144         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11145               (match_operand 2)))]
11146   "!SIBLING_CALL_P (insn)"
11147   "* return ix86_output_call_insn (insn, operands[1]);"
11148   [(set_attr "type" "callv")])
11150 (define_insn "*sibcall_value"
11151   [(set (match_operand 0)
11152         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11153               (match_operand 2)))]
11154   "SIBLING_CALL_P (insn)"
11155   "* return ix86_output_call_insn (insn, operands[1]);"
11156   [(set_attr "type" "callv")])
11158 (define_insn "*call_value_rex64_ms_sysv"
11159   [(match_parallel 3 "call_rex64_ms_sysv_operation"
11160     [(set (match_operand 0)
11161           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11162                 (match_operand 2)))
11163      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11164  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11165   "* return ix86_output_call_insn (insn, operands[1]);"
11166   [(set_attr "type" "callv")])
11168 (define_expand "call_value_pop"
11169   [(parallel [(set (match_operand 0)
11170                    (call (match_operand:QI 1)
11171                          (match_operand:SI 2)))
11172               (set (reg:SI SP_REG)
11173                    (plus:SI (reg:SI SP_REG)
11174                             (match_operand:SI 4)))])]
11175   "!TARGET_64BIT"
11177   ix86_expand_call (operands[0], operands[1], operands[2],
11178                     operands[3], operands[4], false);
11179   DONE;
11182 (define_insn "*call_value_pop"
11183   [(set (match_operand 0)
11184         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11185               (match_operand 2)))
11186    (set (reg:SI SP_REG)
11187         (plus:SI (reg:SI SP_REG)
11188                  (match_operand:SI 3 "immediate_operand" "i")))]
11189   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11190   "* return ix86_output_call_insn (insn, operands[1]);"
11191   [(set_attr "type" "callv")])
11193 (define_insn "*sibcall_value_pop"
11194   [(set (match_operand 0)
11195         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11196               (match_operand 2)))
11197    (set (reg:SI SP_REG)
11198         (plus:SI (reg:SI SP_REG)
11199                  (match_operand:SI 3 "immediate_operand" "i")))]
11200   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11201   "* return ix86_output_call_insn (insn, operands[1]);"
11202   [(set_attr "type" "callv")])
11204 ;; Call subroutine returning any type.
11206 (define_expand "untyped_call"
11207   [(parallel [(call (match_operand 0)
11208                     (const_int 0))
11209               (match_operand 1)
11210               (match_operand 2)])]
11211   ""
11213   int i;
11215   /* In order to give reg-stack an easier job in validating two
11216      coprocessor registers as containing a possible return value,
11217      simply pretend the untyped call returns a complex long double
11218      value. 
11220      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11221      and should have the default ABI.  */
11223   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11224                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11225                     operands[0], const0_rtx,
11226                     GEN_INT ((TARGET_64BIT
11227                               ? (ix86_abi == SYSV_ABI
11228                                  ? X86_64_SSE_REGPARM_MAX
11229                                  : X86_64_MS_SSE_REGPARM_MAX)
11230                               : X86_32_SSE_REGPARM_MAX)
11231                              - 1),
11232                     NULL, false);
11234   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11235     {
11236       rtx set = XVECEXP (operands[2], 0, i);
11237       emit_move_insn (SET_DEST (set), SET_SRC (set));
11238     }
11240   /* The optimizer does not know that the call sets the function value
11241      registers we stored in the result block.  We avoid problems by
11242      claiming that all hard registers are used and clobbered at this
11243      point.  */
11244   emit_insn (gen_blockage ());
11246   DONE;
11249 ;; Prologue and epilogue instructions
11251 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11252 ;; all of memory.  This blocks insns from being moved across this point.
11254 (define_insn "blockage"
11255   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11256   ""
11257   ""
11258   [(set_attr "length" "0")])
11260 ;; Do not schedule instructions accessing memory across this point.
11262 (define_expand "memory_blockage"
11263   [(set (match_dup 0)
11264         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11265   ""
11267   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11268   MEM_VOLATILE_P (operands[0]) = 1;
11271 (define_insn "*memory_blockage"
11272   [(set (match_operand:BLK 0)
11273         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11274   ""
11275   ""
11276   [(set_attr "length" "0")])
11278 ;; As USE insns aren't meaningful after reload, this is used instead
11279 ;; to prevent deleting instructions setting registers for PIC code
11280 (define_insn "prologue_use"
11281   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11282   ""
11283   ""
11284   [(set_attr "length" "0")])
11286 ;; Insn emitted into the body of a function to return from a function.
11287 ;; This is only done if the function's epilogue is known to be simple.
11288 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11290 (define_expand "return"
11291   [(simple_return)]
11292   "ix86_can_use_return_insn_p ()"
11294   if (crtl->args.pops_args)
11295     {
11296       rtx popc = GEN_INT (crtl->args.pops_args);
11297       emit_jump_insn (gen_simple_return_pop_internal (popc));
11298       DONE;
11299     }
11302 ;; We need to disable this for TARGET_SEH, as otherwise
11303 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11304 ;; the maximum size of prologue in unwind information.
11306 (define_expand "simple_return"
11307   [(simple_return)]
11308   "!TARGET_SEH"
11310   if (crtl->args.pops_args)
11311     {
11312       rtx popc = GEN_INT (crtl->args.pops_args);
11313       emit_jump_insn (gen_simple_return_pop_internal (popc));
11314       DONE;
11315     }
11318 (define_insn "simple_return_internal"
11319   [(simple_return)]
11320   "reload_completed"
11321   "ret"
11322   [(set_attr "length" "1")
11323    (set_attr "atom_unit" "jeu")
11324    (set_attr "length_immediate" "0")
11325    (set_attr "modrm" "0")])
11327 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11328 ;; instruction Athlon and K8 have.
11330 (define_insn "simple_return_internal_long"
11331   [(simple_return)
11332    (unspec [(const_int 0)] UNSPEC_REP)]
11333   "reload_completed"
11334   "rep%; ret"
11335   [(set_attr "length" "2")
11336    (set_attr "atom_unit" "jeu")
11337    (set_attr "length_immediate" "0")
11338    (set_attr "prefix_rep" "1")
11339    (set_attr "modrm" "0")])
11341 (define_insn "simple_return_pop_internal"
11342   [(simple_return)
11343    (use (match_operand:SI 0 "const_int_operand"))]
11344   "reload_completed"
11345   "ret\t%0"
11346   [(set_attr "length" "3")
11347    (set_attr "atom_unit" "jeu")
11348    (set_attr "length_immediate" "2")
11349    (set_attr "modrm" "0")])
11351 (define_insn "simple_return_indirect_internal"
11352   [(simple_return)
11353    (use (match_operand:SI 0 "register_operand" "r"))]
11354   "reload_completed"
11355   "jmp\t%A0"
11356   [(set_attr "type" "ibr")
11357    (set_attr "length_immediate" "0")])
11359 (define_insn "nop"
11360   [(const_int 0)]
11361   ""
11362   "nop"
11363   [(set_attr "length" "1")
11364    (set_attr "length_immediate" "0")
11365    (set_attr "modrm" "0")])
11367 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11368 (define_insn "nops"
11369   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11370                     UNSPECV_NOPS)]
11371   "reload_completed"
11373   int num = INTVAL (operands[0]);
11375   gcc_assert (IN_RANGE (num, 1, 8));
11377   while (num--)
11378     fputs ("\tnop\n", asm_out_file);
11380   return "";
11382   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11383    (set_attr "length_immediate" "0")
11384    (set_attr "modrm" "0")])
11386 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11387 ;; branch prediction penalty for the third jump in a 16-byte
11388 ;; block on K8.
11390 (define_insn "pad"
11391   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11392   ""
11394 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11395   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11396 #else
11397   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11398      The align insn is used to avoid 3 jump instructions in the row to improve
11399      branch prediction and the benefits hardly outweigh the cost of extra 8
11400      nops on the average inserted by full alignment pseudo operation.  */
11401 #endif
11402   return "";
11404   [(set_attr "length" "16")])
11406 (define_expand "prologue"
11407   [(const_int 0)]
11408   ""
11409   "ix86_expand_prologue (); DONE;")
11411 (define_insn "set_got"
11412   [(set (match_operand:SI 0 "register_operand" "=r")
11413         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11414    (clobber (reg:CC FLAGS_REG))]
11415   "!TARGET_64BIT"
11416   "* return output_set_got (operands[0], NULL_RTX);"
11417   [(set_attr "type" "multi")
11418    (set_attr "length" "12")])
11420 (define_insn "set_got_labelled"
11421   [(set (match_operand:SI 0 "register_operand" "=r")
11422         (unspec:SI [(label_ref (match_operand 1))]
11423          UNSPEC_SET_GOT))
11424    (clobber (reg:CC FLAGS_REG))]
11425   "!TARGET_64BIT"
11426   "* return output_set_got (operands[0], operands[1]);"
11427   [(set_attr "type" "multi")
11428    (set_attr "length" "12")])
11430 (define_insn "set_got_rex64"
11431   [(set (match_operand:DI 0 "register_operand" "=r")
11432         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11433   "TARGET_64BIT"
11434   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11435   [(set_attr "type" "lea")
11436    (set_attr "length_address" "4")
11437    (set_attr "mode" "DI")])
11439 (define_insn "set_rip_rex64"
11440   [(set (match_operand:DI 0 "register_operand" "=r")
11441         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11442   "TARGET_64BIT"
11443   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11444   [(set_attr "type" "lea")
11445    (set_attr "length_address" "4")
11446    (set_attr "mode" "DI")])
11448 (define_insn "set_got_offset_rex64"
11449   [(set (match_operand:DI 0 "register_operand" "=r")
11450         (unspec:DI
11451           [(label_ref (match_operand 1))]
11452           UNSPEC_SET_GOT_OFFSET))]
11453   "TARGET_LP64"
11454   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11455   [(set_attr "type" "imov")
11456    (set_attr "length_immediate" "0")
11457    (set_attr "length_address" "8")
11458    (set_attr "mode" "DI")])
11460 (define_expand "epilogue"
11461   [(const_int 0)]
11462   ""
11463   "ix86_expand_epilogue (1); DONE;")
11465 (define_expand "sibcall_epilogue"
11466   [(const_int 0)]
11467   ""
11468   "ix86_expand_epilogue (0); DONE;")
11470 (define_expand "eh_return"
11471   [(use (match_operand 0 "register_operand"))]
11472   ""
11474   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11476   /* Tricky bit: we write the address of the handler to which we will
11477      be returning into someone else's stack frame, one word below the
11478      stack address we wish to restore.  */
11479   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11480   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11481   tmp = gen_rtx_MEM (Pmode, tmp);
11482   emit_move_insn (tmp, ra);
11484   emit_jump_insn (gen_eh_return_internal ());
11485   emit_barrier ();
11486   DONE;
11489 (define_insn_and_split "eh_return_internal"
11490   [(eh_return)]
11491   ""
11492   "#"
11493   "epilogue_completed"
11494   [(const_int 0)]
11495   "ix86_expand_epilogue (2); DONE;")
11497 (define_insn "leave"
11498   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11499    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11500    (clobber (mem:BLK (scratch)))]
11501   "!TARGET_64BIT"
11502   "leave"
11503   [(set_attr "type" "leave")])
11505 (define_insn "leave_rex64"
11506   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11507    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11508    (clobber (mem:BLK (scratch)))]
11509   "TARGET_64BIT"
11510   "leave"
11511   [(set_attr "type" "leave")])
11513 ;; Handle -fsplit-stack.
11515 (define_expand "split_stack_prologue"
11516   [(const_int 0)]
11517   ""
11519   ix86_expand_split_stack_prologue ();
11520   DONE;
11523 ;; In order to support the call/return predictor, we use a return
11524 ;; instruction which the middle-end doesn't see.
11525 (define_insn "split_stack_return"
11526   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11527                      UNSPECV_SPLIT_STACK_RETURN)]
11528   ""
11530   if (operands[0] == const0_rtx)
11531     return "ret";
11532   else
11533     return "ret\t%0";
11535   [(set_attr "atom_unit" "jeu")
11536    (set_attr "modrm" "0")
11537    (set (attr "length")
11538         (if_then_else (match_operand:SI 0 "const0_operand")
11539                       (const_int 1)
11540                       (const_int 3)))
11541    (set (attr "length_immediate")
11542         (if_then_else (match_operand:SI 0 "const0_operand")
11543                       (const_int 0)
11544                       (const_int 2)))])
11546 ;; If there are operand 0 bytes available on the stack, jump to
11547 ;; operand 1.
11549 (define_expand "split_stack_space_check"
11550   [(set (pc) (if_then_else
11551               (ltu (minus (reg SP_REG)
11552                           (match_operand 0 "register_operand"))
11553                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11554               (label_ref (match_operand 1))
11555               (pc)))]
11556   ""
11558   rtx reg, size, limit;
11560   reg = gen_reg_rtx (Pmode);
11561   size = force_reg (Pmode, operands[0]);
11562   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11563   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11564                           UNSPEC_STACK_CHECK);
11565   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11566   ix86_expand_branch (GEU, reg, limit, operands[1]);
11568   DONE;
11571 ;; Bit manipulation instructions.
11573 (define_expand "ffs<mode>2"
11574   [(set (match_dup 2) (const_int -1))
11575    (parallel [(set (match_dup 3) (match_dup 4))
11576               (set (match_operand:SWI48 0 "register_operand")
11577                    (ctz:SWI48
11578                      (match_operand:SWI48 1 "nonimmediate_operand")))])
11579    (set (match_dup 0) (if_then_else:SWI48
11580                         (eq (match_dup 3) (const_int 0))
11581                         (match_dup 2)
11582                         (match_dup 0)))
11583    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11584               (clobber (reg:CC FLAGS_REG))])]
11585   ""
11587   enum machine_mode flags_mode;
11589   if (<MODE>mode == SImode && !TARGET_CMOVE)
11590     {
11591       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11592       DONE;
11593     }
11595   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11597   operands[2] = gen_reg_rtx (<MODE>mode);
11598   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
11599   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11602 (define_insn_and_split "ffssi2_no_cmove"
11603   [(set (match_operand:SI 0 "register_operand" "=r")
11604         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11605    (clobber (match_scratch:SI 2 "=&q"))
11606    (clobber (reg:CC FLAGS_REG))]
11607   "!TARGET_CMOVE"
11608   "#"
11609   "&& reload_completed"
11610   [(parallel [(set (match_dup 4) (match_dup 5))
11611               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11612    (set (strict_low_part (match_dup 3))
11613         (eq:QI (match_dup 4) (const_int 0)))
11614    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11615               (clobber (reg:CC FLAGS_REG))])
11616    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11617               (clobber (reg:CC FLAGS_REG))])
11618    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11619               (clobber (reg:CC FLAGS_REG))])]
11621   enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11623   operands[3] = gen_lowpart (QImode, operands[2]);
11624   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
11625   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11627   ix86_expand_clear (operands[2]);
11630 (define_insn "*tzcnt<mode>_1"
11631   [(set (reg:CCC FLAGS_REG)
11632         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11633                      (const_int 0)))
11634    (set (match_operand:SWI48 0 "register_operand" "=r")
11635         (ctz:SWI48 (match_dup 1)))]
11636   "TARGET_BMI"
11637   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11638   [(set_attr "type" "alu1")
11639    (set_attr "prefix_0f" "1")
11640    (set_attr "prefix_rep" "1")
11641    (set_attr "btver2_decode" "double")
11642    (set_attr "mode" "<MODE>")])
11644 (define_insn "*bsf<mode>_1"
11645   [(set (reg:CCZ FLAGS_REG)
11646         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11647                      (const_int 0)))
11648    (set (match_operand:SWI48 0 "register_operand" "=r")
11649         (ctz:SWI48 (match_dup 1)))]
11650   ""
11651   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11652   [(set_attr "type" "alu1")
11653    (set_attr "prefix_0f" "1")
11654    (set_attr "btver2_decode" "double")
11655    (set_attr "mode" "<MODE>")])
11657 (define_insn "ctz<mode>2"
11658   [(set (match_operand:SWI248 0 "register_operand" "=r")
11659         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11660    (clobber (reg:CC FLAGS_REG))]
11661   ""
11663   if (TARGET_BMI)
11664     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11665   else if (optimize_function_for_size_p (cfun))
11666     ;
11667   else if (TARGET_GENERIC)
11668     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
11669     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11671   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11673   [(set_attr "type" "alu1")
11674    (set_attr "prefix_0f" "1")
11675    (set (attr "prefix_rep")
11676      (if_then_else
11677        (ior (match_test "TARGET_BMI")
11678             (and (not (match_test "optimize_function_for_size_p (cfun)"))
11679                  (match_test "TARGET_GENERIC")))
11680        (const_string "1")
11681        (const_string "0")))
11682    (set_attr "mode" "<MODE>")])
11684 (define_expand "clz<mode>2"
11685   [(parallel
11686      [(set (match_operand:SWI248 0 "register_operand")
11687            (minus:SWI248
11688              (match_dup 2)
11689              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
11690       (clobber (reg:CC FLAGS_REG))])
11691    (parallel
11692      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11693       (clobber (reg:CC FLAGS_REG))])]
11694   ""
11696   if (TARGET_LZCNT)
11697     {
11698       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11699       DONE;
11700     }
11701   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11704 (define_insn "clz<mode>2_lzcnt"
11705   [(set (match_operand:SWI248 0 "register_operand" "=r")
11706         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11707    (clobber (reg:CC FLAGS_REG))]
11708   "TARGET_LZCNT"
11709   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11710   [(set_attr "prefix_rep" "1")
11711    (set_attr "type" "bitmanip")
11712    (set_attr "mode" "<MODE>")])
11714 ;; BMI instructions.
11715 (define_insn "*bmi_andn_<mode>"
11716   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11717         (and:SWI48
11718           (not:SWI48
11719             (match_operand:SWI48 1 "register_operand" "r,r"))
11720             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
11721    (clobber (reg:CC FLAGS_REG))]
11722   "TARGET_BMI"
11723   "andn\t{%2, %1, %0|%0, %1, %2}"
11724   [(set_attr "type" "bitmanip")
11725    (set_attr "btver2_decode" "direct, double")
11726    (set_attr "mode" "<MODE>")])
11728 (define_insn "bmi_bextr_<mode>"
11729   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11730         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
11731                        (match_operand:SWI48 2 "register_operand" "r,r")]
11732                        UNSPEC_BEXTR))
11733    (clobber (reg:CC FLAGS_REG))]
11734   "TARGET_BMI"
11735   "bextr\t{%2, %1, %0|%0, %1, %2}"
11736   [(set_attr "type" "bitmanip")
11737    (set_attr "btver2_decode" "direct, double")
11738    (set_attr "mode" "<MODE>")])
11740 (define_insn "*bmi_blsi_<mode>"
11741   [(set (match_operand:SWI48 0 "register_operand" "=r")
11742         (and:SWI48
11743           (neg:SWI48
11744             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11745           (match_dup 1)))
11746    (clobber (reg:CC FLAGS_REG))]
11747   "TARGET_BMI"
11748   "blsi\t{%1, %0|%0, %1}"
11749   [(set_attr "type" "bitmanip")
11750    (set_attr "btver2_decode" "double")
11751    (set_attr "mode" "<MODE>")])
11753 (define_insn "*bmi_blsmsk_<mode>"
11754   [(set (match_operand:SWI48 0 "register_operand" "=r")
11755         (xor:SWI48
11756           (plus:SWI48
11757             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11758             (const_int -1))
11759           (match_dup 1)))
11760    (clobber (reg:CC FLAGS_REG))]
11761   "TARGET_BMI"
11762   "blsmsk\t{%1, %0|%0, %1}"
11763   [(set_attr "type" "bitmanip")
11764    (set_attr "btver2_decode" "double")
11765    (set_attr "mode" "<MODE>")])
11767 (define_insn "*bmi_blsr_<mode>"
11768   [(set (match_operand:SWI48 0 "register_operand" "=r")
11769         (and:SWI48
11770           (plus:SWI48
11771             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11772             (const_int -1))
11773           (match_dup 1)))
11774    (clobber (reg:CC FLAGS_REG))]
11775    "TARGET_BMI"
11776    "blsr\t{%1, %0|%0, %1}"
11777   [(set_attr "type" "bitmanip")
11778    (set_attr "btver2_decode" "double")
11779    (set_attr "mode" "<MODE>")])
11781 ;; BMI2 instructions.
11782 (define_insn "bmi2_bzhi_<mode>3"
11783   [(set (match_operand:SWI48 0 "register_operand" "=r")
11784         (and:SWI48 (lshiftrt:SWI48 (const_int -1)
11785                                    (match_operand:SWI48 2 "register_operand" "r"))
11786                    (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11787    (clobber (reg:CC FLAGS_REG))]
11788   "TARGET_BMI2"
11789   "bzhi\t{%2, %1, %0|%0, %1, %2}"
11790   [(set_attr "type" "bitmanip")
11791    (set_attr "prefix" "vex")
11792    (set_attr "mode" "<MODE>")])
11794 (define_insn "bmi2_pdep_<mode>3"
11795   [(set (match_operand:SWI48 0 "register_operand" "=r")
11796         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11797                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11798                        UNSPEC_PDEP))]
11799   "TARGET_BMI2"
11800   "pdep\t{%2, %1, %0|%0, %1, %2}"
11801   [(set_attr "type" "bitmanip")
11802    (set_attr "prefix" "vex")
11803    (set_attr "mode" "<MODE>")])
11805 (define_insn "bmi2_pext_<mode>3"
11806   [(set (match_operand:SWI48 0 "register_operand" "=r")
11807         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11808                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11809                        UNSPEC_PEXT))]
11810   "TARGET_BMI2"
11811   "pext\t{%2, %1, %0|%0, %1, %2}"
11812   [(set_attr "type" "bitmanip")
11813    (set_attr "prefix" "vex")
11814    (set_attr "mode" "<MODE>")])
11816 ;; TBM instructions.
11817 (define_insn "tbm_bextri_<mode>"
11818   [(set (match_operand:SWI48 0 "register_operand" "=r")
11819         (zero_extract:SWI48
11820           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11821           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11822           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11823    (clobber (reg:CC FLAGS_REG))]
11824    "TARGET_TBM"
11826   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11827   return "bextr\t{%2, %1, %0|%0, %1, %2}";
11829   [(set_attr "type" "bitmanip")
11830    (set_attr "mode" "<MODE>")])
11832 (define_insn "*tbm_blcfill_<mode>"
11833   [(set (match_operand:SWI48 0 "register_operand" "=r")
11834         (and:SWI48
11835           (plus:SWI48
11836             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11837             (const_int 1))
11838           (match_dup 1)))
11839    (clobber (reg:CC FLAGS_REG))]
11840    "TARGET_TBM"
11841    "blcfill\t{%1, %0|%0, %1}"
11842   [(set_attr "type" "bitmanip")
11843    (set_attr "mode" "<MODE>")])
11845 (define_insn "*tbm_blci_<mode>"
11846   [(set (match_operand:SWI48 0 "register_operand" "=r")
11847         (ior:SWI48
11848           (not:SWI48
11849             (plus:SWI48
11850               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11851               (const_int 1)))
11852           (match_dup 1)))
11853    (clobber (reg:CC FLAGS_REG))]
11854    "TARGET_TBM"
11855    "blci\t{%1, %0|%0, %1}"
11856   [(set_attr "type" "bitmanip")
11857    (set_attr "mode" "<MODE>")])
11859 (define_insn "*tbm_blcic_<mode>"
11860   [(set (match_operand:SWI48 0 "register_operand" "=r")
11861         (and:SWI48
11862           (plus:SWI48
11863             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11864             (const_int 1))
11865           (not:SWI48
11866             (match_dup 1))))
11867    (clobber (reg:CC FLAGS_REG))]
11868    "TARGET_TBM"
11869    "blcic\t{%1, %0|%0, %1}"
11870   [(set_attr "type" "bitmanip")
11871    (set_attr "mode" "<MODE>")])
11873 (define_insn "*tbm_blcmsk_<mode>"
11874   [(set (match_operand:SWI48 0 "register_operand" "=r")
11875         (xor:SWI48
11876           (plus:SWI48
11877             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11878             (const_int 1))
11879           (match_dup 1)))
11880    (clobber (reg:CC FLAGS_REG))]
11881    "TARGET_TBM"
11882    "blcmsk\t{%1, %0|%0, %1}"
11883   [(set_attr "type" "bitmanip")
11884    (set_attr "mode" "<MODE>")])
11886 (define_insn "*tbm_blcs_<mode>"
11887   [(set (match_operand:SWI48 0 "register_operand" "=r")
11888         (ior:SWI48
11889           (plus:SWI48
11890             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11891             (const_int 1))
11892           (match_dup 1)))
11893    (clobber (reg:CC FLAGS_REG))]
11894    "TARGET_TBM"
11895    "blcs\t{%1, %0|%0, %1}"
11896   [(set_attr "type" "bitmanip")
11897    (set_attr "mode" "<MODE>")])
11899 (define_insn "*tbm_blsfill_<mode>"
11900   [(set (match_operand:SWI48 0 "register_operand" "=r")
11901         (ior:SWI48
11902           (plus:SWI48
11903             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11904             (const_int -1))
11905           (match_dup 1)))
11906    (clobber (reg:CC FLAGS_REG))]
11907    "TARGET_TBM"
11908    "blsfill\t{%1, %0|%0, %1}"
11909   [(set_attr "type" "bitmanip")
11910    (set_attr "mode" "<MODE>")])
11912 (define_insn "*tbm_blsic_<mode>"
11913   [(set (match_operand:SWI48 0 "register_operand" "=r")
11914         (ior:SWI48
11915           (plus:SWI48
11916             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11917             (const_int -1))
11918           (not:SWI48
11919             (match_dup 1))))
11920    (clobber (reg:CC FLAGS_REG))]
11921    "TARGET_TBM"
11922    "blsic\t{%1, %0|%0, %1}"
11923   [(set_attr "type" "bitmanip")
11924    (set_attr "mode" "<MODE>")])
11926 (define_insn "*tbm_t1mskc_<mode>"
11927   [(set (match_operand:SWI48 0 "register_operand" "=r")
11928         (ior:SWI48
11929           (plus:SWI48
11930             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11931             (const_int 1))
11932           (not:SWI48
11933             (match_dup 1))))
11934    (clobber (reg:CC FLAGS_REG))]
11935    "TARGET_TBM"
11936    "t1mskc\t{%1, %0|%0, %1}"
11937   [(set_attr "type" "bitmanip")
11938    (set_attr "mode" "<MODE>")])
11940 (define_insn "*tbm_tzmsk_<mode>"
11941   [(set (match_operand:SWI48 0 "register_operand" "=r")
11942         (and:SWI48
11943           (plus:SWI48
11944             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11945             (const_int -1))
11946           (not:SWI48
11947             (match_dup 1))))
11948    (clobber (reg:CC FLAGS_REG))]
11949    "TARGET_TBM"
11950    "tzmsk\t{%1, %0|%0, %1}"
11951   [(set_attr "type" "bitmanip")
11952    (set_attr "mode" "<MODE>")])
11954 (define_insn "bsr_rex64"
11955   [(set (match_operand:DI 0 "register_operand" "=r")
11956         (minus:DI (const_int 63)
11957                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "TARGET_64BIT"
11960   "bsr{q}\t{%1, %0|%0, %1}"
11961   [(set_attr "type" "alu1")
11962    (set_attr "prefix_0f" "1")
11963    (set_attr "mode" "DI")])
11965 (define_insn "bsr"
11966   [(set (match_operand:SI 0 "register_operand" "=r")
11967         (minus:SI (const_int 31)
11968                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11969    (clobber (reg:CC FLAGS_REG))]
11970   ""
11971   "bsr{l}\t{%1, %0|%0, %1}"
11972   [(set_attr "type" "alu1")
11973    (set_attr "prefix_0f" "1")
11974    (set_attr "mode" "SI")])
11976 (define_insn "*bsrhi"
11977   [(set (match_operand:HI 0 "register_operand" "=r")
11978         (minus:HI (const_int 15)
11979                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11980    (clobber (reg:CC FLAGS_REG))]
11981   ""
11982   "bsr{w}\t{%1, %0|%0, %1}"
11983   [(set_attr "type" "alu1")
11984    (set_attr "prefix_0f" "1")
11985    (set_attr "mode" "HI")])
11987 (define_insn "popcount<mode>2"
11988   [(set (match_operand:SWI248 0 "register_operand" "=r")
11989         (popcount:SWI248
11990           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11991    (clobber (reg:CC FLAGS_REG))]
11992   "TARGET_POPCNT"
11994 #if TARGET_MACHO
11995   return "popcnt\t{%1, %0|%0, %1}";
11996 #else
11997   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11998 #endif
12000   [(set_attr "prefix_rep" "1")
12001    (set_attr "type" "bitmanip")
12002    (set_attr "mode" "<MODE>")])
12004 (define_insn "*popcount<mode>2_cmp"
12005   [(set (reg FLAGS_REG)
12006         (compare
12007           (popcount:SWI248
12008             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12009           (const_int 0)))
12010    (set (match_operand:SWI248 0 "register_operand" "=r")
12011         (popcount:SWI248 (match_dup 1)))]
12012   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12014 #if TARGET_MACHO
12015   return "popcnt\t{%1, %0|%0, %1}";
12016 #else
12017   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12018 #endif
12020   [(set_attr "prefix_rep" "1")
12021    (set_attr "type" "bitmanip")
12022    (set_attr "mode" "<MODE>")])
12024 (define_insn "*popcountsi2_cmp_zext"
12025   [(set (reg FLAGS_REG)
12026         (compare
12027           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12028           (const_int 0)))
12029    (set (match_operand:DI 0 "register_operand" "=r")
12030         (zero_extend:DI(popcount:SI (match_dup 1))))]
12031   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12033 #if TARGET_MACHO
12034   return "popcnt\t{%1, %0|%0, %1}";
12035 #else
12036   return "popcnt{l}\t{%1, %0|%0, %1}";
12037 #endif
12039   [(set_attr "prefix_rep" "1")
12040    (set_attr "type" "bitmanip")
12041    (set_attr "mode" "SI")])
12043 (define_expand "bswapdi2"
12044   [(set (match_operand:DI 0 "register_operand")
12045         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12046   "TARGET_64BIT"
12048   if (!TARGET_MOVBE)
12049     operands[1] = force_reg (DImode, operands[1]);
12052 (define_expand "bswapsi2"
12053   [(set (match_operand:SI 0 "register_operand")
12054         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12055   ""
12057   if (TARGET_MOVBE)
12058     ;
12059   else if (TARGET_BSWAP)
12060     operands[1] = force_reg (SImode, operands[1]);
12061   else
12062     {
12063       rtx x = operands[0];
12065       emit_move_insn (x, operands[1]);
12066       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12067       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12068       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12069       DONE;
12070     }
12073 (define_insn "*bswap<mode>2_movbe"
12074   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12075         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12076   "TARGET_MOVBE
12077    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12078   "@
12079     bswap\t%0
12080     movbe\t{%1, %0|%0, %1}
12081     movbe\t{%1, %0|%0, %1}"
12082   [(set_attr "type" "bitmanip,imov,imov")
12083    (set_attr "modrm" "0,1,1")
12084    (set_attr "prefix_0f" "*,1,1")
12085    (set_attr "prefix_extra" "*,1,1")
12086    (set_attr "mode" "<MODE>")])
12088 (define_insn "*bswap<mode>2"
12089   [(set (match_operand:SWI48 0 "register_operand" "=r")
12090         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12091   "TARGET_BSWAP"
12092   "bswap\t%0"
12093   [(set_attr "type" "bitmanip")
12094    (set_attr "modrm" "0")
12095    (set_attr "mode" "<MODE>")])
12097 (define_insn "*bswaphi_lowpart_1"
12098   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12099         (bswap:HI (match_dup 0)))
12100    (clobber (reg:CC FLAGS_REG))]
12101   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12102   "@
12103     xchg{b}\t{%h0, %b0|%b0, %h0}
12104     rol{w}\t{$8, %0|%0, 8}"
12105   [(set_attr "length" "2,4")
12106    (set_attr "mode" "QI,HI")])
12108 (define_insn "bswaphi_lowpart"
12109   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12110         (bswap:HI (match_dup 0)))
12111    (clobber (reg:CC FLAGS_REG))]
12112   ""
12113   "rol{w}\t{$8, %0|%0, 8}"
12114   [(set_attr "length" "4")
12115    (set_attr "mode" "HI")])
12117 (define_expand "paritydi2"
12118   [(set (match_operand:DI 0 "register_operand")
12119         (parity:DI (match_operand:DI 1 "register_operand")))]
12120   "! TARGET_POPCNT"
12122   rtx scratch = gen_reg_rtx (QImode);
12123   rtx cond;
12125   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12126                                 NULL_RTX, operands[1]));
12128   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12129                          gen_rtx_REG (CCmode, FLAGS_REG),
12130                          const0_rtx);
12131   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12133   if (TARGET_64BIT)
12134     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12135   else
12136     {
12137       rtx tmp = gen_reg_rtx (SImode);
12139       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12140       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12141     }
12142   DONE;
12145 (define_expand "paritysi2"
12146   [(set (match_operand:SI 0 "register_operand")
12147         (parity:SI (match_operand:SI 1 "register_operand")))]
12148   "! TARGET_POPCNT"
12150   rtx scratch = gen_reg_rtx (QImode);
12151   rtx cond;
12153   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12155   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12156                          gen_rtx_REG (CCmode, FLAGS_REG),
12157                          const0_rtx);
12158   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12160   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12161   DONE;
12164 (define_insn_and_split "paritydi2_cmp"
12165   [(set (reg:CC FLAGS_REG)
12166         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12167                    UNSPEC_PARITY))
12168    (clobber (match_scratch:DI 0 "=r"))
12169    (clobber (match_scratch:SI 1 "=&r"))
12170    (clobber (match_scratch:HI 2 "=Q"))]
12171   "! TARGET_POPCNT"
12172   "#"
12173   "&& reload_completed"
12174   [(parallel
12175      [(set (match_dup 1)
12176            (xor:SI (match_dup 1) (match_dup 4)))
12177       (clobber (reg:CC FLAGS_REG))])
12178    (parallel
12179      [(set (reg:CC FLAGS_REG)
12180            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12181       (clobber (match_dup 1))
12182       (clobber (match_dup 2))])]
12184   operands[4] = gen_lowpart (SImode, operands[3]);
12186   if (TARGET_64BIT)
12187     {
12188       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12189       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12190     }
12191   else
12192     operands[1] = gen_highpart (SImode, operands[3]);
12195 (define_insn_and_split "paritysi2_cmp"
12196   [(set (reg:CC FLAGS_REG)
12197         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12198                    UNSPEC_PARITY))
12199    (clobber (match_scratch:SI 0 "=r"))
12200    (clobber (match_scratch:HI 1 "=&Q"))]
12201   "! TARGET_POPCNT"
12202   "#"
12203   "&& reload_completed"
12204   [(parallel
12205      [(set (match_dup 1)
12206            (xor:HI (match_dup 1) (match_dup 3)))
12207       (clobber (reg:CC FLAGS_REG))])
12208    (parallel
12209      [(set (reg:CC FLAGS_REG)
12210            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12211       (clobber (match_dup 1))])]
12213   operands[3] = gen_lowpart (HImode, operands[2]);
12215   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12216   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12219 (define_insn "*parityhi2_cmp"
12220   [(set (reg:CC FLAGS_REG)
12221         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12222                    UNSPEC_PARITY))
12223    (clobber (match_scratch:HI 0 "=Q"))]
12224   "! TARGET_POPCNT"
12225   "xor{b}\t{%h0, %b0|%b0, %h0}"
12226   [(set_attr "length" "2")
12227    (set_attr "mode" "HI")])
12230 ;; Thread-local storage patterns for ELF.
12232 ;; Note that these code sequences must appear exactly as shown
12233 ;; in order to allow linker relaxation.
12235 (define_insn "*tls_global_dynamic_32_gnu"
12236   [(set (match_operand:SI 0 "register_operand" "=a")
12237         (unspec:SI
12238          [(match_operand:SI 1 "register_operand" "b")
12239           (match_operand 2 "tls_symbolic_operand")
12240           (match_operand 3 "constant_call_address_operand" "z")]
12241          UNSPEC_TLS_GD))
12242    (clobber (match_scratch:SI 4 "=d"))
12243    (clobber (match_scratch:SI 5 "=c"))
12244    (clobber (reg:CC FLAGS_REG))]
12245   "!TARGET_64BIT && TARGET_GNU_TLS"
12247   output_asm_insn
12248     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12249   if (TARGET_SUN_TLS)
12250 #ifdef HAVE_AS_IX86_TLSGDPLT
12251     return "call\t%a2@tlsgdplt";
12252 #else
12253     return "call\t%p3@plt";
12254 #endif
12255   return "call\t%P3";
12257   [(set_attr "type" "multi")
12258    (set_attr "length" "12")])
12260 (define_expand "tls_global_dynamic_32"
12261   [(parallel
12262     [(set (match_operand:SI 0 "register_operand")
12263           (unspec:SI [(match_operand:SI 2 "register_operand")
12264                       (match_operand 1 "tls_symbolic_operand")
12265                       (match_operand 3 "constant_call_address_operand")]
12266                      UNSPEC_TLS_GD))
12267      (clobber (match_scratch:SI 4))
12268      (clobber (match_scratch:SI 5))
12269      (clobber (reg:CC FLAGS_REG))])])
12271 (define_insn "*tls_global_dynamic_64_<mode>"
12272   [(set (match_operand:P 0 "register_operand" "=a")
12273         (call:P
12274          (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12275          (match_operand 3)))
12276    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12277              UNSPEC_TLS_GD)]
12278   "TARGET_64BIT"
12280   if (!TARGET_X32)
12281     fputs (ASM_BYTE "0x66\n", asm_out_file);
12282   output_asm_insn
12283     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12284   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12285   fputs ("\trex64\n", asm_out_file);
12286   if (TARGET_SUN_TLS)
12287     return "call\t%p2@plt";
12288   return "call\t%P2";
12290   [(set_attr "type" "multi")
12291    (set (attr "length")
12292         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12294 (define_expand "tls_global_dynamic_64_<mode>"
12295   [(parallel
12296     [(set (match_operand:P 0 "register_operand")
12297           (call:P
12298            (mem:QI (match_operand 2 "constant_call_address_operand"))
12299            (const_int 0)))
12300      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12301                UNSPEC_TLS_GD)])]
12302   "TARGET_64BIT")
12304 (define_insn "*tls_local_dynamic_base_32_gnu"
12305   [(set (match_operand:SI 0 "register_operand" "=a")
12306         (unspec:SI
12307          [(match_operand:SI 1 "register_operand" "b")
12308           (match_operand 2 "constant_call_address_operand" "z")]
12309          UNSPEC_TLS_LD_BASE))
12310    (clobber (match_scratch:SI 3 "=d"))
12311    (clobber (match_scratch:SI 4 "=c"))
12312    (clobber (reg:CC FLAGS_REG))]
12313   "!TARGET_64BIT && TARGET_GNU_TLS"
12315   output_asm_insn
12316     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12317   if (TARGET_SUN_TLS)
12318 #ifdef HAVE_AS_IX86_TLSLDMPLT
12319     return "call\t%&@tlsldmplt";
12320 #else
12321     return "call\t%p2@plt";
12322 #endif
12323   return "call\t%P2";
12325   [(set_attr "type" "multi")
12326    (set_attr "length" "11")])
12328 (define_expand "tls_local_dynamic_base_32"
12329   [(parallel
12330      [(set (match_operand:SI 0 "register_operand")
12331            (unspec:SI
12332             [(match_operand:SI 1 "register_operand")
12333              (match_operand 2 "constant_call_address_operand")]
12334             UNSPEC_TLS_LD_BASE))
12335       (clobber (match_scratch:SI 3))
12336       (clobber (match_scratch:SI 4))
12337       (clobber (reg:CC FLAGS_REG))])])
12339 (define_insn "*tls_local_dynamic_base_64_<mode>"
12340   [(set (match_operand:P 0 "register_operand" "=a")
12341         (call:P
12342          (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12343          (match_operand 2)))
12344    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12345   "TARGET_64BIT"
12347   output_asm_insn
12348     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12349   if (TARGET_SUN_TLS)
12350     return "call\t%p1@plt";
12351   return "call\t%P1";
12353   [(set_attr "type" "multi")
12354    (set_attr "length" "12")])
12356 (define_expand "tls_local_dynamic_base_64_<mode>"
12357   [(parallel
12358      [(set (match_operand:P 0 "register_operand")
12359            (call:P
12360             (mem:QI (match_operand 1 "constant_call_address_operand"))
12361             (const_int 0)))
12362       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12363   "TARGET_64BIT")
12365 ;; Local dynamic of a single variable is a lose.  Show combine how
12366 ;; to convert that back to global dynamic.
12368 (define_insn_and_split "*tls_local_dynamic_32_once"
12369   [(set (match_operand:SI 0 "register_operand" "=a")
12370         (plus:SI
12371          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12372                      (match_operand 2 "constant_call_address_operand" "z")]
12373                     UNSPEC_TLS_LD_BASE)
12374          (const:SI (unspec:SI
12375                     [(match_operand 3 "tls_symbolic_operand")]
12376                     UNSPEC_DTPOFF))))
12377    (clobber (match_scratch:SI 4 "=d"))
12378    (clobber (match_scratch:SI 5 "=c"))
12379    (clobber (reg:CC FLAGS_REG))]
12380   ""
12381   "#"
12382   ""
12383   [(parallel
12384      [(set (match_dup 0)
12385            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12386                       UNSPEC_TLS_GD))
12387       (clobber (match_dup 4))
12388       (clobber (match_dup 5))
12389       (clobber (reg:CC FLAGS_REG))])])
12391 ;; Segment register for the thread base ptr load
12392 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12394 ;; Load and add the thread base pointer from %<tp_seg>:0.
12395 (define_insn "*load_tp_x32"
12396   [(set (match_operand:SI 0 "register_operand" "=r")
12397         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12398   "TARGET_X32"
12399   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12400   [(set_attr "type" "imov")
12401    (set_attr "modrm" "0")
12402    (set_attr "length" "7")
12403    (set_attr "memory" "load")
12404    (set_attr "imm_disp" "false")])
12406 (define_insn "*load_tp_x32_zext"
12407   [(set (match_operand:DI 0 "register_operand" "=r")
12408         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12409   "TARGET_X32"
12410   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12411   [(set_attr "type" "imov")
12412    (set_attr "modrm" "0")
12413    (set_attr "length" "7")
12414    (set_attr "memory" "load")
12415    (set_attr "imm_disp" "false")])
12417 (define_insn "*load_tp_<mode>"
12418   [(set (match_operand:P 0 "register_operand" "=r")
12419         (unspec:P [(const_int 0)] UNSPEC_TP))]
12420   "!TARGET_X32"
12421   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12422   [(set_attr "type" "imov")
12423    (set_attr "modrm" "0")
12424    (set_attr "length" "7")
12425    (set_attr "memory" "load")
12426    (set_attr "imm_disp" "false")])
12428 (define_insn "*add_tp_x32"
12429   [(set (match_operand:SI 0 "register_operand" "=r")
12430         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12431                  (match_operand:SI 1 "register_operand" "0")))
12432    (clobber (reg:CC FLAGS_REG))]
12433   "TARGET_X32"
12434   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12435   [(set_attr "type" "alu")
12436    (set_attr "modrm" "0")
12437    (set_attr "length" "7")
12438    (set_attr "memory" "load")
12439    (set_attr "imm_disp" "false")])
12441 (define_insn "*add_tp_x32_zext"
12442   [(set (match_operand:DI 0 "register_operand" "=r")
12443         (zero_extend:DI
12444           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12445                    (match_operand:SI 1 "register_operand" "0"))))
12446    (clobber (reg:CC FLAGS_REG))]
12447   "TARGET_X32"
12448   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12449   [(set_attr "type" "alu")
12450    (set_attr "modrm" "0")
12451    (set_attr "length" "7")
12452    (set_attr "memory" "load")
12453    (set_attr "imm_disp" "false")])
12455 (define_insn "*add_tp_<mode>"
12456   [(set (match_operand:P 0 "register_operand" "=r")
12457         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12458                 (match_operand:P 1 "register_operand" "0")))
12459    (clobber (reg:CC FLAGS_REG))]
12460   "!TARGET_X32"
12461   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12462   [(set_attr "type" "alu")
12463    (set_attr "modrm" "0")
12464    (set_attr "length" "7")
12465    (set_attr "memory" "load")
12466    (set_attr "imm_disp" "false")])
12468 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12469 ;; %rax as destination of the initial executable code sequence.
12470 (define_insn "tls_initial_exec_64_sun"
12471   [(set (match_operand:DI 0 "register_operand" "=a")
12472         (unspec:DI
12473          [(match_operand 1 "tls_symbolic_operand")]
12474          UNSPEC_TLS_IE_SUN))
12475    (clobber (reg:CC FLAGS_REG))]
12476   "TARGET_64BIT && TARGET_SUN_TLS"
12478   output_asm_insn
12479     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12480   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12482   [(set_attr "type" "multi")])
12484 ;; GNU2 TLS patterns can be split.
12486 (define_expand "tls_dynamic_gnu2_32"
12487   [(set (match_dup 3)
12488         (plus:SI (match_operand:SI 2 "register_operand")
12489                  (const:SI
12490                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12491                              UNSPEC_TLSDESC))))
12492    (parallel
12493     [(set (match_operand:SI 0 "register_operand")
12494           (unspec:SI [(match_dup 1) (match_dup 3)
12495                       (match_dup 2) (reg:SI SP_REG)]
12496                       UNSPEC_TLSDESC))
12497      (clobber (reg:CC FLAGS_REG))])]
12498   "!TARGET_64BIT && TARGET_GNU2_TLS"
12500   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12501   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12504 (define_insn "*tls_dynamic_gnu2_lea_32"
12505   [(set (match_operand:SI 0 "register_operand" "=r")
12506         (plus:SI (match_operand:SI 1 "register_operand" "b")
12507                  (const:SI
12508                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12509                               UNSPEC_TLSDESC))))]
12510   "!TARGET_64BIT && TARGET_GNU2_TLS"
12511   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12512   [(set_attr "type" "lea")
12513    (set_attr "mode" "SI")
12514    (set_attr "length" "6")
12515    (set_attr "length_address" "4")])
12517 (define_insn "*tls_dynamic_gnu2_call_32"
12518   [(set (match_operand:SI 0 "register_operand" "=a")
12519         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12520                     (match_operand:SI 2 "register_operand" "0")
12521                     ;; we have to make sure %ebx still points to the GOT
12522                     (match_operand:SI 3 "register_operand" "b")
12523                     (reg:SI SP_REG)]
12524                    UNSPEC_TLSDESC))
12525    (clobber (reg:CC FLAGS_REG))]
12526   "!TARGET_64BIT && TARGET_GNU2_TLS"
12527   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12528   [(set_attr "type" "call")
12529    (set_attr "length" "2")
12530    (set_attr "length_address" "0")])
12532 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12533   [(set (match_operand:SI 0 "register_operand" "=&a")
12534         (plus:SI
12535          (unspec:SI [(match_operand 3 "tls_modbase_operand")
12536                      (match_operand:SI 4)
12537                      (match_operand:SI 2 "register_operand" "b")
12538                      (reg:SI SP_REG)]
12539                     UNSPEC_TLSDESC)
12540          (const:SI (unspec:SI
12541                     [(match_operand 1 "tls_symbolic_operand")]
12542                     UNSPEC_DTPOFF))))
12543    (clobber (reg:CC FLAGS_REG))]
12544   "!TARGET_64BIT && TARGET_GNU2_TLS"
12545   "#"
12546   ""
12547   [(set (match_dup 0) (match_dup 5))]
12549   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12550   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12553 (define_expand "tls_dynamic_gnu2_64"
12554   [(set (match_dup 2)
12555         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12556                    UNSPEC_TLSDESC))
12557    (parallel
12558     [(set (match_operand:DI 0 "register_operand")
12559           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12560                      UNSPEC_TLSDESC))
12561      (clobber (reg:CC FLAGS_REG))])]
12562   "TARGET_64BIT && TARGET_GNU2_TLS"
12564   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12565   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12568 (define_insn "*tls_dynamic_gnu2_lea_64"
12569   [(set (match_operand:DI 0 "register_operand" "=r")
12570         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12571                    UNSPEC_TLSDESC))]
12572   "TARGET_64BIT && TARGET_GNU2_TLS"
12573   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12574   [(set_attr "type" "lea")
12575    (set_attr "mode" "DI")
12576    (set_attr "length" "7")
12577    (set_attr "length_address" "4")])
12579 (define_insn "*tls_dynamic_gnu2_call_64"
12580   [(set (match_operand:DI 0 "register_operand" "=a")
12581         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12582                     (match_operand:DI 2 "register_operand" "0")
12583                     (reg:DI SP_REG)]
12584                    UNSPEC_TLSDESC))
12585    (clobber (reg:CC FLAGS_REG))]
12586   "TARGET_64BIT && TARGET_GNU2_TLS"
12587   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12588   [(set_attr "type" "call")
12589    (set_attr "length" "2")
12590    (set_attr "length_address" "0")])
12592 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12593   [(set (match_operand:DI 0 "register_operand" "=&a")
12594         (plus:DI
12595          (unspec:DI [(match_operand 2 "tls_modbase_operand")
12596                      (match_operand:DI 3)
12597                      (reg:DI SP_REG)]
12598                     UNSPEC_TLSDESC)
12599          (const:DI (unspec:DI
12600                     [(match_operand 1 "tls_symbolic_operand")]
12601                     UNSPEC_DTPOFF))))
12602    (clobber (reg:CC FLAGS_REG))]
12603   "TARGET_64BIT && TARGET_GNU2_TLS"
12604   "#"
12605   ""
12606   [(set (match_dup 0) (match_dup 4))]
12608   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12609   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12612 ;; These patterns match the binary 387 instructions for addM3, subM3,
12613 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12614 ;; SFmode.  The first is the normal insn, the second the same insn but
12615 ;; with one operand a conversion, and the third the same insn but with
12616 ;; the other operand a conversion.  The conversion may be SFmode or
12617 ;; SImode if the target mode DFmode, but only SImode if the target mode
12618 ;; is SFmode.
12620 ;; Gcc is slightly more smart about handling normal two address instructions
12621 ;; so use special patterns for add and mull.
12623 (define_insn "*fop_<mode>_comm_mixed"
12624   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12625         (match_operator:MODEF 3 "binary_fp_operator"
12626           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12627            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12628   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12629    && COMMUTATIVE_ARITH_P (operands[3])
12630    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12631   "* return output_387_binary_op (insn, operands);"
12632   [(set (attr "type")
12633         (if_then_else (eq_attr "alternative" "1,2")
12634            (if_then_else (match_operand:MODEF 3 "mult_operator")
12635               (const_string "ssemul")
12636               (const_string "sseadd"))
12637            (if_then_else (match_operand:MODEF 3 "mult_operator")
12638               (const_string "fmul")
12639               (const_string "fop"))))
12640    (set_attr "isa" "*,noavx,avx")
12641    (set_attr "prefix" "orig,orig,vex")
12642    (set_attr "mode" "<MODE>")])
12644 (define_insn "*fop_<mode>_comm_sse"
12645   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12646         (match_operator:MODEF 3 "binary_fp_operator"
12647           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12648            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12649   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12650    && COMMUTATIVE_ARITH_P (operands[3])
12651    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12652   "* return output_387_binary_op (insn, operands);"
12653   [(set (attr "type")
12654         (if_then_else (match_operand:MODEF 3 "mult_operator")
12655            (const_string "ssemul")
12656            (const_string "sseadd")))
12657    (set_attr "isa" "noavx,avx")
12658    (set_attr "prefix" "orig,vex")
12659    (set_attr "mode" "<MODE>")])
12661 (define_insn "*fop_<mode>_comm_i387"
12662   [(set (match_operand:MODEF 0 "register_operand" "=f")
12663         (match_operator:MODEF 3 "binary_fp_operator"
12664           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12665            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12666   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12667    && COMMUTATIVE_ARITH_P (operands[3])
12668    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12669   "* return output_387_binary_op (insn, operands);"
12670   [(set (attr "type")
12671         (if_then_else (match_operand:MODEF 3 "mult_operator")
12672            (const_string "fmul")
12673            (const_string "fop")))
12674    (set_attr "mode" "<MODE>")])
12676 (define_insn "*fop_<mode>_1_mixed"
12677   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12678         (match_operator:MODEF 3 "binary_fp_operator"
12679           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12680            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12681   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12682    && !COMMUTATIVE_ARITH_P (operands[3])
12683    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12684   "* return output_387_binary_op (insn, operands);"
12685   [(set (attr "type")
12686         (cond [(and (eq_attr "alternative" "2,3")
12687                     (match_operand:MODEF 3 "mult_operator"))
12688                  (const_string "ssemul")
12689                (and (eq_attr "alternative" "2,3")
12690                     (match_operand:MODEF 3 "div_operator"))
12691                  (const_string "ssediv")
12692                (eq_attr "alternative" "2,3")
12693                  (const_string "sseadd")
12694                (match_operand:MODEF 3 "mult_operator")
12695                  (const_string "fmul")
12696                (match_operand:MODEF 3 "div_operator")
12697                  (const_string "fdiv")
12698               ]
12699               (const_string "fop")))
12700    (set_attr "isa" "*,*,noavx,avx")
12701    (set_attr "prefix" "orig,orig,orig,vex")
12702    (set_attr "mode" "<MODE>")])
12704 (define_insn "*rcpsf2_sse"
12705   [(set (match_operand:SF 0 "register_operand" "=x")
12706         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12707                    UNSPEC_RCP))]
12708   "TARGET_SSE_MATH"
12709   "%vrcpss\t{%1, %d0|%d0, %1}"
12710   [(set_attr "type" "sse")
12711    (set_attr "atom_sse_attr" "rcp")
12712    (set_attr "btver2_sse_attr" "rcp")
12713    (set_attr "prefix" "maybe_vex")
12714    (set_attr "mode" "SF")])
12716 (define_insn "*fop_<mode>_1_sse"
12717   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12718         (match_operator:MODEF 3 "binary_fp_operator"
12719           [(match_operand:MODEF 1 "register_operand" "0,x")
12720            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12721   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12722    && !COMMUTATIVE_ARITH_P (operands[3])"
12723   "* return output_387_binary_op (insn, operands);"
12724   [(set (attr "type")
12725         (cond [(match_operand:MODEF 3 "mult_operator")
12726                  (const_string "ssemul")
12727                (match_operand:MODEF 3 "div_operator")
12728                  (const_string "ssediv")
12729               ]
12730               (const_string "sseadd")))
12731    (set_attr "isa" "noavx,avx")
12732    (set_attr "prefix" "orig,vex")
12733    (set_attr "mode" "<MODE>")])
12735 ;; This pattern is not fully shadowed by the pattern above.
12736 (define_insn "*fop_<mode>_1_i387"
12737   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12738         (match_operator:MODEF 3 "binary_fp_operator"
12739           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12740            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12741   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12742    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12743    && !COMMUTATIVE_ARITH_P (operands[3])
12744    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12745   "* return output_387_binary_op (insn, operands);"
12746   [(set (attr "type")
12747         (cond [(match_operand:MODEF 3 "mult_operator")
12748                  (const_string "fmul")
12749                (match_operand:MODEF 3 "div_operator")
12750                  (const_string "fdiv")
12751               ]
12752               (const_string "fop")))
12753    (set_attr "mode" "<MODE>")])
12755 ;; ??? Add SSE splitters for these!
12756 (define_insn "*fop_<MODEF:mode>_2_i387"
12757   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12758         (match_operator:MODEF 3 "binary_fp_operator"
12759           [(float:MODEF
12760              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12761            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12762   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12763    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12764    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12765   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12766   [(set (attr "type")
12767         (cond [(match_operand:MODEF 3 "mult_operator")
12768                  (const_string "fmul")
12769                (match_operand:MODEF 3 "div_operator")
12770                  (const_string "fdiv")
12771               ]
12772               (const_string "fop")))
12773    (set_attr "fp_int_src" "true")
12774    (set_attr "mode" "<SWI24:MODE>")])
12776 (define_insn "*fop_<MODEF:mode>_3_i387"
12777   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12778         (match_operator:MODEF 3 "binary_fp_operator"
12779           [(match_operand:MODEF 1 "register_operand" "0,0")
12780            (float:MODEF
12781              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12782   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12783    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12784    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12785   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12786   [(set (attr "type")
12787         (cond [(match_operand:MODEF 3 "mult_operator")
12788                  (const_string "fmul")
12789                (match_operand:MODEF 3 "div_operator")
12790                  (const_string "fdiv")
12791               ]
12792               (const_string "fop")))
12793    (set_attr "fp_int_src" "true")
12794    (set_attr "mode" "<MODE>")])
12796 (define_insn "*fop_df_4_i387"
12797   [(set (match_operand:DF 0 "register_operand" "=f,f")
12798         (match_operator:DF 3 "binary_fp_operator"
12799            [(float_extend:DF
12800              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12801             (match_operand:DF 2 "register_operand" "0,f")]))]
12802   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12803    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12804    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12805   "* return output_387_binary_op (insn, operands);"
12806   [(set (attr "type")
12807         (cond [(match_operand:DF 3 "mult_operator")
12808                  (const_string "fmul")
12809                (match_operand:DF 3 "div_operator")
12810                  (const_string "fdiv")
12811               ]
12812               (const_string "fop")))
12813    (set_attr "mode" "SF")])
12815 (define_insn "*fop_df_5_i387"
12816   [(set (match_operand:DF 0 "register_operand" "=f,f")
12817         (match_operator:DF 3 "binary_fp_operator"
12818           [(match_operand:DF 1 "register_operand" "0,f")
12819            (float_extend:DF
12820             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12821   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12822    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12823   "* return output_387_binary_op (insn, operands);"
12824   [(set (attr "type")
12825         (cond [(match_operand:DF 3 "mult_operator")
12826                  (const_string "fmul")
12827                (match_operand:DF 3 "div_operator")
12828                  (const_string "fdiv")
12829               ]
12830               (const_string "fop")))
12831    (set_attr "mode" "SF")])
12833 (define_insn "*fop_df_6_i387"
12834   [(set (match_operand:DF 0 "register_operand" "=f,f")
12835         (match_operator:DF 3 "binary_fp_operator"
12836           [(float_extend:DF
12837             (match_operand:SF 1 "register_operand" "0,f"))
12838            (float_extend:DF
12839             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12840   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12841    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12842   "* return output_387_binary_op (insn, operands);"
12843   [(set (attr "type")
12844         (cond [(match_operand:DF 3 "mult_operator")
12845                  (const_string "fmul")
12846                (match_operand:DF 3 "div_operator")
12847                  (const_string "fdiv")
12848               ]
12849               (const_string "fop")))
12850    (set_attr "mode" "SF")])
12852 (define_insn "*fop_xf_comm_i387"
12853   [(set (match_operand:XF 0 "register_operand" "=f")
12854         (match_operator:XF 3 "binary_fp_operator"
12855                         [(match_operand:XF 1 "register_operand" "%0")
12856                          (match_operand:XF 2 "register_operand" "f")]))]
12857   "TARGET_80387
12858    && COMMUTATIVE_ARITH_P (operands[3])"
12859   "* return output_387_binary_op (insn, operands);"
12860   [(set (attr "type")
12861         (if_then_else (match_operand:XF 3 "mult_operator")
12862            (const_string "fmul")
12863            (const_string "fop")))
12864    (set_attr "mode" "XF")])
12866 (define_insn "*fop_xf_1_i387"
12867   [(set (match_operand:XF 0 "register_operand" "=f,f")
12868         (match_operator:XF 3 "binary_fp_operator"
12869                         [(match_operand:XF 1 "register_operand" "0,f")
12870                          (match_operand:XF 2 "register_operand" "f,0")]))]
12871   "TARGET_80387
12872    && !COMMUTATIVE_ARITH_P (operands[3])"
12873   "* return output_387_binary_op (insn, operands);"
12874   [(set (attr "type")
12875         (cond [(match_operand:XF 3 "mult_operator")
12876                  (const_string "fmul")
12877                (match_operand:XF 3 "div_operator")
12878                  (const_string "fdiv")
12879               ]
12880               (const_string "fop")))
12881    (set_attr "mode" "XF")])
12883 (define_insn "*fop_xf_2_i387"
12884   [(set (match_operand:XF 0 "register_operand" "=f,f")
12885         (match_operator:XF 3 "binary_fp_operator"
12886           [(float:XF
12887              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12888            (match_operand:XF 2 "register_operand" "0,0")]))]
12889   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12890   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12891   [(set (attr "type")
12892         (cond [(match_operand:XF 3 "mult_operator")
12893                  (const_string "fmul")
12894                (match_operand:XF 3 "div_operator")
12895                  (const_string "fdiv")
12896               ]
12897               (const_string "fop")))
12898    (set_attr "fp_int_src" "true")
12899    (set_attr "mode" "<MODE>")])
12901 (define_insn "*fop_xf_3_i387"
12902   [(set (match_operand:XF 0 "register_operand" "=f,f")
12903         (match_operator:XF 3 "binary_fp_operator"
12904           [(match_operand:XF 1 "register_operand" "0,0")
12905            (float:XF
12906              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12907   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12908   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12909   [(set (attr "type")
12910         (cond [(match_operand:XF 3 "mult_operator")
12911                  (const_string "fmul")
12912                (match_operand:XF 3 "div_operator")
12913                  (const_string "fdiv")
12914               ]
12915               (const_string "fop")))
12916    (set_attr "fp_int_src" "true")
12917    (set_attr "mode" "<MODE>")])
12919 (define_insn "*fop_xf_4_i387"
12920   [(set (match_operand:XF 0 "register_operand" "=f,f")
12921         (match_operator:XF 3 "binary_fp_operator"
12922            [(float_extend:XF
12923               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12924             (match_operand:XF 2 "register_operand" "0,f")]))]
12925   "TARGET_80387"
12926   "* return output_387_binary_op (insn, operands);"
12927   [(set (attr "type")
12928         (cond [(match_operand:XF 3 "mult_operator")
12929                  (const_string "fmul")
12930                (match_operand:XF 3 "div_operator")
12931                  (const_string "fdiv")
12932               ]
12933               (const_string "fop")))
12934    (set_attr "mode" "<MODE>")])
12936 (define_insn "*fop_xf_5_i387"
12937   [(set (match_operand:XF 0 "register_operand" "=f,f")
12938         (match_operator:XF 3 "binary_fp_operator"
12939           [(match_operand:XF 1 "register_operand" "0,f")
12940            (float_extend:XF
12941              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12942   "TARGET_80387"
12943   "* return output_387_binary_op (insn, operands);"
12944   [(set (attr "type")
12945         (cond [(match_operand:XF 3 "mult_operator")
12946                  (const_string "fmul")
12947                (match_operand:XF 3 "div_operator")
12948                  (const_string "fdiv")
12949               ]
12950               (const_string "fop")))
12951    (set_attr "mode" "<MODE>")])
12953 (define_insn "*fop_xf_6_i387"
12954   [(set (match_operand:XF 0 "register_operand" "=f,f")
12955         (match_operator:XF 3 "binary_fp_operator"
12956           [(float_extend:XF
12957              (match_operand:MODEF 1 "register_operand" "0,f"))
12958            (float_extend:XF
12959              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12960   "TARGET_80387"
12961   "* return output_387_binary_op (insn, operands);"
12962   [(set (attr "type")
12963         (cond [(match_operand:XF 3 "mult_operator")
12964                  (const_string "fmul")
12965                (match_operand:XF 3 "div_operator")
12966                  (const_string "fdiv")
12967               ]
12968               (const_string "fop")))
12969    (set_attr "mode" "<MODE>")])
12971 (define_split
12972   [(set (match_operand 0 "register_operand")
12973         (match_operator 3 "binary_fp_operator"
12974            [(float (match_operand:SWI24 1 "register_operand"))
12975             (match_operand 2 "register_operand")]))]
12976   "reload_completed
12977    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12978    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12979   [(const_int 0)]
12981   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12982   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12983   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12984                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12985                                           GET_MODE (operands[3]),
12986                                           operands[4],
12987                                           operands[2])));
12988   ix86_free_from_memory (GET_MODE (operands[1]));
12989   DONE;
12992 (define_split
12993   [(set (match_operand 0 "register_operand")
12994         (match_operator 3 "binary_fp_operator"
12995            [(match_operand 1 "register_operand")
12996             (float (match_operand:SWI24 2 "register_operand"))]))]
12997   "reload_completed
12998    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12999    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13000   [(const_int 0)]
13002   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13003   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13004   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13005                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13006                                           GET_MODE (operands[3]),
13007                                           operands[1],
13008                                           operands[4])));
13009   ix86_free_from_memory (GET_MODE (operands[2]));
13010   DONE;
13013 ;; FPU special functions.
13015 ;; This pattern implements a no-op XFmode truncation for
13016 ;; all fancy i386 XFmode math functions.
13018 (define_insn "truncxf<mode>2_i387_noop_unspec"
13019   [(set (match_operand:MODEF 0 "register_operand" "=f")
13020         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13021         UNSPEC_TRUNC_NOOP))]
13022   "TARGET_USE_FANCY_MATH_387"
13023   "* return output_387_reg_move (insn, operands);"
13024   [(set_attr "type" "fmov")
13025    (set_attr "mode" "<MODE>")])
13027 (define_insn "sqrtxf2"
13028   [(set (match_operand:XF 0 "register_operand" "=f")
13029         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13030   "TARGET_USE_FANCY_MATH_387"
13031   "fsqrt"
13032   [(set_attr "type" "fpspc")
13033    (set_attr "mode" "XF")
13034    (set_attr "athlon_decode" "direct")
13035    (set_attr "amdfam10_decode" "direct")
13036    (set_attr "bdver1_decode" "direct")])
13038 (define_insn "sqrt_extend<mode>xf2_i387"
13039   [(set (match_operand:XF 0 "register_operand" "=f")
13040         (sqrt:XF
13041           (float_extend:XF
13042             (match_operand:MODEF 1 "register_operand" "0"))))]
13043   "TARGET_USE_FANCY_MATH_387"
13044   "fsqrt"
13045   [(set_attr "type" "fpspc")
13046    (set_attr "mode" "XF")
13047    (set_attr "athlon_decode" "direct")
13048    (set_attr "amdfam10_decode" "direct")
13049    (set_attr "bdver1_decode" "direct")])
13051 (define_insn "*rsqrtsf2_sse"
13052   [(set (match_operand:SF 0 "register_operand" "=x")
13053         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13054                    UNSPEC_RSQRT))]
13055   "TARGET_SSE_MATH"
13056   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13057   [(set_attr "type" "sse")
13058    (set_attr "atom_sse_attr" "rcp")
13059    (set_attr "btver2_sse_attr" "rcp")
13060    (set_attr "prefix" "maybe_vex")
13061    (set_attr "mode" "SF")])
13063 (define_expand "rsqrtsf2"
13064   [(set (match_operand:SF 0 "register_operand")
13065         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13066                    UNSPEC_RSQRT))]
13067   "TARGET_SSE_MATH"
13069   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13070   DONE;
13073 (define_insn "*sqrt<mode>2_sse"
13074   [(set (match_operand:MODEF 0 "register_operand" "=x")
13075         (sqrt:MODEF
13076           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13077   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13078   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13079   [(set_attr "type" "sse")
13080    (set_attr "atom_sse_attr" "sqrt")
13081    (set_attr "btver2_sse_attr" "sqrt")
13082    (set_attr "prefix" "maybe_vex")
13083    (set_attr "mode" "<MODE>")
13084    (set_attr "athlon_decode" "*")
13085    (set_attr "amdfam10_decode" "*")
13086    (set_attr "bdver1_decode" "*")])
13088 (define_expand "sqrt<mode>2"
13089   [(set (match_operand:MODEF 0 "register_operand")
13090         (sqrt:MODEF
13091           (match_operand:MODEF 1 "nonimmediate_operand")))]
13092   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13093    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13095   if (<MODE>mode == SFmode
13096       && TARGET_SSE_MATH
13097       && TARGET_RECIP_SQRT
13098       && !optimize_function_for_size_p (cfun)
13099       && flag_finite_math_only && !flag_trapping_math
13100       && flag_unsafe_math_optimizations)
13101     {
13102       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13103       DONE;
13104     }
13106   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13107     {
13108       rtx op0 = gen_reg_rtx (XFmode);
13109       rtx op1 = force_reg (<MODE>mode, operands[1]);
13111       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13112       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13113       DONE;
13114    }
13117 (define_insn "fpremxf4_i387"
13118   [(set (match_operand:XF 0 "register_operand" "=f")
13119         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13120                     (match_operand:XF 3 "register_operand" "1")]
13121                    UNSPEC_FPREM_F))
13122    (set (match_operand:XF 1 "register_operand" "=u")
13123         (unspec:XF [(match_dup 2) (match_dup 3)]
13124                    UNSPEC_FPREM_U))
13125    (set (reg:CCFP FPSR_REG)
13126         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13127                      UNSPEC_C2_FLAG))]
13128   "TARGET_USE_FANCY_MATH_387"
13129   "fprem"
13130   [(set_attr "type" "fpspc")
13131    (set_attr "mode" "XF")])
13133 (define_expand "fmodxf3"
13134   [(use (match_operand:XF 0 "register_operand"))
13135    (use (match_operand:XF 1 "general_operand"))
13136    (use (match_operand:XF 2 "general_operand"))]
13137   "TARGET_USE_FANCY_MATH_387"
13139   rtx label = gen_label_rtx ();
13141   rtx op1 = gen_reg_rtx (XFmode);
13142   rtx op2 = gen_reg_rtx (XFmode);
13144   emit_move_insn (op2, operands[2]);
13145   emit_move_insn (op1, operands[1]);
13147   emit_label (label);
13148   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13149   ix86_emit_fp_unordered_jump (label);
13150   LABEL_NUSES (label) = 1;
13152   emit_move_insn (operands[0], op1);
13153   DONE;
13156 (define_expand "fmod<mode>3"
13157   [(use (match_operand:MODEF 0 "register_operand"))
13158    (use (match_operand:MODEF 1 "general_operand"))
13159    (use (match_operand:MODEF 2 "general_operand"))]
13160   "TARGET_USE_FANCY_MATH_387"
13162   rtx (*gen_truncxf) (rtx, rtx);
13164   rtx label = gen_label_rtx ();
13166   rtx op1 = gen_reg_rtx (XFmode);
13167   rtx op2 = gen_reg_rtx (XFmode);
13169   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13170   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13172   emit_label (label);
13173   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13174   ix86_emit_fp_unordered_jump (label);
13175   LABEL_NUSES (label) = 1;
13177   /* Truncate the result properly for strict SSE math.  */
13178   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13179       && !TARGET_MIX_SSE_I387)
13180     gen_truncxf = gen_truncxf<mode>2;
13181   else
13182     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13184   emit_insn (gen_truncxf (operands[0], op1));
13185   DONE;
13188 (define_insn "fprem1xf4_i387"
13189   [(set (match_operand:XF 0 "register_operand" "=f")
13190         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13191                     (match_operand:XF 3 "register_operand" "1")]
13192                    UNSPEC_FPREM1_F))
13193    (set (match_operand:XF 1 "register_operand" "=u")
13194         (unspec:XF [(match_dup 2) (match_dup 3)]
13195                    UNSPEC_FPREM1_U))
13196    (set (reg:CCFP FPSR_REG)
13197         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13198                      UNSPEC_C2_FLAG))]
13199   "TARGET_USE_FANCY_MATH_387"
13200   "fprem1"
13201   [(set_attr "type" "fpspc")
13202    (set_attr "mode" "XF")])
13204 (define_expand "remainderxf3"
13205   [(use (match_operand:XF 0 "register_operand"))
13206    (use (match_operand:XF 1 "general_operand"))
13207    (use (match_operand:XF 2 "general_operand"))]
13208   "TARGET_USE_FANCY_MATH_387"
13210   rtx label = gen_label_rtx ();
13212   rtx op1 = gen_reg_rtx (XFmode);
13213   rtx op2 = gen_reg_rtx (XFmode);
13215   emit_move_insn (op2, operands[2]);
13216   emit_move_insn (op1, operands[1]);
13218   emit_label (label);
13219   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13220   ix86_emit_fp_unordered_jump (label);
13221   LABEL_NUSES (label) = 1;
13223   emit_move_insn (operands[0], op1);
13224   DONE;
13227 (define_expand "remainder<mode>3"
13228   [(use (match_operand:MODEF 0 "register_operand"))
13229    (use (match_operand:MODEF 1 "general_operand"))
13230    (use (match_operand:MODEF 2 "general_operand"))]
13231   "TARGET_USE_FANCY_MATH_387"
13233   rtx (*gen_truncxf) (rtx, rtx);
13235   rtx label = gen_label_rtx ();
13237   rtx op1 = gen_reg_rtx (XFmode);
13238   rtx op2 = gen_reg_rtx (XFmode);
13240   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13241   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13243   emit_label (label);
13245   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13246   ix86_emit_fp_unordered_jump (label);
13247   LABEL_NUSES (label) = 1;
13249   /* Truncate the result properly for strict SSE math.  */
13250   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13251       && !TARGET_MIX_SSE_I387)
13252     gen_truncxf = gen_truncxf<mode>2;
13253   else
13254     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13256   emit_insn (gen_truncxf (operands[0], op1));
13257   DONE;
13260 (define_int_iterator SINCOS
13261         [UNSPEC_SIN
13262          UNSPEC_COS])
13264 (define_int_attr sincos
13265         [(UNSPEC_SIN "sin")
13266          (UNSPEC_COS "cos")])
13268 (define_insn "*<sincos>xf2_i387"
13269   [(set (match_operand:XF 0 "register_operand" "=f")
13270         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13271                    SINCOS))]
13272   "TARGET_USE_FANCY_MATH_387
13273    && flag_unsafe_math_optimizations"
13274   "f<sincos>"
13275   [(set_attr "type" "fpspc")
13276    (set_attr "mode" "XF")])
13278 (define_insn "*<sincos>_extend<mode>xf2_i387"
13279   [(set (match_operand:XF 0 "register_operand" "=f")
13280         (unspec:XF [(float_extend:XF
13281                       (match_operand:MODEF 1 "register_operand" "0"))]
13282                    SINCOS))]
13283   "TARGET_USE_FANCY_MATH_387
13284    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13285        || TARGET_MIX_SSE_I387)
13286    && flag_unsafe_math_optimizations"
13287   "f<sincos>"
13288   [(set_attr "type" "fpspc")
13289    (set_attr "mode" "XF")])
13291 ;; When sincos pattern is defined, sin and cos builtin functions will be
13292 ;; expanded to sincos pattern with one of its outputs left unused.
13293 ;; CSE pass will figure out if two sincos patterns can be combined,
13294 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13295 ;; depending on the unused output.
13297 (define_insn "sincosxf3"
13298   [(set (match_operand:XF 0 "register_operand" "=f")
13299         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13300                    UNSPEC_SINCOS_COS))
13301    (set (match_operand:XF 1 "register_operand" "=u")
13302         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13303   "TARGET_USE_FANCY_MATH_387
13304    && flag_unsafe_math_optimizations"
13305   "fsincos"
13306   [(set_attr "type" "fpspc")
13307    (set_attr "mode" "XF")])
13309 (define_split
13310   [(set (match_operand:XF 0 "register_operand")
13311         (unspec:XF [(match_operand:XF 2 "register_operand")]
13312                    UNSPEC_SINCOS_COS))
13313    (set (match_operand:XF 1 "register_operand")
13314         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13315   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13316    && can_create_pseudo_p ()"
13317   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13319 (define_split
13320   [(set (match_operand:XF 0 "register_operand")
13321         (unspec:XF [(match_operand:XF 2 "register_operand")]
13322                    UNSPEC_SINCOS_COS))
13323    (set (match_operand:XF 1 "register_operand")
13324         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13325   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13326    && can_create_pseudo_p ()"
13327   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13329 (define_insn "sincos_extend<mode>xf3_i387"
13330   [(set (match_operand:XF 0 "register_operand" "=f")
13331         (unspec:XF [(float_extend:XF
13332                       (match_operand:MODEF 2 "register_operand" "0"))]
13333                    UNSPEC_SINCOS_COS))
13334    (set (match_operand:XF 1 "register_operand" "=u")
13335         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13336   "TARGET_USE_FANCY_MATH_387
13337    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13338        || TARGET_MIX_SSE_I387)
13339    && flag_unsafe_math_optimizations"
13340   "fsincos"
13341   [(set_attr "type" "fpspc")
13342    (set_attr "mode" "XF")])
13344 (define_split
13345   [(set (match_operand:XF 0 "register_operand")
13346         (unspec:XF [(float_extend:XF
13347                       (match_operand:MODEF 2 "register_operand"))]
13348                    UNSPEC_SINCOS_COS))
13349    (set (match_operand:XF 1 "register_operand")
13350         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13351   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13352    && can_create_pseudo_p ()"
13353   [(set (match_dup 1)
13354         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13356 (define_split
13357   [(set (match_operand:XF 0 "register_operand")
13358         (unspec:XF [(float_extend:XF
13359                       (match_operand:MODEF 2 "register_operand"))]
13360                    UNSPEC_SINCOS_COS))
13361    (set (match_operand:XF 1 "register_operand")
13362         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13363   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13364    && can_create_pseudo_p ()"
13365   [(set (match_dup 0)
13366         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13368 (define_expand "sincos<mode>3"
13369   [(use (match_operand:MODEF 0 "register_operand"))
13370    (use (match_operand:MODEF 1 "register_operand"))
13371    (use (match_operand:MODEF 2 "register_operand"))]
13372   "TARGET_USE_FANCY_MATH_387
13373    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13374        || TARGET_MIX_SSE_I387)
13375    && flag_unsafe_math_optimizations"
13377   rtx op0 = gen_reg_rtx (XFmode);
13378   rtx op1 = gen_reg_rtx (XFmode);
13380   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13381   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13382   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13383   DONE;
13386 (define_insn "fptanxf4_i387"
13387   [(set (match_operand:XF 0 "register_operand" "=f")
13388         (match_operand:XF 3 "const_double_operand" "F"))
13389    (set (match_operand:XF 1 "register_operand" "=u")
13390         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13391                    UNSPEC_TAN))]
13392   "TARGET_USE_FANCY_MATH_387
13393    && flag_unsafe_math_optimizations
13394    && standard_80387_constant_p (operands[3]) == 2"
13395   "fptan"
13396   [(set_attr "type" "fpspc")
13397    (set_attr "mode" "XF")])
13399 (define_insn "fptan_extend<mode>xf4_i387"
13400   [(set (match_operand:MODEF 0 "register_operand" "=f")
13401         (match_operand:MODEF 3 "const_double_operand" "F"))
13402    (set (match_operand:XF 1 "register_operand" "=u")
13403         (unspec:XF [(float_extend:XF
13404                       (match_operand:MODEF 2 "register_operand" "0"))]
13405                    UNSPEC_TAN))]
13406   "TARGET_USE_FANCY_MATH_387
13407    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13408        || TARGET_MIX_SSE_I387)
13409    && flag_unsafe_math_optimizations
13410    && standard_80387_constant_p (operands[3]) == 2"
13411   "fptan"
13412   [(set_attr "type" "fpspc")
13413    (set_attr "mode" "XF")])
13415 (define_expand "tanxf2"
13416   [(use (match_operand:XF 0 "register_operand"))
13417    (use (match_operand:XF 1 "register_operand"))]
13418   "TARGET_USE_FANCY_MATH_387
13419    && flag_unsafe_math_optimizations"
13421   rtx one = gen_reg_rtx (XFmode);
13422   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13424   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13425   DONE;
13428 (define_expand "tan<mode>2"
13429   [(use (match_operand:MODEF 0 "register_operand"))
13430    (use (match_operand:MODEF 1 "register_operand"))]
13431   "TARGET_USE_FANCY_MATH_387
13432    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13433        || TARGET_MIX_SSE_I387)
13434    && flag_unsafe_math_optimizations"
13436   rtx op0 = gen_reg_rtx (XFmode);
13438   rtx one = gen_reg_rtx (<MODE>mode);
13439   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13441   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13442                                              operands[1], op2));
13443   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13444   DONE;
13447 (define_insn "*fpatanxf3_i387"
13448   [(set (match_operand:XF 0 "register_operand" "=f")
13449         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13450                     (match_operand:XF 2 "register_operand" "u")]
13451                    UNSPEC_FPATAN))
13452    (clobber (match_scratch:XF 3 "=2"))]
13453   "TARGET_USE_FANCY_MATH_387
13454    && flag_unsafe_math_optimizations"
13455   "fpatan"
13456   [(set_attr "type" "fpspc")
13457    (set_attr "mode" "XF")])
13459 (define_insn "fpatan_extend<mode>xf3_i387"
13460   [(set (match_operand:XF 0 "register_operand" "=f")
13461         (unspec:XF [(float_extend:XF
13462                       (match_operand:MODEF 1 "register_operand" "0"))
13463                     (float_extend:XF
13464                       (match_operand:MODEF 2 "register_operand" "u"))]
13465                    UNSPEC_FPATAN))
13466    (clobber (match_scratch:XF 3 "=2"))]
13467   "TARGET_USE_FANCY_MATH_387
13468    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13469        || TARGET_MIX_SSE_I387)
13470    && flag_unsafe_math_optimizations"
13471   "fpatan"
13472   [(set_attr "type" "fpspc")
13473    (set_attr "mode" "XF")])
13475 (define_expand "atan2xf3"
13476   [(parallel [(set (match_operand:XF 0 "register_operand")
13477                    (unspec:XF [(match_operand:XF 2 "register_operand")
13478                                (match_operand:XF 1 "register_operand")]
13479                               UNSPEC_FPATAN))
13480               (clobber (match_scratch:XF 3))])]
13481   "TARGET_USE_FANCY_MATH_387
13482    && flag_unsafe_math_optimizations")
13484 (define_expand "atan2<mode>3"
13485   [(use (match_operand:MODEF 0 "register_operand"))
13486    (use (match_operand:MODEF 1 "register_operand"))
13487    (use (match_operand:MODEF 2 "register_operand"))]
13488   "TARGET_USE_FANCY_MATH_387
13489    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13490        || TARGET_MIX_SSE_I387)
13491    && flag_unsafe_math_optimizations"
13493   rtx op0 = gen_reg_rtx (XFmode);
13495   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13496   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13497   DONE;
13500 (define_expand "atanxf2"
13501   [(parallel [(set (match_operand:XF 0 "register_operand")
13502                    (unspec:XF [(match_dup 2)
13503                                (match_operand:XF 1 "register_operand")]
13504                               UNSPEC_FPATAN))
13505               (clobber (match_scratch:XF 3))])]
13506   "TARGET_USE_FANCY_MATH_387
13507    && flag_unsafe_math_optimizations"
13509   operands[2] = gen_reg_rtx (XFmode);
13510   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13513 (define_expand "atan<mode>2"
13514   [(use (match_operand:MODEF 0 "register_operand"))
13515    (use (match_operand:MODEF 1 "register_operand"))]
13516   "TARGET_USE_FANCY_MATH_387
13517    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13518        || TARGET_MIX_SSE_I387)
13519    && flag_unsafe_math_optimizations"
13521   rtx op0 = gen_reg_rtx (XFmode);
13523   rtx op2 = gen_reg_rtx (<MODE>mode);
13524   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13526   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13527   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13528   DONE;
13531 (define_expand "asinxf2"
13532   [(set (match_dup 2)
13533         (mult:XF (match_operand:XF 1 "register_operand")
13534                  (match_dup 1)))
13535    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13536    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13537    (parallel [(set (match_operand:XF 0 "register_operand")
13538                    (unspec:XF [(match_dup 5) (match_dup 1)]
13539                               UNSPEC_FPATAN))
13540               (clobber (match_scratch:XF 6))])]
13541   "TARGET_USE_FANCY_MATH_387
13542    && flag_unsafe_math_optimizations"
13544   int i;
13546   if (optimize_insn_for_size_p ())
13547     FAIL;
13549   for (i = 2; i < 6; i++)
13550     operands[i] = gen_reg_rtx (XFmode);
13552   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13555 (define_expand "asin<mode>2"
13556   [(use (match_operand:MODEF 0 "register_operand"))
13557    (use (match_operand:MODEF 1 "general_operand"))]
13558  "TARGET_USE_FANCY_MATH_387
13559    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13560        || TARGET_MIX_SSE_I387)
13561    && flag_unsafe_math_optimizations"
13563   rtx op0 = gen_reg_rtx (XFmode);
13564   rtx op1 = gen_reg_rtx (XFmode);
13566   if (optimize_insn_for_size_p ())
13567     FAIL;
13569   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13570   emit_insn (gen_asinxf2 (op0, op1));
13571   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13572   DONE;
13575 (define_expand "acosxf2"
13576   [(set (match_dup 2)
13577         (mult:XF (match_operand:XF 1 "register_operand")
13578                  (match_dup 1)))
13579    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13580    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13581    (parallel [(set (match_operand:XF 0 "register_operand")
13582                    (unspec:XF [(match_dup 1) (match_dup 5)]
13583                               UNSPEC_FPATAN))
13584               (clobber (match_scratch:XF 6))])]
13585   "TARGET_USE_FANCY_MATH_387
13586    && flag_unsafe_math_optimizations"
13588   int i;
13590   if (optimize_insn_for_size_p ())
13591     FAIL;
13593   for (i = 2; i < 6; i++)
13594     operands[i] = gen_reg_rtx (XFmode);
13596   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13599 (define_expand "acos<mode>2"
13600   [(use (match_operand:MODEF 0 "register_operand"))
13601    (use (match_operand:MODEF 1 "general_operand"))]
13602  "TARGET_USE_FANCY_MATH_387
13603    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13604        || TARGET_MIX_SSE_I387)
13605    && flag_unsafe_math_optimizations"
13607   rtx op0 = gen_reg_rtx (XFmode);
13608   rtx op1 = gen_reg_rtx (XFmode);
13610   if (optimize_insn_for_size_p ())
13611     FAIL;
13613   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13614   emit_insn (gen_acosxf2 (op0, op1));
13615   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13616   DONE;
13619 (define_insn "fyl2xxf3_i387"
13620   [(set (match_operand:XF 0 "register_operand" "=f")
13621         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13622                     (match_operand:XF 2 "register_operand" "u")]
13623                    UNSPEC_FYL2X))
13624    (clobber (match_scratch:XF 3 "=2"))]
13625   "TARGET_USE_FANCY_MATH_387
13626    && flag_unsafe_math_optimizations"
13627   "fyl2x"
13628   [(set_attr "type" "fpspc")
13629    (set_attr "mode" "XF")])
13631 (define_insn "fyl2x_extend<mode>xf3_i387"
13632   [(set (match_operand:XF 0 "register_operand" "=f")
13633         (unspec:XF [(float_extend:XF
13634                       (match_operand:MODEF 1 "register_operand" "0"))
13635                     (match_operand:XF 2 "register_operand" "u")]
13636                    UNSPEC_FYL2X))
13637    (clobber (match_scratch:XF 3 "=2"))]
13638   "TARGET_USE_FANCY_MATH_387
13639    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13640        || TARGET_MIX_SSE_I387)
13641    && flag_unsafe_math_optimizations"
13642   "fyl2x"
13643   [(set_attr "type" "fpspc")
13644    (set_attr "mode" "XF")])
13646 (define_expand "logxf2"
13647   [(parallel [(set (match_operand:XF 0 "register_operand")
13648                    (unspec:XF [(match_operand:XF 1 "register_operand")
13649                                (match_dup 2)] UNSPEC_FYL2X))
13650               (clobber (match_scratch:XF 3))])]
13651   "TARGET_USE_FANCY_MATH_387
13652    && flag_unsafe_math_optimizations"
13654   operands[2] = gen_reg_rtx (XFmode);
13655   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13658 (define_expand "log<mode>2"
13659   [(use (match_operand:MODEF 0 "register_operand"))
13660    (use (match_operand:MODEF 1 "register_operand"))]
13661   "TARGET_USE_FANCY_MATH_387
13662    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13663        || TARGET_MIX_SSE_I387)
13664    && flag_unsafe_math_optimizations"
13666   rtx op0 = gen_reg_rtx (XFmode);
13668   rtx op2 = gen_reg_rtx (XFmode);
13669   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13671   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13672   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13673   DONE;
13676 (define_expand "log10xf2"
13677   [(parallel [(set (match_operand:XF 0 "register_operand")
13678                    (unspec:XF [(match_operand:XF 1 "register_operand")
13679                                (match_dup 2)] UNSPEC_FYL2X))
13680               (clobber (match_scratch:XF 3))])]
13681   "TARGET_USE_FANCY_MATH_387
13682    && flag_unsafe_math_optimizations"
13684   operands[2] = gen_reg_rtx (XFmode);
13685   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13688 (define_expand "log10<mode>2"
13689   [(use (match_operand:MODEF 0 "register_operand"))
13690    (use (match_operand:MODEF 1 "register_operand"))]
13691   "TARGET_USE_FANCY_MATH_387
13692    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13693        || TARGET_MIX_SSE_I387)
13694    && flag_unsafe_math_optimizations"
13696   rtx op0 = gen_reg_rtx (XFmode);
13698   rtx op2 = gen_reg_rtx (XFmode);
13699   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13701   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13702   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13703   DONE;
13706 (define_expand "log2xf2"
13707   [(parallel [(set (match_operand:XF 0 "register_operand")
13708                    (unspec:XF [(match_operand:XF 1 "register_operand")
13709                                (match_dup 2)] UNSPEC_FYL2X))
13710               (clobber (match_scratch:XF 3))])]
13711   "TARGET_USE_FANCY_MATH_387
13712    && flag_unsafe_math_optimizations"
13714   operands[2] = gen_reg_rtx (XFmode);
13715   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13718 (define_expand "log2<mode>2"
13719   [(use (match_operand:MODEF 0 "register_operand"))
13720    (use (match_operand:MODEF 1 "register_operand"))]
13721   "TARGET_USE_FANCY_MATH_387
13722    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13723        || TARGET_MIX_SSE_I387)
13724    && flag_unsafe_math_optimizations"
13726   rtx op0 = gen_reg_rtx (XFmode);
13728   rtx op2 = gen_reg_rtx (XFmode);
13729   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13731   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13732   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13733   DONE;
13736 (define_insn "fyl2xp1xf3_i387"
13737   [(set (match_operand:XF 0 "register_operand" "=f")
13738         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13739                     (match_operand:XF 2 "register_operand" "u")]
13740                    UNSPEC_FYL2XP1))
13741    (clobber (match_scratch:XF 3 "=2"))]
13742   "TARGET_USE_FANCY_MATH_387
13743    && flag_unsafe_math_optimizations"
13744   "fyl2xp1"
13745   [(set_attr "type" "fpspc")
13746    (set_attr "mode" "XF")])
13748 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13749   [(set (match_operand:XF 0 "register_operand" "=f")
13750         (unspec:XF [(float_extend:XF
13751                       (match_operand:MODEF 1 "register_operand" "0"))
13752                     (match_operand:XF 2 "register_operand" "u")]
13753                    UNSPEC_FYL2XP1))
13754    (clobber (match_scratch:XF 3 "=2"))]
13755   "TARGET_USE_FANCY_MATH_387
13756    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13757        || TARGET_MIX_SSE_I387)
13758    && flag_unsafe_math_optimizations"
13759   "fyl2xp1"
13760   [(set_attr "type" "fpspc")
13761    (set_attr "mode" "XF")])
13763 (define_expand "log1pxf2"
13764   [(use (match_operand:XF 0 "register_operand"))
13765    (use (match_operand:XF 1 "register_operand"))]
13766   "TARGET_USE_FANCY_MATH_387
13767    && flag_unsafe_math_optimizations"
13769   if (optimize_insn_for_size_p ())
13770     FAIL;
13772   ix86_emit_i387_log1p (operands[0], operands[1]);
13773   DONE;
13776 (define_expand "log1p<mode>2"
13777   [(use (match_operand:MODEF 0 "register_operand"))
13778    (use (match_operand:MODEF 1 "register_operand"))]
13779   "TARGET_USE_FANCY_MATH_387
13780    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781        || TARGET_MIX_SSE_I387)
13782    && flag_unsafe_math_optimizations"
13784   rtx op0;
13786   if (optimize_insn_for_size_p ())
13787     FAIL;
13789   op0 = gen_reg_rtx (XFmode);
13791   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13793   ix86_emit_i387_log1p (op0, operands[1]);
13794   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13795   DONE;
13798 (define_insn "fxtractxf3_i387"
13799   [(set (match_operand:XF 0 "register_operand" "=f")
13800         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13801                    UNSPEC_XTRACT_FRACT))
13802    (set (match_operand:XF 1 "register_operand" "=u")
13803         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13804   "TARGET_USE_FANCY_MATH_387
13805    && flag_unsafe_math_optimizations"
13806   "fxtract"
13807   [(set_attr "type" "fpspc")
13808    (set_attr "mode" "XF")])
13810 (define_insn "fxtract_extend<mode>xf3_i387"
13811   [(set (match_operand:XF 0 "register_operand" "=f")
13812         (unspec:XF [(float_extend:XF
13813                       (match_operand:MODEF 2 "register_operand" "0"))]
13814                    UNSPEC_XTRACT_FRACT))
13815    (set (match_operand:XF 1 "register_operand" "=u")
13816         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13817   "TARGET_USE_FANCY_MATH_387
13818    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13819        || TARGET_MIX_SSE_I387)
13820    && flag_unsafe_math_optimizations"
13821   "fxtract"
13822   [(set_attr "type" "fpspc")
13823    (set_attr "mode" "XF")])
13825 (define_expand "logbxf2"
13826   [(parallel [(set (match_dup 2)
13827                    (unspec:XF [(match_operand:XF 1 "register_operand")]
13828                               UNSPEC_XTRACT_FRACT))
13829               (set (match_operand:XF 0 "register_operand")
13830                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13831   "TARGET_USE_FANCY_MATH_387
13832    && flag_unsafe_math_optimizations"
13833   "operands[2] = gen_reg_rtx (XFmode);")
13835 (define_expand "logb<mode>2"
13836   [(use (match_operand:MODEF 0 "register_operand"))
13837    (use (match_operand:MODEF 1 "register_operand"))]
13838   "TARGET_USE_FANCY_MATH_387
13839    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13840        || TARGET_MIX_SSE_I387)
13841    && flag_unsafe_math_optimizations"
13843   rtx op0 = gen_reg_rtx (XFmode);
13844   rtx op1 = gen_reg_rtx (XFmode);
13846   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13847   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13848   DONE;
13851 (define_expand "ilogbxf2"
13852   [(use (match_operand:SI 0 "register_operand"))
13853    (use (match_operand:XF 1 "register_operand"))]
13854   "TARGET_USE_FANCY_MATH_387
13855    && flag_unsafe_math_optimizations"
13857   rtx op0, op1;
13859   if (optimize_insn_for_size_p ())
13860     FAIL;
13862   op0 = gen_reg_rtx (XFmode);
13863   op1 = gen_reg_rtx (XFmode);
13865   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13866   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13867   DONE;
13870 (define_expand "ilogb<mode>2"
13871   [(use (match_operand:SI 0 "register_operand"))
13872    (use (match_operand:MODEF 1 "register_operand"))]
13873   "TARGET_USE_FANCY_MATH_387
13874    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13875        || TARGET_MIX_SSE_I387)
13876    && flag_unsafe_math_optimizations"
13878   rtx op0, op1;
13880   if (optimize_insn_for_size_p ())
13881     FAIL;
13883   op0 = gen_reg_rtx (XFmode);
13884   op1 = gen_reg_rtx (XFmode);
13886   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13887   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13888   DONE;
13891 (define_insn "*f2xm1xf2_i387"
13892   [(set (match_operand:XF 0 "register_operand" "=f")
13893         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13894                    UNSPEC_F2XM1))]
13895   "TARGET_USE_FANCY_MATH_387
13896    && flag_unsafe_math_optimizations"
13897   "f2xm1"
13898   [(set_attr "type" "fpspc")
13899    (set_attr "mode" "XF")])
13901 (define_insn "*fscalexf4_i387"
13902   [(set (match_operand:XF 0 "register_operand" "=f")
13903         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13904                     (match_operand:XF 3 "register_operand" "1")]
13905                    UNSPEC_FSCALE_FRACT))
13906    (set (match_operand:XF 1 "register_operand" "=u")
13907         (unspec:XF [(match_dup 2) (match_dup 3)]
13908                    UNSPEC_FSCALE_EXP))]
13909   "TARGET_USE_FANCY_MATH_387
13910    && flag_unsafe_math_optimizations"
13911   "fscale"
13912   [(set_attr "type" "fpspc")
13913    (set_attr "mode" "XF")])
13915 (define_expand "expNcorexf3"
13916   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
13917                                (match_operand:XF 2 "register_operand")))
13918    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13919    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13920    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13921    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13922    (parallel [(set (match_operand:XF 0 "register_operand")
13923                    (unspec:XF [(match_dup 8) (match_dup 4)]
13924                               UNSPEC_FSCALE_FRACT))
13925               (set (match_dup 9)
13926                    (unspec:XF [(match_dup 8) (match_dup 4)]
13927                               UNSPEC_FSCALE_EXP))])]
13928   "TARGET_USE_FANCY_MATH_387
13929    && flag_unsafe_math_optimizations"
13931   int i;
13933   if (optimize_insn_for_size_p ())
13934     FAIL;
13936   for (i = 3; i < 10; i++)
13937     operands[i] = gen_reg_rtx (XFmode);
13939   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
13942 (define_expand "expxf2"
13943   [(use (match_operand:XF 0 "register_operand"))
13944    (use (match_operand:XF 1 "register_operand"))]
13945   "TARGET_USE_FANCY_MATH_387
13946    && flag_unsafe_math_optimizations"
13948   rtx op2;
13950   if (optimize_insn_for_size_p ())
13951     FAIL;
13953   op2 = gen_reg_rtx (XFmode);
13954   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13956   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13957   DONE;
13960 (define_expand "exp<mode>2"
13961   [(use (match_operand:MODEF 0 "register_operand"))
13962    (use (match_operand:MODEF 1 "general_operand"))]
13963  "TARGET_USE_FANCY_MATH_387
13964    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13965        || TARGET_MIX_SSE_I387)
13966    && flag_unsafe_math_optimizations"
13968   rtx op0, op1;
13970   if (optimize_insn_for_size_p ())
13971     FAIL;
13973   op0 = gen_reg_rtx (XFmode);
13974   op1 = gen_reg_rtx (XFmode);
13976   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13977   emit_insn (gen_expxf2 (op0, op1));
13978   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13979   DONE;
13982 (define_expand "exp10xf2"
13983   [(use (match_operand:XF 0 "register_operand"))
13984    (use (match_operand:XF 1 "register_operand"))]
13985   "TARGET_USE_FANCY_MATH_387
13986    && flag_unsafe_math_optimizations"
13988   rtx op2;
13990   if (optimize_insn_for_size_p ())
13991     FAIL;
13993   op2 = gen_reg_rtx (XFmode);
13994   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13996   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13997   DONE;
14000 (define_expand "exp10<mode>2"
14001   [(use (match_operand:MODEF 0 "register_operand"))
14002    (use (match_operand:MODEF 1 "general_operand"))]
14003  "TARGET_USE_FANCY_MATH_387
14004    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14005        || TARGET_MIX_SSE_I387)
14006    && flag_unsafe_math_optimizations"
14008   rtx op0, op1;
14010   if (optimize_insn_for_size_p ())
14011     FAIL;
14013   op0 = gen_reg_rtx (XFmode);
14014   op1 = gen_reg_rtx (XFmode);
14016   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14017   emit_insn (gen_exp10xf2 (op0, op1));
14018   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14019   DONE;
14022 (define_expand "exp2xf2"
14023   [(use (match_operand:XF 0 "register_operand"))
14024    (use (match_operand:XF 1 "register_operand"))]
14025   "TARGET_USE_FANCY_MATH_387
14026    && flag_unsafe_math_optimizations"
14028   rtx op2;
14030   if (optimize_insn_for_size_p ())
14031     FAIL;
14033   op2 = gen_reg_rtx (XFmode);
14034   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14036   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14037   DONE;
14040 (define_expand "exp2<mode>2"
14041   [(use (match_operand:MODEF 0 "register_operand"))
14042    (use (match_operand:MODEF 1 "general_operand"))]
14043  "TARGET_USE_FANCY_MATH_387
14044    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045        || TARGET_MIX_SSE_I387)
14046    && flag_unsafe_math_optimizations"
14048   rtx op0, op1;
14050   if (optimize_insn_for_size_p ())
14051     FAIL;
14053   op0 = gen_reg_rtx (XFmode);
14054   op1 = gen_reg_rtx (XFmode);
14056   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14057   emit_insn (gen_exp2xf2 (op0, op1));
14058   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14059   DONE;
14062 (define_expand "expm1xf2"
14063   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14064                                (match_dup 2)))
14065    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14066    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14067    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14068    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14069    (parallel [(set (match_dup 7)
14070                    (unspec:XF [(match_dup 6) (match_dup 4)]
14071                               UNSPEC_FSCALE_FRACT))
14072               (set (match_dup 8)
14073                    (unspec:XF [(match_dup 6) (match_dup 4)]
14074                               UNSPEC_FSCALE_EXP))])
14075    (parallel [(set (match_dup 10)
14076                    (unspec:XF [(match_dup 9) (match_dup 8)]
14077                               UNSPEC_FSCALE_FRACT))
14078               (set (match_dup 11)
14079                    (unspec:XF [(match_dup 9) (match_dup 8)]
14080                               UNSPEC_FSCALE_EXP))])
14081    (set (match_dup 12) (minus:XF (match_dup 10)
14082                                  (float_extend:XF (match_dup 13))))
14083    (set (match_operand:XF 0 "register_operand")
14084         (plus:XF (match_dup 12) (match_dup 7)))]
14085   "TARGET_USE_FANCY_MATH_387
14086    && flag_unsafe_math_optimizations"
14088   int i;
14090   if (optimize_insn_for_size_p ())
14091     FAIL;
14093   for (i = 2; i < 13; i++)
14094     operands[i] = gen_reg_rtx (XFmode);
14096   operands[13]
14097     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14099   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14102 (define_expand "expm1<mode>2"
14103   [(use (match_operand:MODEF 0 "register_operand"))
14104    (use (match_operand:MODEF 1 "general_operand"))]
14105  "TARGET_USE_FANCY_MATH_387
14106    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14107        || TARGET_MIX_SSE_I387)
14108    && flag_unsafe_math_optimizations"
14110   rtx op0, op1;
14112   if (optimize_insn_for_size_p ())
14113     FAIL;
14115   op0 = gen_reg_rtx (XFmode);
14116   op1 = gen_reg_rtx (XFmode);
14118   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14119   emit_insn (gen_expm1xf2 (op0, op1));
14120   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14121   DONE;
14124 (define_expand "ldexpxf3"
14125   [(set (match_dup 3)
14126         (float:XF (match_operand:SI 2 "register_operand")))
14127    (parallel [(set (match_operand:XF 0 " register_operand")
14128                    (unspec:XF [(match_operand:XF 1 "register_operand")
14129                                (match_dup 3)]
14130                               UNSPEC_FSCALE_FRACT))
14131               (set (match_dup 4)
14132                    (unspec:XF [(match_dup 1) (match_dup 3)]
14133                               UNSPEC_FSCALE_EXP))])]
14134   "TARGET_USE_FANCY_MATH_387
14135    && flag_unsafe_math_optimizations"
14137   if (optimize_insn_for_size_p ())
14138     FAIL;
14140   operands[3] = gen_reg_rtx (XFmode);
14141   operands[4] = gen_reg_rtx (XFmode);
14144 (define_expand "ldexp<mode>3"
14145   [(use (match_operand:MODEF 0 "register_operand"))
14146    (use (match_operand:MODEF 1 "general_operand"))
14147    (use (match_operand:SI 2 "register_operand"))]
14148  "TARGET_USE_FANCY_MATH_387
14149    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14150        || TARGET_MIX_SSE_I387)
14151    && flag_unsafe_math_optimizations"
14153   rtx op0, op1;
14155   if (optimize_insn_for_size_p ())
14156     FAIL;
14158   op0 = gen_reg_rtx (XFmode);
14159   op1 = gen_reg_rtx (XFmode);
14161   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14162   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14163   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14164   DONE;
14167 (define_expand "scalbxf3"
14168   [(parallel [(set (match_operand:XF 0 " register_operand")
14169                    (unspec:XF [(match_operand:XF 1 "register_operand")
14170                                (match_operand:XF 2 "register_operand")]
14171                               UNSPEC_FSCALE_FRACT))
14172               (set (match_dup 3)
14173                    (unspec:XF [(match_dup 1) (match_dup 2)]
14174                               UNSPEC_FSCALE_EXP))])]
14175   "TARGET_USE_FANCY_MATH_387
14176    && flag_unsafe_math_optimizations"
14178   if (optimize_insn_for_size_p ())
14179     FAIL;
14181   operands[3] = gen_reg_rtx (XFmode);
14184 (define_expand "scalb<mode>3"
14185   [(use (match_operand:MODEF 0 "register_operand"))
14186    (use (match_operand:MODEF 1 "general_operand"))
14187    (use (match_operand:MODEF 2 "general_operand"))]
14188  "TARGET_USE_FANCY_MATH_387
14189    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14190        || TARGET_MIX_SSE_I387)
14191    && flag_unsafe_math_optimizations"
14193   rtx op0, op1, op2;
14195   if (optimize_insn_for_size_p ())
14196     FAIL;
14198   op0 = gen_reg_rtx (XFmode);
14199   op1 = gen_reg_rtx (XFmode);
14200   op2 = gen_reg_rtx (XFmode);
14202   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14203   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14204   emit_insn (gen_scalbxf3 (op0, op1, op2));
14205   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14206   DONE;
14209 (define_expand "significandxf2"
14210   [(parallel [(set (match_operand:XF 0 "register_operand")
14211                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14212                               UNSPEC_XTRACT_FRACT))
14213               (set (match_dup 2)
14214                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14215   "TARGET_USE_FANCY_MATH_387
14216    && flag_unsafe_math_optimizations"
14217   "operands[2] = gen_reg_rtx (XFmode);")
14219 (define_expand "significand<mode>2"
14220   [(use (match_operand:MODEF 0 "register_operand"))
14221    (use (match_operand:MODEF 1 "register_operand"))]
14222   "TARGET_USE_FANCY_MATH_387
14223    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14224        || TARGET_MIX_SSE_I387)
14225    && flag_unsafe_math_optimizations"
14227   rtx op0 = gen_reg_rtx (XFmode);
14228   rtx op1 = gen_reg_rtx (XFmode);
14230   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14231   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14232   DONE;
14236 (define_insn "sse4_1_round<mode>2"
14237   [(set (match_operand:MODEF 0 "register_operand" "=x")
14238         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14239                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14240                       UNSPEC_ROUND))]
14241   "TARGET_ROUND"
14242   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14243   [(set_attr "type" "ssecvt")
14244    (set_attr "prefix_extra" "1")
14245    (set_attr "prefix" "maybe_vex")
14246    (set_attr "mode" "<MODE>")])
14248 (define_insn "rintxf2"
14249   [(set (match_operand:XF 0 "register_operand" "=f")
14250         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14251                    UNSPEC_FRNDINT))]
14252   "TARGET_USE_FANCY_MATH_387
14253    && flag_unsafe_math_optimizations"
14254   "frndint"
14255   [(set_attr "type" "fpspc")
14256    (set_attr "mode" "XF")])
14258 (define_expand "rint<mode>2"
14259   [(use (match_operand:MODEF 0 "register_operand"))
14260    (use (match_operand:MODEF 1 "register_operand"))]
14261   "(TARGET_USE_FANCY_MATH_387
14262     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14263         || TARGET_MIX_SSE_I387)
14264     && flag_unsafe_math_optimizations)
14265    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14266        && !flag_trapping_math)"
14268   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14269       && !flag_trapping_math)
14270     {
14271       if (TARGET_ROUND)
14272         emit_insn (gen_sse4_1_round<mode>2
14273                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14274       else if (optimize_insn_for_size_p ())
14275         FAIL;
14276       else
14277         ix86_expand_rint (operands[0], operands[1]);
14278     }
14279   else
14280     {
14281       rtx op0 = gen_reg_rtx (XFmode);
14282       rtx op1 = gen_reg_rtx (XFmode);
14284       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14285       emit_insn (gen_rintxf2 (op0, op1));
14287       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14288     }
14289   DONE;
14292 (define_expand "round<mode>2"
14293   [(match_operand:X87MODEF 0 "register_operand")
14294    (match_operand:X87MODEF 1 "nonimmediate_operand")]
14295   "(TARGET_USE_FANCY_MATH_387
14296     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14297         || TARGET_MIX_SSE_I387)
14298     && flag_unsafe_math_optimizations)
14299    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14300        && !flag_trapping_math && !flag_rounding_math)"
14302   if (optimize_insn_for_size_p ())
14303     FAIL;
14305   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14306       && !flag_trapping_math && !flag_rounding_math)
14307     {
14308       if (TARGET_ROUND)
14309         {
14310           operands[1] = force_reg (<MODE>mode, operands[1]);
14311           ix86_expand_round_sse4 (operands[0], operands[1]);
14312         }
14313       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14314         ix86_expand_round (operands[0], operands[1]);
14315       else
14316         ix86_expand_rounddf_32 (operands[0], operands[1]);
14317     }
14318   else
14319     {
14320       operands[1] = force_reg (<MODE>mode, operands[1]);
14321       ix86_emit_i387_round (operands[0], operands[1]);
14322     }
14323   DONE;
14326 (define_insn_and_split "*fistdi2_1"
14327   [(set (match_operand:DI 0 "nonimmediate_operand")
14328         (unspec:DI [(match_operand:XF 1 "register_operand")]
14329                    UNSPEC_FIST))]
14330   "TARGET_USE_FANCY_MATH_387
14331    && can_create_pseudo_p ()"
14332   "#"
14333   "&& 1"
14334   [(const_int 0)]
14336   if (memory_operand (operands[0], VOIDmode))
14337     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14338   else
14339     {
14340       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14341       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14342                                          operands[2]));
14343     }
14344   DONE;
14346   [(set_attr "type" "fpspc")
14347    (set_attr "mode" "DI")])
14349 (define_insn "fistdi2"
14350   [(set (match_operand:DI 0 "memory_operand" "=m")
14351         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14352                    UNSPEC_FIST))
14353    (clobber (match_scratch:XF 2 "=&1f"))]
14354   "TARGET_USE_FANCY_MATH_387"
14355   "* return output_fix_trunc (insn, operands, false);"
14356   [(set_attr "type" "fpspc")
14357    (set_attr "mode" "DI")])
14359 (define_insn "fistdi2_with_temp"
14360   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14361         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14362                    UNSPEC_FIST))
14363    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14364    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14365   "TARGET_USE_FANCY_MATH_387"
14366   "#"
14367   [(set_attr "type" "fpspc")
14368    (set_attr "mode" "DI")])
14370 (define_split
14371   [(set (match_operand:DI 0 "register_operand")
14372         (unspec:DI [(match_operand:XF 1 "register_operand")]
14373                    UNSPEC_FIST))
14374    (clobber (match_operand:DI 2 "memory_operand"))
14375    (clobber (match_scratch 3))]
14376   "reload_completed"
14377   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14378               (clobber (match_dup 3))])
14379    (set (match_dup 0) (match_dup 2))])
14381 (define_split
14382   [(set (match_operand:DI 0 "memory_operand")
14383         (unspec:DI [(match_operand:XF 1 "register_operand")]
14384                    UNSPEC_FIST))
14385    (clobber (match_operand:DI 2 "memory_operand"))
14386    (clobber (match_scratch 3))]
14387   "reload_completed"
14388   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14389               (clobber (match_dup 3))])])
14391 (define_insn_and_split "*fist<mode>2_1"
14392   [(set (match_operand:SWI24 0 "register_operand")
14393         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14394                       UNSPEC_FIST))]
14395   "TARGET_USE_FANCY_MATH_387
14396    && can_create_pseudo_p ()"
14397   "#"
14398   "&& 1"
14399   [(const_int 0)]
14401   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14402   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14403                                         operands[2]));
14404   DONE;
14406   [(set_attr "type" "fpspc")
14407    (set_attr "mode" "<MODE>")])
14409 (define_insn "fist<mode>2"
14410   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14411         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14412                       UNSPEC_FIST))]
14413   "TARGET_USE_FANCY_MATH_387"
14414   "* return output_fix_trunc (insn, operands, false);"
14415   [(set_attr "type" "fpspc")
14416    (set_attr "mode" "<MODE>")])
14418 (define_insn "fist<mode>2_with_temp"
14419   [(set (match_operand:SWI24 0 "register_operand" "=r")
14420         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14421                       UNSPEC_FIST))
14422    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14423   "TARGET_USE_FANCY_MATH_387"
14424   "#"
14425   [(set_attr "type" "fpspc")
14426    (set_attr "mode" "<MODE>")])
14428 (define_split
14429   [(set (match_operand:SWI24 0 "register_operand")
14430         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14431                       UNSPEC_FIST))
14432    (clobber (match_operand:SWI24 2 "memory_operand"))]
14433   "reload_completed"
14434   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14435    (set (match_dup 0) (match_dup 2))])
14437 (define_split
14438   [(set (match_operand:SWI24 0 "memory_operand")
14439         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14440                       UNSPEC_FIST))
14441    (clobber (match_operand:SWI24 2 "memory_operand"))]
14442   "reload_completed"
14443   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14445 (define_expand "lrintxf<mode>2"
14446   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14447      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14448                      UNSPEC_FIST))]
14449   "TARGET_USE_FANCY_MATH_387")
14451 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14452   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14453      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14454                    UNSPEC_FIX_NOTRUNC))]
14455   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14457 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14458   [(match_operand:SWI248x 0 "nonimmediate_operand")
14459    (match_operand:X87MODEF 1 "register_operand")]
14460   "(TARGET_USE_FANCY_MATH_387
14461     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14462         || TARGET_MIX_SSE_I387)
14463     && flag_unsafe_math_optimizations)
14464    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14465        && <SWI248x:MODE>mode != HImode 
14466        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14467        && !flag_trapping_math && !flag_rounding_math)"
14469   if (optimize_insn_for_size_p ())
14470     FAIL;
14472   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14473       && <SWI248x:MODE>mode != HImode
14474       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14475       && !flag_trapping_math && !flag_rounding_math)
14476     ix86_expand_lround (operands[0], operands[1]);
14477   else
14478     ix86_emit_i387_round (operands[0], operands[1]);
14479   DONE;
14482 (define_int_iterator FRNDINT_ROUNDING
14483         [UNSPEC_FRNDINT_FLOOR
14484          UNSPEC_FRNDINT_CEIL
14485          UNSPEC_FRNDINT_TRUNC])
14487 (define_int_iterator FIST_ROUNDING
14488         [UNSPEC_FIST_FLOOR
14489          UNSPEC_FIST_CEIL])
14491 ;; Base name for define_insn
14492 (define_int_attr rounding_insn
14493         [(UNSPEC_FRNDINT_FLOOR "floor")
14494          (UNSPEC_FRNDINT_CEIL "ceil")
14495          (UNSPEC_FRNDINT_TRUNC "btrunc")
14496          (UNSPEC_FIST_FLOOR "floor")
14497          (UNSPEC_FIST_CEIL "ceil")])
14499 (define_int_attr rounding
14500         [(UNSPEC_FRNDINT_FLOOR "floor")
14501          (UNSPEC_FRNDINT_CEIL "ceil")
14502          (UNSPEC_FRNDINT_TRUNC "trunc")
14503          (UNSPEC_FIST_FLOOR "floor")
14504          (UNSPEC_FIST_CEIL "ceil")])
14506 (define_int_attr ROUNDING
14507         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14508          (UNSPEC_FRNDINT_CEIL "CEIL")
14509          (UNSPEC_FRNDINT_TRUNC "TRUNC")
14510          (UNSPEC_FIST_FLOOR "FLOOR")
14511          (UNSPEC_FIST_CEIL "CEIL")])
14513 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14514 (define_insn_and_split "frndintxf2_<rounding>"
14515   [(set (match_operand:XF 0 "register_operand")
14516         (unspec:XF [(match_operand:XF 1 "register_operand")]
14517                    FRNDINT_ROUNDING))
14518    (clobber (reg:CC FLAGS_REG))]
14519   "TARGET_USE_FANCY_MATH_387
14520    && flag_unsafe_math_optimizations
14521    && can_create_pseudo_p ()"
14522   "#"
14523   "&& 1"
14524   [(const_int 0)]
14526   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14528   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14529   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14531   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14532                                              operands[2], operands[3]));
14533   DONE;
14535   [(set_attr "type" "frndint")
14536    (set_attr "i387_cw" "<rounding>")
14537    (set_attr "mode" "XF")])
14539 (define_insn "frndintxf2_<rounding>_i387"
14540   [(set (match_operand:XF 0 "register_operand" "=f")
14541         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14542                    FRNDINT_ROUNDING))
14543    (use (match_operand:HI 2 "memory_operand" "m"))
14544    (use (match_operand:HI 3 "memory_operand" "m"))]
14545   "TARGET_USE_FANCY_MATH_387
14546    && flag_unsafe_math_optimizations"
14547   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14548   [(set_attr "type" "frndint")
14549    (set_attr "i387_cw" "<rounding>")
14550    (set_attr "mode" "XF")])
14552 (define_expand "<rounding_insn>xf2"
14553   [(parallel [(set (match_operand:XF 0 "register_operand")
14554                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14555                               FRNDINT_ROUNDING))
14556               (clobber (reg:CC FLAGS_REG))])]
14557   "TARGET_USE_FANCY_MATH_387
14558    && flag_unsafe_math_optimizations
14559    && !optimize_insn_for_size_p ()")
14561 (define_expand "<rounding_insn><mode>2"
14562   [(parallel [(set (match_operand:MODEF 0 "register_operand")
14563                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14564                                  FRNDINT_ROUNDING))
14565               (clobber (reg:CC FLAGS_REG))])]
14566   "(TARGET_USE_FANCY_MATH_387
14567     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568         || TARGET_MIX_SSE_I387)
14569     && flag_unsafe_math_optimizations)
14570    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14571        && !flag_trapping_math)"
14573   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14574       && !flag_trapping_math)
14575     {
14576       if (TARGET_ROUND)
14577         emit_insn (gen_sse4_1_round<mode>2
14578                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14579       else if (optimize_insn_for_size_p ())
14580         FAIL;
14581       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14582         {
14583           if (ROUND_<ROUNDING> == ROUND_FLOOR)
14584             ix86_expand_floorceil (operands[0], operands[1], true);
14585           else if (ROUND_<ROUNDING> == ROUND_CEIL)
14586             ix86_expand_floorceil (operands[0], operands[1], false);
14587           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14588             ix86_expand_trunc (operands[0], operands[1]);
14589           else
14590             gcc_unreachable ();
14591         }
14592       else
14593         {
14594           if (ROUND_<ROUNDING> == ROUND_FLOOR)
14595             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14596           else if (ROUND_<ROUNDING> == ROUND_CEIL)
14597             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
14598           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14599             ix86_expand_truncdf_32 (operands[0], operands[1]);
14600           else
14601             gcc_unreachable ();
14602         }
14603     }
14604   else
14605     {
14606       rtx op0, op1;
14608       if (optimize_insn_for_size_p ())
14609         FAIL;
14611       op0 = gen_reg_rtx (XFmode);
14612       op1 = gen_reg_rtx (XFmode);
14613       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14614       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
14616       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14617     }
14618   DONE;
14621 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14622 (define_insn_and_split "frndintxf2_mask_pm"
14623   [(set (match_operand:XF 0 "register_operand")
14624         (unspec:XF [(match_operand:XF 1 "register_operand")]
14625                    UNSPEC_FRNDINT_MASK_PM))
14626    (clobber (reg:CC FLAGS_REG))]
14627   "TARGET_USE_FANCY_MATH_387
14628    && flag_unsafe_math_optimizations
14629    && can_create_pseudo_p ()"
14630   "#"
14631   "&& 1"
14632   [(const_int 0)]
14634   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14636   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14637   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14639   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14640                                           operands[2], operands[3]));
14641   DONE;
14643   [(set_attr "type" "frndint")
14644    (set_attr "i387_cw" "mask_pm")
14645    (set_attr "mode" "XF")])
14647 (define_insn "frndintxf2_mask_pm_i387"
14648   [(set (match_operand:XF 0 "register_operand" "=f")
14649         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14650                    UNSPEC_FRNDINT_MASK_PM))
14651    (use (match_operand:HI 2 "memory_operand" "m"))
14652    (use (match_operand:HI 3 "memory_operand" "m"))]
14653   "TARGET_USE_FANCY_MATH_387
14654    && flag_unsafe_math_optimizations"
14655   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14656   [(set_attr "type" "frndint")
14657    (set_attr "i387_cw" "mask_pm")
14658    (set_attr "mode" "XF")])
14660 (define_expand "nearbyintxf2"
14661   [(parallel [(set (match_operand:XF 0 "register_operand")
14662                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14663                               UNSPEC_FRNDINT_MASK_PM))
14664               (clobber (reg:CC FLAGS_REG))])]
14665   "TARGET_USE_FANCY_MATH_387
14666    && flag_unsafe_math_optimizations")
14668 (define_expand "nearbyint<mode>2"
14669   [(use (match_operand:MODEF 0 "register_operand"))
14670    (use (match_operand:MODEF 1 "register_operand"))]
14671   "TARGET_USE_FANCY_MATH_387
14672    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14673        || TARGET_MIX_SSE_I387)
14674    && flag_unsafe_math_optimizations"
14676   rtx op0 = gen_reg_rtx (XFmode);
14677   rtx op1 = gen_reg_rtx (XFmode);
14679   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14680   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14682   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14683   DONE;
14686 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14687 (define_insn_and_split "*fist<mode>2_<rounding>_1"
14688   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14689         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14690                         FIST_ROUNDING))
14691    (clobber (reg:CC FLAGS_REG))]
14692   "TARGET_USE_FANCY_MATH_387
14693    && flag_unsafe_math_optimizations
14694    && can_create_pseudo_p ()"
14695   "#"
14696   "&& 1"
14697   [(const_int 0)]
14699   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14701   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14702   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14703   if (memory_operand (operands[0], VOIDmode))
14704     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
14705                                            operands[2], operands[3]));
14706   else
14707     {
14708       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14709       emit_insn (gen_fist<mode>2_<rounding>_with_temp
14710                   (operands[0], operands[1], operands[2],
14711                    operands[3], operands[4]));
14712     }
14713   DONE;
14715   [(set_attr "type" "fistp")
14716    (set_attr "i387_cw" "<rounding>")
14717    (set_attr "mode" "<MODE>")])
14719 (define_insn "fistdi2_<rounding>"
14720   [(set (match_operand:DI 0 "memory_operand" "=m")
14721         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14722                    FIST_ROUNDING))
14723    (use (match_operand:HI 2 "memory_operand" "m"))
14724    (use (match_operand:HI 3 "memory_operand" "m"))
14725    (clobber (match_scratch:XF 4 "=&1f"))]
14726   "TARGET_USE_FANCY_MATH_387
14727    && flag_unsafe_math_optimizations"
14728   "* return output_fix_trunc (insn, operands, false);"
14729   [(set_attr "type" "fistp")
14730    (set_attr "i387_cw" "<rounding>")
14731    (set_attr "mode" "DI")])
14733 (define_insn "fistdi2_<rounding>_with_temp"
14734   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14735         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14736                    FIST_ROUNDING))
14737    (use (match_operand:HI 2 "memory_operand" "m,m"))
14738    (use (match_operand:HI 3 "memory_operand" "m,m"))
14739    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14740    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14741   "TARGET_USE_FANCY_MATH_387
14742    && flag_unsafe_math_optimizations"
14743   "#"
14744   [(set_attr "type" "fistp")
14745    (set_attr "i387_cw" "<rounding>")
14746    (set_attr "mode" "DI")])
14748 (define_split
14749   [(set (match_operand:DI 0 "register_operand")
14750         (unspec:DI [(match_operand:XF 1 "register_operand")]
14751                    FIST_ROUNDING))
14752    (use (match_operand:HI 2 "memory_operand"))
14753    (use (match_operand:HI 3 "memory_operand"))
14754    (clobber (match_operand:DI 4 "memory_operand"))
14755    (clobber (match_scratch 5))]
14756   "reload_completed"
14757   [(parallel [(set (match_dup 4)
14758                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14759               (use (match_dup 2))
14760               (use (match_dup 3))
14761               (clobber (match_dup 5))])
14762    (set (match_dup 0) (match_dup 4))])
14764 (define_split
14765   [(set (match_operand:DI 0 "memory_operand")
14766         (unspec:DI [(match_operand:XF 1 "register_operand")]
14767                    FIST_ROUNDING))
14768    (use (match_operand:HI 2 "memory_operand"))
14769    (use (match_operand:HI 3 "memory_operand"))
14770    (clobber (match_operand:DI 4 "memory_operand"))
14771    (clobber (match_scratch 5))]
14772   "reload_completed"
14773   [(parallel [(set (match_dup 0)
14774                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14775               (use (match_dup 2))
14776               (use (match_dup 3))
14777               (clobber (match_dup 5))])])
14779 (define_insn "fist<mode>2_<rounding>"
14780   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14781         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14782                       FIST_ROUNDING))
14783    (use (match_operand:HI 2 "memory_operand" "m"))
14784    (use (match_operand:HI 3 "memory_operand" "m"))]
14785   "TARGET_USE_FANCY_MATH_387
14786    && flag_unsafe_math_optimizations"
14787   "* return output_fix_trunc (insn, operands, false);"
14788   [(set_attr "type" "fistp")
14789    (set_attr "i387_cw" "<rounding>")
14790    (set_attr "mode" "<MODE>")])
14792 (define_insn "fist<mode>2_<rounding>_with_temp"
14793   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14794         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14795                       FIST_ROUNDING))
14796    (use (match_operand:HI 2 "memory_operand" "m,m"))
14797    (use (match_operand:HI 3 "memory_operand" "m,m"))
14798    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14799   "TARGET_USE_FANCY_MATH_387
14800    && flag_unsafe_math_optimizations"
14801   "#"
14802   [(set_attr "type" "fistp")
14803    (set_attr "i387_cw" "<rounding>")
14804    (set_attr "mode" "<MODE>")])
14806 (define_split
14807   [(set (match_operand:SWI24 0 "register_operand")
14808         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14809                       FIST_ROUNDING))
14810    (use (match_operand:HI 2 "memory_operand"))
14811    (use (match_operand:HI 3 "memory_operand"))
14812    (clobber (match_operand:SWI24 4 "memory_operand"))]
14813   "reload_completed"
14814   [(parallel [(set (match_dup 4)
14815                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14816               (use (match_dup 2))
14817               (use (match_dup 3))])
14818    (set (match_dup 0) (match_dup 4))])
14820 (define_split
14821   [(set (match_operand:SWI24 0 "memory_operand")
14822         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14823                       FIST_ROUNDING))
14824    (use (match_operand:HI 2 "memory_operand"))
14825    (use (match_operand:HI 3 "memory_operand"))
14826    (clobber (match_operand:SWI24 4 "memory_operand"))]
14827   "reload_completed"
14828   [(parallel [(set (match_dup 0)
14829                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14830               (use (match_dup 2))
14831               (use (match_dup 3))])])
14833 (define_expand "l<rounding_insn>xf<mode>2"
14834   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14835                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14836                                    FIST_ROUNDING))
14837               (clobber (reg:CC FLAGS_REG))])]
14838   "TARGET_USE_FANCY_MATH_387
14839    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14840    && flag_unsafe_math_optimizations")
14842 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
14843   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
14844                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14845                                  FIST_ROUNDING))
14846               (clobber (reg:CC FLAGS_REG))])]
14847   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14848    && !flag_trapping_math"
14850   if (TARGET_64BIT && optimize_insn_for_size_p ())
14851     FAIL;
14853   if (ROUND_<ROUNDING> == ROUND_FLOOR)
14854     ix86_expand_lfloorceil (operands[0], operands[1], true);
14855   else if (ROUND_<ROUNDING> == ROUND_CEIL)
14856     ix86_expand_lfloorceil (operands[0], operands[1], false);
14857   else
14858     gcc_unreachable ();
14860   DONE;
14863 (define_insn "fxam<mode>2_i387"
14864   [(set (match_operand:HI 0 "register_operand" "=a")
14865         (unspec:HI
14866           [(match_operand:X87MODEF 1 "register_operand" "f")]
14867           UNSPEC_FXAM))]
14868   "TARGET_USE_FANCY_MATH_387"
14869   "fxam\n\tfnstsw\t%0"
14870   [(set_attr "type" "multi")
14871    (set_attr "length" "4")
14872    (set_attr "unit" "i387")
14873    (set_attr "mode" "<MODE>")])
14875 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14876   [(set (match_operand:HI 0 "register_operand")
14877         (unspec:HI
14878           [(match_operand:MODEF 1 "memory_operand")]
14879           UNSPEC_FXAM_MEM))]
14880   "TARGET_USE_FANCY_MATH_387
14881    && can_create_pseudo_p ()"
14882   "#"
14883   "&& 1"
14884   [(set (match_dup 2)(match_dup 1))
14885    (set (match_dup 0)
14886         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14888   operands[2] = gen_reg_rtx (<MODE>mode);
14890   MEM_VOLATILE_P (operands[1]) = 1;
14892   [(set_attr "type" "multi")
14893    (set_attr "unit" "i387")
14894    (set_attr "mode" "<MODE>")])
14896 (define_expand "isinfxf2"
14897   [(use (match_operand:SI 0 "register_operand"))
14898    (use (match_operand:XF 1 "register_operand"))]
14899   "TARGET_USE_FANCY_MATH_387
14900    && TARGET_C99_FUNCTIONS"
14902   rtx mask = GEN_INT (0x45);
14903   rtx val = GEN_INT (0x05);
14905   rtx cond;
14907   rtx scratch = gen_reg_rtx (HImode);
14908   rtx res = gen_reg_rtx (QImode);
14910   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14912   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14913   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14914   cond = gen_rtx_fmt_ee (EQ, QImode,
14915                          gen_rtx_REG (CCmode, FLAGS_REG),
14916                          const0_rtx);
14917   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14918   emit_insn (gen_zero_extendqisi2 (operands[0], res));
14919   DONE;
14922 (define_expand "isinf<mode>2"
14923   [(use (match_operand:SI 0 "register_operand"))
14924    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
14925   "TARGET_USE_FANCY_MATH_387
14926    && TARGET_C99_FUNCTIONS
14927    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14929   rtx mask = GEN_INT (0x45);
14930   rtx val = GEN_INT (0x05);
14932   rtx cond;
14934   rtx scratch = gen_reg_rtx (HImode);
14935   rtx res = gen_reg_rtx (QImode);
14937   /* Remove excess precision by forcing value through memory. */
14938   if (memory_operand (operands[1], VOIDmode))
14939     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14940   else
14941     {
14942       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14944       emit_move_insn (temp, operands[1]);
14945       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14946     }
14948   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14949   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14950   cond = gen_rtx_fmt_ee (EQ, QImode,
14951                          gen_rtx_REG (CCmode, FLAGS_REG),
14952                          const0_rtx);
14953   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14954   emit_insn (gen_zero_extendqisi2 (operands[0], res));
14955   DONE;
14958 (define_expand "signbitxf2"
14959   [(use (match_operand:SI 0 "register_operand"))
14960    (use (match_operand:XF 1 "register_operand"))]
14961   "TARGET_USE_FANCY_MATH_387"
14963   rtx scratch = gen_reg_rtx (HImode);
14965   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14966   emit_insn (gen_andsi3 (operands[0],
14967              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14968   DONE;
14971 (define_insn "movmsk_df"
14972   [(set (match_operand:SI 0 "register_operand" "=r")
14973         (unspec:SI
14974           [(match_operand:DF 1 "register_operand" "x")]
14975           UNSPEC_MOVMSK))]
14976   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
14977   "%vmovmskpd\t{%1, %0|%0, %1}"
14978   [(set_attr "type" "ssemov")
14979    (set_attr "prefix" "maybe_vex")
14980    (set_attr "mode" "DF")])
14982 ;; Use movmskpd in SSE mode to avoid store forwarding stall
14983 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
14984 (define_expand "signbitdf2"
14985   [(use (match_operand:SI 0 "register_operand"))
14986    (use (match_operand:DF 1 "register_operand"))]
14987   "TARGET_USE_FANCY_MATH_387
14988    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14990   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
14991     {
14992       emit_insn (gen_movmsk_df (operands[0], operands[1]));
14993       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
14994     }
14995   else
14996     {
14997       rtx scratch = gen_reg_rtx (HImode);
14999       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15000       emit_insn (gen_andsi3 (operands[0],
15001                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15002     }
15003   DONE;
15006 (define_expand "signbitsf2"
15007   [(use (match_operand:SI 0 "register_operand"))
15008    (use (match_operand:SF 1 "register_operand"))]
15009   "TARGET_USE_FANCY_MATH_387
15010    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15012   rtx scratch = gen_reg_rtx (HImode);
15014   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15015   emit_insn (gen_andsi3 (operands[0],
15016              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15017   DONE;
15020 ;; Block operation instructions
15022 (define_insn "cld"
15023   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15024   ""
15025   "cld"
15026   [(set_attr "length" "1")
15027    (set_attr "length_immediate" "0")
15028    (set_attr "modrm" "0")])
15030 (define_expand "movmem<mode>"
15031   [(use (match_operand:BLK 0 "memory_operand"))
15032    (use (match_operand:BLK 1 "memory_operand"))
15033    (use (match_operand:SWI48 2 "nonmemory_operand"))
15034    (use (match_operand:SWI48 3 "const_int_operand"))
15035    (use (match_operand:SI 4 "const_int_operand"))
15036    (use (match_operand:SI 5 "const_int_operand"))]
15037   ""
15039  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15040                          operands[4], operands[5]))
15041    DONE;
15042  else
15043    FAIL;
15046 ;; Most CPUs don't like single string operations
15047 ;; Handle this case here to simplify previous expander.
15049 (define_expand "strmov"
15050   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15051    (set (match_operand 1 "memory_operand") (match_dup 4))
15052    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15053               (clobber (reg:CC FLAGS_REG))])
15054    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15055               (clobber (reg:CC FLAGS_REG))])]
15056   ""
15058   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15060   /* If .md ever supports :P for Pmode, these can be directly
15061      in the pattern above.  */
15062   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15063   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15065   /* Can't use this if the user has appropriated esi or edi.  */
15066   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15067       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15068     {
15069       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15070                                       operands[2], operands[3],
15071                                       operands[5], operands[6]));
15072       DONE;
15073     }
15075   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15078 (define_expand "strmov_singleop"
15079   [(parallel [(set (match_operand 1 "memory_operand")
15080                    (match_operand 3 "memory_operand"))
15081               (set (match_operand 0 "register_operand")
15082                    (match_operand 4))
15083               (set (match_operand 2 "register_operand")
15084                    (match_operand 5))])]
15085   ""
15086   "ix86_current_function_needs_cld = 1;")
15088 (define_insn "*strmovdi_rex_1"
15089   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15090         (mem:DI (match_operand:P 3 "register_operand" "1")))
15091    (set (match_operand:P 0 "register_operand" "=D")
15092         (plus:P (match_dup 2)
15093                 (const_int 8)))
15094    (set (match_operand:P 1 "register_operand" "=S")
15095         (plus:P (match_dup 3)
15096                 (const_int 8)))]
15097   "TARGET_64BIT
15098    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15099   "%^movsq"
15100   [(set_attr "type" "str")
15101    (set_attr "memory" "both")
15102    (set_attr "mode" "DI")])
15104 (define_insn "*strmovsi_1"
15105   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15106         (mem:SI (match_operand:P 3 "register_operand" "1")))
15107    (set (match_operand:P 0 "register_operand" "=D")
15108         (plus:P (match_dup 2)
15109                 (const_int 4)))
15110    (set (match_operand:P 1 "register_operand" "=S")
15111         (plus:P (match_dup 3)
15112                 (const_int 4)))]
15113   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15114   "%^movs{l|d}"
15115   [(set_attr "type" "str")
15116    (set_attr "memory" "both")
15117    (set_attr "mode" "SI")])
15119 (define_insn "*strmovhi_1"
15120   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15121         (mem:HI (match_operand:P 3 "register_operand" "1")))
15122    (set (match_operand:P 0 "register_operand" "=D")
15123         (plus:P (match_dup 2)
15124                 (const_int 2)))
15125    (set (match_operand:P 1 "register_operand" "=S")
15126         (plus:P (match_dup 3)
15127                 (const_int 2)))]
15128   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15129   "%^movsw"
15130   [(set_attr "type" "str")
15131    (set_attr "memory" "both")
15132    (set_attr "mode" "HI")])
15134 (define_insn "*strmovqi_1"
15135   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15136         (mem:QI (match_operand:P 3 "register_operand" "1")))
15137    (set (match_operand:P 0 "register_operand" "=D")
15138         (plus:P (match_dup 2)
15139                 (const_int 1)))
15140    (set (match_operand:P 1 "register_operand" "=S")
15141         (plus:P (match_dup 3)
15142                 (const_int 1)))]
15143   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15144   "%^movsb"
15145   [(set_attr "type" "str")
15146    (set_attr "memory" "both")
15147    (set (attr "prefix_rex")
15148         (if_then_else
15149           (match_test "<P:MODE>mode == DImode")
15150           (const_string "0")
15151           (const_string "*")))
15152    (set_attr "mode" "QI")])
15154 (define_expand "rep_mov"
15155   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15156               (set (match_operand 0 "register_operand")
15157                    (match_operand 5))
15158               (set (match_operand 2 "register_operand")
15159                    (match_operand 6))
15160               (set (match_operand 1 "memory_operand")
15161                    (match_operand 3 "memory_operand"))
15162               (use (match_dup 4))])]
15163   ""
15164   "ix86_current_function_needs_cld = 1;")
15166 (define_insn "*rep_movdi_rex64"
15167   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15168    (set (match_operand:P 0 "register_operand" "=D")
15169         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15170                           (const_int 3))
15171                 (match_operand:P 3 "register_operand" "0")))
15172    (set (match_operand:P 1 "register_operand" "=S")
15173         (plus:P (ashift:P (match_dup 5) (const_int 3))
15174                 (match_operand:P 4 "register_operand" "1")))
15175    (set (mem:BLK (match_dup 3))
15176         (mem:BLK (match_dup 4)))
15177    (use (match_dup 5))]
15178   "TARGET_64BIT
15179    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15180   "%^rep{%;} movsq"
15181   [(set_attr "type" "str")
15182    (set_attr "prefix_rep" "1")
15183    (set_attr "memory" "both")
15184    (set_attr "mode" "DI")])
15186 (define_insn "*rep_movsi"
15187   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15188    (set (match_operand:P 0 "register_operand" "=D")
15189         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15190                           (const_int 2))
15191                  (match_operand:P 3 "register_operand" "0")))
15192    (set (match_operand:P 1 "register_operand" "=S")
15193         (plus:P (ashift:P (match_dup 5) (const_int 2))
15194                 (match_operand:P 4 "register_operand" "1")))
15195    (set (mem:BLK (match_dup 3))
15196         (mem:BLK (match_dup 4)))
15197    (use (match_dup 5))]
15198   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15199   "%^rep{%;} movs{l|d}"
15200   [(set_attr "type" "str")
15201    (set_attr "prefix_rep" "1")
15202    (set_attr "memory" "both")
15203    (set_attr "mode" "SI")])
15205 (define_insn "*rep_movqi"
15206   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15207    (set (match_operand:P 0 "register_operand" "=D")
15208         (plus:P (match_operand:P 3 "register_operand" "0")
15209                 (match_operand:P 5 "register_operand" "2")))
15210    (set (match_operand:P 1 "register_operand" "=S")
15211         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15212    (set (mem:BLK (match_dup 3))
15213         (mem:BLK (match_dup 4)))
15214    (use (match_dup 5))]
15215   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15216   "%^rep{%;} movsb"
15217   [(set_attr "type" "str")
15218    (set_attr "prefix_rep" "1")
15219    (set_attr "memory" "both")
15220    (set_attr "mode" "QI")])
15222 (define_expand "setmem<mode>"
15223    [(use (match_operand:BLK 0 "memory_operand"))
15224     (use (match_operand:SWI48 1 "nonmemory_operand"))
15225     (use (match_operand:QI 2 "nonmemory_operand"))
15226     (use (match_operand 3 "const_int_operand"))
15227     (use (match_operand:SI 4 "const_int_operand"))
15228     (use (match_operand:SI 5 "const_int_operand"))]
15229   ""
15231  if (ix86_expand_setmem (operands[0], operands[1],
15232                          operands[2], operands[3],
15233                          operands[4], operands[5]))
15234    DONE;
15235  else
15236    FAIL;
15239 ;; Most CPUs don't like single string operations
15240 ;; Handle this case here to simplify previous expander.
15242 (define_expand "strset"
15243   [(set (match_operand 1 "memory_operand")
15244         (match_operand 2 "register_operand"))
15245    (parallel [(set (match_operand 0 "register_operand")
15246                    (match_dup 3))
15247               (clobber (reg:CC FLAGS_REG))])]
15248   ""
15250   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15251     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15253   /* If .md ever supports :P for Pmode, this can be directly
15254      in the pattern above.  */
15255   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15256                               GEN_INT (GET_MODE_SIZE (GET_MODE
15257                                                       (operands[2]))));
15258   /* Can't use this if the user has appropriated eax or edi.  */
15259   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15260       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15261     {
15262       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15263                                       operands[3]));
15264       DONE;
15265     }
15268 (define_expand "strset_singleop"
15269   [(parallel [(set (match_operand 1 "memory_operand")
15270                    (match_operand 2 "register_operand"))
15271               (set (match_operand 0 "register_operand")
15272                    (match_operand 3))
15273               (unspec [(const_int 0)] UNSPEC_STOS)])]
15274   ""
15275   "ix86_current_function_needs_cld = 1;")
15277 (define_insn "*strsetdi_rex_1"
15278   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15279         (match_operand:DI 2 "register_operand" "a"))
15280    (set (match_operand:P 0 "register_operand" "=D")
15281         (plus:P (match_dup 1)
15282                 (const_int 8)))
15283    (unspec [(const_int 0)] UNSPEC_STOS)]
15284   "TARGET_64BIT
15285    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15286   "%^stosq"
15287   [(set_attr "type" "str")
15288    (set_attr "memory" "store")
15289    (set_attr "mode" "DI")])
15291 (define_insn "*strsetsi_1"
15292   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15293         (match_operand:SI 2 "register_operand" "a"))
15294    (set (match_operand:P 0 "register_operand" "=D")
15295         (plus:P (match_dup 1)
15296                 (const_int 4)))
15297    (unspec [(const_int 0)] UNSPEC_STOS)]
15298   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15299   "%^stos{l|d}"
15300   [(set_attr "type" "str")
15301    (set_attr "memory" "store")
15302    (set_attr "mode" "SI")])
15304 (define_insn "*strsethi_1"
15305   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15306         (match_operand:HI 2 "register_operand" "a"))
15307    (set (match_operand:P 0 "register_operand" "=D")
15308         (plus:P (match_dup 1)
15309                 (const_int 2)))
15310    (unspec [(const_int 0)] UNSPEC_STOS)]
15311   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15312   "%^stosw"
15313   [(set_attr "type" "str")
15314    (set_attr "memory" "store")
15315    (set_attr "mode" "HI")])
15317 (define_insn "*strsetqi_1"
15318   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15319         (match_operand:QI 2 "register_operand" "a"))
15320    (set (match_operand:P 0 "register_operand" "=D")
15321         (plus:P (match_dup 1)
15322                 (const_int 1)))
15323    (unspec [(const_int 0)] UNSPEC_STOS)]
15324   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15325   "%^stosb"
15326   [(set_attr "type" "str")
15327    (set_attr "memory" "store")
15328    (set (attr "prefix_rex")
15329         (if_then_else
15330           (match_test "<P:MODE>mode == DImode")
15331           (const_string "0")
15332           (const_string "*")))
15333    (set_attr "mode" "QI")])
15335 (define_expand "rep_stos"
15336   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15337               (set (match_operand 0 "register_operand")
15338                    (match_operand 4))
15339               (set (match_operand 2 "memory_operand") (const_int 0))
15340               (use (match_operand 3 "register_operand"))
15341               (use (match_dup 1))])]
15342   ""
15343   "ix86_current_function_needs_cld = 1;")
15345 (define_insn "*rep_stosdi_rex64"
15346   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15347    (set (match_operand:P 0 "register_operand" "=D")
15348         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15349                           (const_int 3))
15350                  (match_operand:P 3 "register_operand" "0")))
15351    (set (mem:BLK (match_dup 3))
15352         (const_int 0))
15353    (use (match_operand:DI 2 "register_operand" "a"))
15354    (use (match_dup 4))]
15355   "TARGET_64BIT
15356    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15357   "%^rep{%;} stosq"
15358   [(set_attr "type" "str")
15359    (set_attr "prefix_rep" "1")
15360    (set_attr "memory" "store")
15361    (set_attr "mode" "DI")])
15363 (define_insn "*rep_stossi"
15364   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15365    (set (match_operand:P 0 "register_operand" "=D")
15366         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15367                           (const_int 2))
15368                  (match_operand:P 3 "register_operand" "0")))
15369    (set (mem:BLK (match_dup 3))
15370         (const_int 0))
15371    (use (match_operand:SI 2 "register_operand" "a"))
15372    (use (match_dup 4))]
15373   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15374   "%^rep{%;} stos{l|d}"
15375   [(set_attr "type" "str")
15376    (set_attr "prefix_rep" "1")
15377    (set_attr "memory" "store")
15378    (set_attr "mode" "SI")])
15380 (define_insn "*rep_stosqi"
15381   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15382    (set (match_operand:P 0 "register_operand" "=D")
15383         (plus:P (match_operand:P 3 "register_operand" "0")
15384                 (match_operand:P 4 "register_operand" "1")))
15385    (set (mem:BLK (match_dup 3))
15386         (const_int 0))
15387    (use (match_operand:QI 2 "register_operand" "a"))
15388    (use (match_dup 4))]
15389   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15390   "%^rep{%;} stosb"
15391   [(set_attr "type" "str")
15392    (set_attr "prefix_rep" "1")
15393    (set_attr "memory" "store")
15394    (set (attr "prefix_rex")
15395         (if_then_else
15396           (match_test "<P:MODE>mode == DImode")
15397           (const_string "0")
15398           (const_string "*")))
15399    (set_attr "mode" "QI")])
15401 (define_expand "cmpstrnsi"
15402   [(set (match_operand:SI 0 "register_operand")
15403         (compare:SI (match_operand:BLK 1 "general_operand")
15404                     (match_operand:BLK 2 "general_operand")))
15405    (use (match_operand 3 "general_operand"))
15406    (use (match_operand 4 "immediate_operand"))]
15407   ""
15409   rtx addr1, addr2, out, outlow, count, countreg, align;
15411   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15412     FAIL;
15414   /* Can't use this if the user has appropriated ecx, esi or edi.  */
15415   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15416     FAIL;
15418   out = operands[0];
15419   if (!REG_P (out))
15420     out = gen_reg_rtx (SImode);
15422   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15423   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15424   if (addr1 != XEXP (operands[1], 0))
15425     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15426   if (addr2 != XEXP (operands[2], 0))
15427     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15429   count = operands[3];
15430   countreg = ix86_zero_extend_to_Pmode (count);
15432   /* %%% Iff we are testing strict equality, we can use known alignment
15433      to good advantage.  This may be possible with combine, particularly
15434      once cc0 is dead.  */
15435   align = operands[4];
15437   if (CONST_INT_P (count))
15438     {
15439       if (INTVAL (count) == 0)
15440         {
15441           emit_move_insn (operands[0], const0_rtx);
15442           DONE;
15443         }
15444       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15445                                      operands[1], operands[2]));
15446     }
15447   else
15448     {
15449       rtx (*gen_cmp) (rtx, rtx);
15451       gen_cmp = (TARGET_64BIT
15452                  ? gen_cmpdi_1 : gen_cmpsi_1);
15454       emit_insn (gen_cmp (countreg, countreg));
15455       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15456                                   operands[1], operands[2]));
15457     }
15459   outlow = gen_lowpart (QImode, out);
15460   emit_insn (gen_cmpintqi (outlow));
15461   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15463   if (operands[0] != out)
15464     emit_move_insn (operands[0], out);
15466   DONE;
15469 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15471 (define_expand "cmpintqi"
15472   [(set (match_dup 1)
15473         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15474    (set (match_dup 2)
15475         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15476    (parallel [(set (match_operand:QI 0 "register_operand")
15477                    (minus:QI (match_dup 1)
15478                              (match_dup 2)))
15479               (clobber (reg:CC FLAGS_REG))])]
15480   ""
15482   operands[1] = gen_reg_rtx (QImode);
15483   operands[2] = gen_reg_rtx (QImode);
15486 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15487 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15489 (define_expand "cmpstrnqi_nz_1"
15490   [(parallel [(set (reg:CC FLAGS_REG)
15491                    (compare:CC (match_operand 4 "memory_operand")
15492                                (match_operand 5 "memory_operand")))
15493               (use (match_operand 2 "register_operand"))
15494               (use (match_operand:SI 3 "immediate_operand"))
15495               (clobber (match_operand 0 "register_operand"))
15496               (clobber (match_operand 1 "register_operand"))
15497               (clobber (match_dup 2))])]
15498   ""
15499   "ix86_current_function_needs_cld = 1;")
15501 (define_insn "*cmpstrnqi_nz_1"
15502   [(set (reg:CC FLAGS_REG)
15503         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15504                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15505    (use (match_operand:P 6 "register_operand" "2"))
15506    (use (match_operand:SI 3 "immediate_operand" "i"))
15507    (clobber (match_operand:P 0 "register_operand" "=S"))
15508    (clobber (match_operand:P 1 "register_operand" "=D"))
15509    (clobber (match_operand:P 2 "register_operand" "=c"))]
15510   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15511   "%^repz{%;} cmpsb"
15512   [(set_attr "type" "str")
15513    (set_attr "mode" "QI")
15514    (set (attr "prefix_rex")
15515         (if_then_else
15516           (match_test "<P:MODE>mode == DImode")
15517           (const_string "0")
15518           (const_string "*")))
15519    (set_attr "prefix_rep" "1")])
15521 ;; The same, but the count is not known to not be zero.
15523 (define_expand "cmpstrnqi_1"
15524   [(parallel [(set (reg:CC FLAGS_REG)
15525                 (if_then_else:CC (ne (match_operand 2 "register_operand")
15526                                      (const_int 0))
15527                   (compare:CC (match_operand 4 "memory_operand")
15528                               (match_operand 5 "memory_operand"))
15529                   (const_int 0)))
15530               (use (match_operand:SI 3 "immediate_operand"))
15531               (use (reg:CC FLAGS_REG))
15532               (clobber (match_operand 0 "register_operand"))
15533               (clobber (match_operand 1 "register_operand"))
15534               (clobber (match_dup 2))])]
15535   ""
15536   "ix86_current_function_needs_cld = 1;")
15538 (define_insn "*cmpstrnqi_1"
15539   [(set (reg:CC FLAGS_REG)
15540         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15541                              (const_int 0))
15542           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15543                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15544           (const_int 0)))
15545    (use (match_operand:SI 3 "immediate_operand" "i"))
15546    (use (reg:CC FLAGS_REG))
15547    (clobber (match_operand:P 0 "register_operand" "=S"))
15548    (clobber (match_operand:P 1 "register_operand" "=D"))
15549    (clobber (match_operand:P 2 "register_operand" "=c"))]
15550   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15551   "%^repz{%;} cmpsb"
15552   [(set_attr "type" "str")
15553    (set_attr "mode" "QI")
15554    (set (attr "prefix_rex")
15555         (if_then_else
15556           (match_test "<P:MODE>mode == DImode")
15557           (const_string "0")
15558           (const_string "*")))
15559    (set_attr "prefix_rep" "1")])
15561 (define_expand "strlen<mode>"
15562   [(set (match_operand:P 0 "register_operand")
15563         (unspec:P [(match_operand:BLK 1 "general_operand")
15564                    (match_operand:QI 2 "immediate_operand")
15565                    (match_operand 3 "immediate_operand")]
15566                   UNSPEC_SCAS))]
15567   ""
15569  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15570    DONE;
15571  else
15572    FAIL;
15575 (define_expand "strlenqi_1"
15576   [(parallel [(set (match_operand 0 "register_operand")
15577                    (match_operand 2))
15578               (clobber (match_operand 1 "register_operand"))
15579               (clobber (reg:CC FLAGS_REG))])]
15580   ""
15581   "ix86_current_function_needs_cld = 1;")
15583 (define_insn "*strlenqi_1"
15584   [(set (match_operand:P 0 "register_operand" "=&c")
15585         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15586                    (match_operand:QI 2 "register_operand" "a")
15587                    (match_operand:P 3 "immediate_operand" "i")
15588                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15589    (clobber (match_operand:P 1 "register_operand" "=D"))
15590    (clobber (reg:CC FLAGS_REG))]
15591   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15592   "%^repnz{%;} scasb"
15593   [(set_attr "type" "str")
15594    (set_attr "mode" "QI")
15595    (set (attr "prefix_rex")
15596         (if_then_else
15597           (match_test "<P:MODE>mode == DImode")
15598           (const_string "0")
15599           (const_string "*")))
15600    (set_attr "prefix_rep" "1")])
15602 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15603 ;; handled in combine, but it is not currently up to the task.
15604 ;; When used for their truth value, the cmpstrn* expanders generate
15605 ;; code like this:
15607 ;;   repz cmpsb
15608 ;;   seta       %al
15609 ;;   setb       %dl
15610 ;;   cmpb       %al, %dl
15611 ;;   jcc        label
15613 ;; The intermediate three instructions are unnecessary.
15615 ;; This one handles cmpstrn*_nz_1...
15616 (define_peephole2
15617   [(parallel[
15618      (set (reg:CC FLAGS_REG)
15619           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15620                       (mem:BLK (match_operand 5 "register_operand"))))
15621      (use (match_operand 6 "register_operand"))
15622      (use (match_operand:SI 3 "immediate_operand"))
15623      (clobber (match_operand 0 "register_operand"))
15624      (clobber (match_operand 1 "register_operand"))
15625      (clobber (match_operand 2 "register_operand"))])
15626    (set (match_operand:QI 7 "register_operand")
15627         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15628    (set (match_operand:QI 8 "register_operand")
15629         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15630    (set (reg FLAGS_REG)
15631         (compare (match_dup 7) (match_dup 8)))
15632   ]
15633   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15634   [(parallel[
15635      (set (reg:CC FLAGS_REG)
15636           (compare:CC (mem:BLK (match_dup 4))
15637                       (mem:BLK (match_dup 5))))
15638      (use (match_dup 6))
15639      (use (match_dup 3))
15640      (clobber (match_dup 0))
15641      (clobber (match_dup 1))
15642      (clobber (match_dup 2))])])
15644 ;; ...and this one handles cmpstrn*_1.
15645 (define_peephole2
15646   [(parallel[
15647      (set (reg:CC FLAGS_REG)
15648           (if_then_else:CC (ne (match_operand 6 "register_operand")
15649                                (const_int 0))
15650             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15651                         (mem:BLK (match_operand 5 "register_operand")))
15652             (const_int 0)))
15653      (use (match_operand:SI 3 "immediate_operand"))
15654      (use (reg:CC FLAGS_REG))
15655      (clobber (match_operand 0 "register_operand"))
15656      (clobber (match_operand 1 "register_operand"))
15657      (clobber (match_operand 2 "register_operand"))])
15658    (set (match_operand:QI 7 "register_operand")
15659         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15660    (set (match_operand:QI 8 "register_operand")
15661         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15662    (set (reg FLAGS_REG)
15663         (compare (match_dup 7) (match_dup 8)))
15664   ]
15665   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15666   [(parallel[
15667      (set (reg:CC FLAGS_REG)
15668           (if_then_else:CC (ne (match_dup 6)
15669                                (const_int 0))
15670             (compare:CC (mem:BLK (match_dup 4))
15671                         (mem:BLK (match_dup 5)))
15672             (const_int 0)))
15673      (use (match_dup 3))
15674      (use (reg:CC FLAGS_REG))
15675      (clobber (match_dup 0))
15676      (clobber (match_dup 1))
15677      (clobber (match_dup 2))])])
15679 ;; Conditional move instructions.
15681 (define_expand "mov<mode>cc"
15682   [(set (match_operand:SWIM 0 "register_operand")
15683         (if_then_else:SWIM (match_operand 1 "comparison_operator")
15684                            (match_operand:SWIM 2 "<general_operand>")
15685                            (match_operand:SWIM 3 "<general_operand>")))]
15686   ""
15687   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15689 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15690 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15691 ;; So just document what we're doing explicitly.
15693 (define_expand "x86_mov<mode>cc_0_m1"
15694   [(parallel
15695     [(set (match_operand:SWI48 0 "register_operand")
15696           (if_then_else:SWI48
15697             (match_operator:SWI48 2 "ix86_carry_flag_operator"
15698              [(match_operand 1 "flags_reg_operand")
15699               (const_int 0)])
15700             (const_int -1)
15701             (const_int 0)))
15702      (clobber (reg:CC FLAGS_REG))])])
15704 (define_insn "*x86_mov<mode>cc_0_m1"
15705   [(set (match_operand:SWI48 0 "register_operand" "=r")
15706         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15707                              [(reg FLAGS_REG) (const_int 0)])
15708           (const_int -1)
15709           (const_int 0)))
15710    (clobber (reg:CC FLAGS_REG))]
15711   ""
15712   "sbb{<imodesuffix>}\t%0, %0"
15713   ; Since we don't have the proper number of operands for an alu insn,
15714   ; fill in all the blanks.
15715   [(set_attr "type" "alu")
15716    (set_attr "use_carry" "1")
15717    (set_attr "pent_pair" "pu")
15718    (set_attr "memory" "none")
15719    (set_attr "imm_disp" "false")
15720    (set_attr "mode" "<MODE>")
15721    (set_attr "length_immediate" "0")])
15723 (define_insn "*x86_mov<mode>cc_0_m1_se"
15724   [(set (match_operand:SWI48 0 "register_operand" "=r")
15725         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15726                              [(reg FLAGS_REG) (const_int 0)])
15727                             (const_int 1)
15728                             (const_int 0)))
15729    (clobber (reg:CC FLAGS_REG))]
15730   ""
15731   "sbb{<imodesuffix>}\t%0, %0"
15732   [(set_attr "type" "alu")
15733    (set_attr "use_carry" "1")
15734    (set_attr "pent_pair" "pu")
15735    (set_attr "memory" "none")
15736    (set_attr "imm_disp" "false")
15737    (set_attr "mode" "<MODE>")
15738    (set_attr "length_immediate" "0")])
15740 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15741   [(set (match_operand:SWI48 0 "register_operand" "=r")
15742         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15743                     [(reg FLAGS_REG) (const_int 0)])))
15744    (clobber (reg:CC FLAGS_REG))]
15745   ""
15746   "sbb{<imodesuffix>}\t%0, %0"
15747   [(set_attr "type" "alu")
15748    (set_attr "use_carry" "1")
15749    (set_attr "pent_pair" "pu")
15750    (set_attr "memory" "none")
15751    (set_attr "imm_disp" "false")
15752    (set_attr "mode" "<MODE>")
15753    (set_attr "length_immediate" "0")])
15755 (define_insn "*mov<mode>cc_noc"
15756   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15757         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15758                                [(reg FLAGS_REG) (const_int 0)])
15759           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15760           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15761   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15762   "@
15763    cmov%O2%C1\t{%2, %0|%0, %2}
15764    cmov%O2%c1\t{%3, %0|%0, %3}"
15765   [(set_attr "type" "icmov")
15766    (set_attr "mode" "<MODE>")])
15768 ;; Don't do conditional moves with memory inputs.  This splitter helps
15769 ;; register starved x86_32 by forcing inputs into registers before reload.
15770 (define_split
15771   [(set (match_operand:SWI248 0 "register_operand")
15772         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15773                                [(reg FLAGS_REG) (const_int 0)])
15774           (match_operand:SWI248 2 "nonimmediate_operand")
15775           (match_operand:SWI248 3 "nonimmediate_operand")))]
15776   "!TARGET_64BIT && TARGET_CMOVE
15777    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15778    && (MEM_P (operands[2]) || MEM_P (operands[3]))
15779    && can_create_pseudo_p ()
15780    && optimize_insn_for_speed_p ()"
15781   [(set (match_dup 0)
15782         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
15784   if (MEM_P (operands[2]))
15785     operands[2] = force_reg (<MODE>mode, operands[2]);
15786   if (MEM_P (operands[3]))
15787     operands[3] = force_reg (<MODE>mode, operands[3]);
15790 (define_insn "*movqicc_noc"
15791   [(set (match_operand:QI 0 "register_operand" "=r,r")
15792         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15793                            [(reg FLAGS_REG) (const_int 0)])
15794                       (match_operand:QI 2 "register_operand" "r,0")
15795                       (match_operand:QI 3 "register_operand" "0,r")))]
15796   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15797   "#"
15798   [(set_attr "type" "icmov")
15799    (set_attr "mode" "QI")])
15801 (define_split
15802   [(set (match_operand:SWI12 0 "register_operand")
15803         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
15804                               [(reg FLAGS_REG) (const_int 0)])
15805                       (match_operand:SWI12 2 "register_operand")
15806                       (match_operand:SWI12 3 "register_operand")))]
15807   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
15808    && reload_completed"
15809   [(set (match_dup 0)
15810         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
15812   operands[0] = gen_lowpart (SImode, operands[0]);
15813   operands[2] = gen_lowpart (SImode, operands[2]);
15814   operands[3] = gen_lowpart (SImode, operands[3]);
15817 ;; Don't do conditional moves with memory inputs
15818 (define_peephole2
15819   [(match_scratch:SWI248 2 "r")
15820    (set (match_operand:SWI248 0 "register_operand")
15821         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15822                                [(reg FLAGS_REG) (const_int 0)])
15823           (match_dup 0)
15824           (match_operand:SWI248 3 "memory_operand")))]
15825   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15826    && optimize_insn_for_speed_p ()"
15827   [(set (match_dup 2) (match_dup 3))
15828    (set (match_dup 0)
15829         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
15831 (define_peephole2
15832   [(match_scratch:SWI248 2 "r")
15833    (set (match_operand:SWI248 0 "register_operand")
15834         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15835                                [(reg FLAGS_REG) (const_int 0)])
15836           (match_operand:SWI248 3 "memory_operand")
15837           (match_dup 0)))]
15838   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15839    && optimize_insn_for_speed_p ()"
15840   [(set (match_dup 2) (match_dup 3))
15841    (set (match_dup 0)
15842         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
15844 (define_expand "mov<mode>cc"
15845   [(set (match_operand:X87MODEF 0 "register_operand")
15846         (if_then_else:X87MODEF
15847           (match_operand 1 "comparison_operator")
15848           (match_operand:X87MODEF 2 "register_operand")
15849           (match_operand:X87MODEF 3 "register_operand")))]
15850   "(TARGET_80387 && TARGET_CMOVE)
15851    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15852   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15854 (define_insn "*movxfcc_1"
15855   [(set (match_operand:XF 0 "register_operand" "=f,f")
15856         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15857                                 [(reg FLAGS_REG) (const_int 0)])
15858                       (match_operand:XF 2 "register_operand" "f,0")
15859                       (match_operand:XF 3 "register_operand" "0,f")))]
15860   "TARGET_80387 && TARGET_CMOVE"
15861   "@
15862    fcmov%F1\t{%2, %0|%0, %2}
15863    fcmov%f1\t{%3, %0|%0, %3}"
15864   [(set_attr "type" "fcmov")
15865    (set_attr "mode" "XF")])
15867 (define_insn "*movdfcc_1"
15868   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
15869         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15870                                 [(reg FLAGS_REG) (const_int 0)])
15871                       (match_operand:DF 2 "nonimmediate_operand"
15872                                                "f ,0,rm,0 ,rm,0")
15873                       (match_operand:DF 3 "nonimmediate_operand"
15874                                                "0 ,f,0 ,rm,0, rm")))]
15875   "TARGET_80387 && TARGET_CMOVE
15876    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15877   "@
15878    fcmov%F1\t{%2, %0|%0, %2}
15879    fcmov%f1\t{%3, %0|%0, %3}
15880    #
15881    #
15882    cmov%O2%C1\t{%2, %0|%0, %2}
15883    cmov%O2%c1\t{%3, %0|%0, %3}"
15884   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
15885    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
15886    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
15888 (define_split
15889   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
15890         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15891                                 [(reg FLAGS_REG) (const_int 0)])
15892                       (match_operand:DF 2 "nonimmediate_operand")
15893                       (match_operand:DF 3 "nonimmediate_operand")))]
15894   "!TARGET_64BIT && reload_completed"
15895   [(set (match_dup 2)
15896         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
15897    (set (match_dup 3)
15898         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
15900   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
15901   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
15904 (define_insn "*movsfcc_1_387"
15905   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15906         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15907                                 [(reg FLAGS_REG) (const_int 0)])
15908                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15909                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15910   "TARGET_80387 && TARGET_CMOVE
15911    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15912   "@
15913    fcmov%F1\t{%2, %0|%0, %2}
15914    fcmov%f1\t{%3, %0|%0, %3}
15915    cmov%O2%C1\t{%2, %0|%0, %2}
15916    cmov%O2%c1\t{%3, %0|%0, %3}"
15917   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15918    (set_attr "mode" "SF,SF,SI,SI")])
15920 ;; Don't do conditional moves with memory inputs.  This splitter helps
15921 ;; register starved x86_32 by forcing inputs into registers before reload.
15922 (define_split
15923   [(set (match_operand:MODEF 0 "register_operand")
15924         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
15925                               [(reg FLAGS_REG) (const_int 0)])
15926           (match_operand:MODEF 2 "nonimmediate_operand")
15927           (match_operand:MODEF 3 "nonimmediate_operand")))]
15928   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15929    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15930    && (MEM_P (operands[2]) || MEM_P (operands[3]))
15931    && can_create_pseudo_p ()
15932    && optimize_insn_for_speed_p ()"
15933   [(set (match_dup 0)
15934         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
15936   if (MEM_P (operands[2]))
15937     operands[2] = force_reg (<MODE>mode, operands[2]);
15938   if (MEM_P (operands[3]))
15939     operands[3] = force_reg (<MODE>mode, operands[3]);
15942 ;; Don't do conditional moves with memory inputs
15943 (define_peephole2
15944   [(match_scratch:MODEF 2 "r")
15945    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15946         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15947                               [(reg FLAGS_REG) (const_int 0)])
15948           (match_dup 0)
15949           (match_operand:MODEF 3 "memory_operand")))]
15950   "(<MODE>mode != DFmode || TARGET_64BIT)
15951    && TARGET_80387 && TARGET_CMOVE
15952    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15953    && optimize_insn_for_speed_p ()"
15954   [(set (match_dup 2) (match_dup 3))
15955    (set (match_dup 0)
15956         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
15958 (define_peephole2
15959   [(match_scratch:MODEF 2 "r")
15960    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15961         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15962                               [(reg FLAGS_REG) (const_int 0)])
15963           (match_operand:MODEF 3 "memory_operand")
15964           (match_dup 0)))]
15965   "(<MODE>mode != DFmode || TARGET_64BIT)
15966    && TARGET_80387 && TARGET_CMOVE
15967    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15968    && optimize_insn_for_speed_p ()"
15969   [(set (match_dup 2) (match_dup 3))
15970    (set (match_dup 0)
15971         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
15973 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
15974 ;; the scalar versions to have only XMM registers as operands.
15976 ;; XOP conditional move
15977 (define_insn "*xop_pcmov_<mode>"
15978   [(set (match_operand:MODEF 0 "register_operand" "=x")
15979         (if_then_else:MODEF
15980           (match_operand:MODEF 1 "register_operand" "x")
15981           (match_operand:MODEF 2 "register_operand" "x")
15982           (match_operand:MODEF 3 "register_operand" "x")))]
15983   "TARGET_XOP"
15984   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
15985   [(set_attr "type" "sse4arg")])
15987 ;; These versions of the min/max patterns are intentionally ignorant of
15988 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
15989 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
15990 ;; are undefined in this condition, we're certain this is correct.
15992 (define_insn "<code><mode>3"
15993   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
15994         (smaxmin:MODEF
15995           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15996           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
15997   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15998   "@
15999    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16000    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16001   [(set_attr "isa" "noavx,avx")
16002    (set_attr "prefix" "orig,vex")
16003    (set_attr "type" "sseadd")
16004    (set_attr "mode" "<MODE>")])
16006 ;; These versions of the min/max patterns implement exactly the operations
16007 ;;   min = (op1 < op2 ? op1 : op2)
16008 ;;   max = (!(op1 < op2) ? op1 : op2)
16009 ;; Their operands are not commutative, and thus they may be used in the
16010 ;; presence of -0.0 and NaN.
16012 (define_int_iterator IEEE_MAXMIN
16013         [UNSPEC_IEEE_MAX
16014          UNSPEC_IEEE_MIN])
16016 (define_int_attr ieee_maxmin
16017         [(UNSPEC_IEEE_MAX "max")
16018          (UNSPEC_IEEE_MIN "min")])
16020 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16021   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16022         (unspec:MODEF
16023           [(match_operand:MODEF 1 "register_operand" "0,x")
16024            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16025           IEEE_MAXMIN))]
16026   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16027   "@
16028    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16029    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16030   [(set_attr "isa" "noavx,avx")
16031    (set_attr "prefix" "orig,vex")
16032    (set_attr "type" "sseadd")
16033    (set_attr "mode" "<MODE>")])
16035 ;; Make two stack loads independent:
16036 ;;   fld aa              fld aa
16037 ;;   fld %st(0)     ->   fld bb
16038 ;;   fmul bb             fmul %st(1), %st
16040 ;; Actually we only match the last two instructions for simplicity.
16041 (define_peephole2
16042   [(set (match_operand 0 "fp_register_operand")
16043         (match_operand 1 "fp_register_operand"))
16044    (set (match_dup 0)
16045         (match_operator 2 "binary_fp_operator"
16046            [(match_dup 0)
16047             (match_operand 3 "memory_operand")]))]
16048   "REGNO (operands[0]) != REGNO (operands[1])"
16049   [(set (match_dup 0) (match_dup 3))
16050    (set (match_dup 0) (match_dup 4))]
16052   ;; The % modifier is not operational anymore in peephole2's, so we have to
16053   ;; swap the operands manually in the case of addition and multiplication.
16055   rtx op0, op1;
16057   if (COMMUTATIVE_ARITH_P (operands[2]))
16058     op0 = operands[0], op1 = operands[1];
16059   else
16060     op0 = operands[1], op1 = operands[0];
16062   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16063                                 GET_MODE (operands[2]),
16064                                 op0, op1);
16067 ;; Conditional addition patterns
16068 (define_expand "add<mode>cc"
16069   [(match_operand:SWI 0 "register_operand")
16070    (match_operand 1 "ordered_comparison_operator")
16071    (match_operand:SWI 2 "register_operand")
16072    (match_operand:SWI 3 "const_int_operand")]
16073   ""
16074   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16076 ;; Misc patterns (?)
16078 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16079 ;; Otherwise there will be nothing to keep
16081 ;; [(set (reg ebp) (reg esp))]
16082 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16083 ;;  (clobber (eflags)]
16084 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16086 ;; in proper program order.
16088 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16089   [(set (match_operand:P 0 "register_operand" "=r,r")
16090         (plus:P (match_operand:P 1 "register_operand" "0,r")
16091                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16092    (clobber (reg:CC FLAGS_REG))
16093    (clobber (mem:BLK (scratch)))]
16094   ""
16096   switch (get_attr_type (insn))
16097     {
16098     case TYPE_IMOV:
16099       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16101     case TYPE_ALU:
16102       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16103       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16104         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16106       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16108     default:
16109       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16110       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16111     }
16113   [(set (attr "type")
16114         (cond [(and (eq_attr "alternative" "0")
16115                     (not (match_test "TARGET_OPT_AGU")))
16116                  (const_string "alu")
16117                (match_operand:<MODE> 2 "const0_operand")
16118                  (const_string "imov")
16119               ]
16120               (const_string "lea")))
16121    (set (attr "length_immediate")
16122         (cond [(eq_attr "type" "imov")
16123                  (const_string "0")
16124                (and (eq_attr "type" "alu")
16125                     (match_operand 2 "const128_operand"))
16126                  (const_string "1")
16127               ]
16128               (const_string "*")))
16129    (set_attr "mode" "<MODE>")])
16131 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16132   [(set (match_operand:P 0 "register_operand" "=r")
16133         (minus:P (match_operand:P 1 "register_operand" "0")
16134                  (match_operand:P 2 "register_operand" "r")))
16135    (clobber (reg:CC FLAGS_REG))
16136    (clobber (mem:BLK (scratch)))]
16137   ""
16138   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16139   [(set_attr "type" "alu")
16140    (set_attr "mode" "<MODE>")])
16142 (define_insn "allocate_stack_worker_probe_<mode>"
16143   [(set (match_operand:P 0 "register_operand" "=a")
16144         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16145                             UNSPECV_STACK_PROBE))
16146    (clobber (reg:CC FLAGS_REG))]
16147   "ix86_target_stack_probe ()"
16148   "call\t___chkstk_ms"
16149   [(set_attr "type" "multi")
16150    (set_attr "length" "5")])
16152 (define_expand "allocate_stack"
16153   [(match_operand 0 "register_operand")
16154    (match_operand 1 "general_operand")]
16155   "ix86_target_stack_probe ()"
16157   rtx x;
16159 #ifndef CHECK_STACK_LIMIT
16160 #define CHECK_STACK_LIMIT 0
16161 #endif
16163   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16164       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16165     x = operands[1];
16166   else
16167     {
16168       rtx (*insn) (rtx, rtx);
16170       x = copy_to_mode_reg (Pmode, operands[1]);
16172       insn = (TARGET_64BIT
16173               ? gen_allocate_stack_worker_probe_di
16174               : gen_allocate_stack_worker_probe_si);
16176       emit_insn (insn (x, x));
16177     }
16179   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16180                            stack_pointer_rtx, 0, OPTAB_DIRECT);
16182   if (x != stack_pointer_rtx)
16183     emit_move_insn (stack_pointer_rtx, x);
16185   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16186   DONE;
16189 ;; Use IOR for stack probes, this is shorter.
16190 (define_expand "probe_stack"
16191   [(match_operand 0 "memory_operand")]
16192   ""
16194   rtx (*gen_ior3) (rtx, rtx, rtx);
16196   gen_ior3 = (GET_MODE (operands[0]) == DImode
16197               ? gen_iordi3 : gen_iorsi3);
16199   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16200   DONE;
16203 (define_insn "adjust_stack_and_probe<mode>"
16204   [(set (match_operand:P 0 "register_operand" "=r")
16205         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16206                             UNSPECV_PROBE_STACK_RANGE))
16207    (set (reg:P SP_REG)
16208         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16209    (clobber (reg:CC FLAGS_REG))
16210    (clobber (mem:BLK (scratch)))]
16211   ""
16212   "* return output_adjust_stack_and_probe (operands[0]);"
16213   [(set_attr "type" "multi")])
16215 (define_insn "probe_stack_range<mode>"
16216   [(set (match_operand:P 0 "register_operand" "=r")
16217         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16218                             (match_operand:P 2 "const_int_operand" "n")]
16219                             UNSPECV_PROBE_STACK_RANGE))
16220    (clobber (reg:CC FLAGS_REG))]
16221   ""
16222   "* return output_probe_stack_range (operands[0], operands[2]);"
16223   [(set_attr "type" "multi")])
16225 (define_expand "builtin_setjmp_receiver"
16226   [(label_ref (match_operand 0))]
16227   "!TARGET_64BIT && flag_pic"
16229 #if TARGET_MACHO
16230   if (TARGET_MACHO)
16231     {
16232       rtx xops[3];
16233       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16234       rtx label_rtx = gen_label_rtx ();
16235       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16236       xops[0] = xops[1] = picreg;
16237       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16238       ix86_expand_binary_operator (MINUS, SImode, xops);
16239     }
16240   else
16241 #endif
16242     emit_insn (gen_set_got (pic_offset_table_rtx));
16243   DONE;
16246 (define_insn_and_split "nonlocal_goto_receiver"
16247   [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16248   "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16249   "#"
16250   "&& reload_completed"
16251   [(const_int 0)]
16253   if (crtl->uses_pic_offset_table)
16254     {
16255       rtx xops[3];
16256       rtx label_rtx = gen_label_rtx ();
16257       rtx tmp;
16259       /* Get a new pic base.  */
16260       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16261       /* Correct this with the offset from the new to the old.  */
16262       xops[0] = xops[1] = pic_offset_table_rtx;
16263       label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16264       tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16265                             UNSPEC_MACHOPIC_OFFSET);
16266       xops[2] = gen_rtx_CONST (Pmode, tmp);
16267       ix86_expand_binary_operator (MINUS, SImode, xops);
16268     }
16269   else
16270     /* No pic reg restore needed.  */
16271     emit_note (NOTE_INSN_DELETED);
16273   DONE;
16276 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16278 (define_split
16279   [(set (match_operand 0 "register_operand")
16280         (match_operator 3 "promotable_binary_operator"
16281            [(match_operand 1 "register_operand")
16282             (match_operand 2 "aligned_operand")]))
16283    (clobber (reg:CC FLAGS_REG))]
16284   "! TARGET_PARTIAL_REG_STALL && reload_completed
16285    && ((GET_MODE (operands[0]) == HImode
16286         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16287             /* ??? next two lines just !satisfies_constraint_K (...) */
16288             || !CONST_INT_P (operands[2])
16289             || satisfies_constraint_K (operands[2])))
16290        || (GET_MODE (operands[0]) == QImode
16291            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16292   [(parallel [(set (match_dup 0)
16293                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16294               (clobber (reg:CC FLAGS_REG))])]
16296   operands[0] = gen_lowpart (SImode, operands[0]);
16297   operands[1] = gen_lowpart (SImode, operands[1]);
16298   if (GET_CODE (operands[3]) != ASHIFT)
16299     operands[2] = gen_lowpart (SImode, operands[2]);
16300   PUT_MODE (operands[3], SImode);
16303 ; Promote the QImode tests, as i386 has encoding of the AND
16304 ; instruction with 32-bit sign-extended immediate and thus the
16305 ; instruction size is unchanged, except in the %eax case for
16306 ; which it is increased by one byte, hence the ! optimize_size.
16307 (define_split
16308   [(set (match_operand 0 "flags_reg_operand")
16309         (match_operator 2 "compare_operator"
16310           [(and (match_operand 3 "aligned_operand")
16311                 (match_operand 4 "const_int_operand"))
16312            (const_int 0)]))
16313    (set (match_operand 1 "register_operand")
16314         (and (match_dup 3) (match_dup 4)))]
16315   "! TARGET_PARTIAL_REG_STALL && reload_completed
16316    && optimize_insn_for_speed_p ()
16317    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16318        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16319    /* Ensure that the operand will remain sign-extended immediate.  */
16320    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16321   [(parallel [(set (match_dup 0)
16322                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16323                                     (const_int 0)]))
16324               (set (match_dup 1)
16325                    (and:SI (match_dup 3) (match_dup 4)))])]
16327   operands[4]
16328     = gen_int_mode (INTVAL (operands[4])
16329                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16330   operands[1] = gen_lowpart (SImode, operands[1]);
16331   operands[3] = gen_lowpart (SImode, operands[3]);
16334 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16335 ; the TEST instruction with 32-bit sign-extended immediate and thus
16336 ; the instruction size would at least double, which is not what we
16337 ; want even with ! optimize_size.
16338 (define_split
16339   [(set (match_operand 0 "flags_reg_operand")
16340         (match_operator 1 "compare_operator"
16341           [(and (match_operand:HI 2 "aligned_operand")
16342                 (match_operand:HI 3 "const_int_operand"))
16343            (const_int 0)]))]
16344   "! TARGET_PARTIAL_REG_STALL && reload_completed
16345    && ! TARGET_FAST_PREFIX
16346    && optimize_insn_for_speed_p ()
16347    /* Ensure that the operand will remain sign-extended immediate.  */
16348    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16349   [(set (match_dup 0)
16350         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16351                          (const_int 0)]))]
16353   operands[3]
16354     = gen_int_mode (INTVAL (operands[3])
16355                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16356   operands[2] = gen_lowpart (SImode, operands[2]);
16359 (define_split
16360   [(set (match_operand 0 "register_operand")
16361         (neg (match_operand 1 "register_operand")))
16362    (clobber (reg:CC FLAGS_REG))]
16363   "! TARGET_PARTIAL_REG_STALL && reload_completed
16364    && (GET_MODE (operands[0]) == HImode
16365        || (GET_MODE (operands[0]) == QImode
16366            && (TARGET_PROMOTE_QImode
16367                || optimize_insn_for_size_p ())))"
16368   [(parallel [(set (match_dup 0)
16369                    (neg:SI (match_dup 1)))
16370               (clobber (reg:CC FLAGS_REG))])]
16372   operands[0] = gen_lowpart (SImode, operands[0]);
16373   operands[1] = gen_lowpart (SImode, operands[1]);
16376 (define_split
16377   [(set (match_operand 0 "register_operand")
16378         (not (match_operand 1 "register_operand")))]
16379   "! TARGET_PARTIAL_REG_STALL && reload_completed
16380    && (GET_MODE (operands[0]) == HImode
16381        || (GET_MODE (operands[0]) == QImode
16382            && (TARGET_PROMOTE_QImode
16383                || optimize_insn_for_size_p ())))"
16384   [(set (match_dup 0)
16385         (not:SI (match_dup 1)))]
16387   operands[0] = gen_lowpart (SImode, operands[0]);
16388   operands[1] = gen_lowpart (SImode, operands[1]);
16391 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16392 ;; transform a complex memory operation into two memory to register operations.
16394 ;; Don't push memory operands
16395 (define_peephole2
16396   [(set (match_operand:SWI 0 "push_operand")
16397         (match_operand:SWI 1 "memory_operand"))
16398    (match_scratch:SWI 2 "<r>")]
16399   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16400    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16401   [(set (match_dup 2) (match_dup 1))
16402    (set (match_dup 0) (match_dup 2))])
16404 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16405 ;; SImode pushes.
16406 (define_peephole2
16407   [(set (match_operand:SF 0 "push_operand")
16408         (match_operand:SF 1 "memory_operand"))
16409    (match_scratch:SF 2 "r")]
16410   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16411    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16412   [(set (match_dup 2) (match_dup 1))
16413    (set (match_dup 0) (match_dup 2))])
16415 ;; Don't move an immediate directly to memory when the instruction
16416 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16417 (define_peephole2
16418   [(match_scratch:SWI124 1 "<r>")
16419    (set (match_operand:SWI124 0 "memory_operand")
16420         (const_int 0))]
16421   "optimize_insn_for_speed_p ()
16422    && ((<MODE>mode == HImode
16423        && TARGET_LCP_STALL)
16424        || (!TARGET_USE_MOV0
16425           && TARGET_SPLIT_LONG_MOVES
16426           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16427    && peep2_regno_dead_p (0, FLAGS_REG)"
16428   [(parallel [(set (match_dup 2) (const_int 0))
16429               (clobber (reg:CC FLAGS_REG))])
16430    (set (match_dup 0) (match_dup 1))]
16431   "operands[2] = gen_lowpart (SImode, operands[1]);")
16433 (define_peephole2
16434   [(match_scratch:SWI124 2 "<r>")
16435    (set (match_operand:SWI124 0 "memory_operand")
16436         (match_operand:SWI124 1 "immediate_operand"))]
16437   "optimize_insn_for_speed_p ()
16438    && ((<MODE>mode == HImode
16439        && TARGET_LCP_STALL)
16440        || (TARGET_SPLIT_LONG_MOVES
16441           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16442   [(set (match_dup 2) (match_dup 1))
16443    (set (match_dup 0) (match_dup 2))])
16445 ;; Don't compare memory with zero, load and use a test instead.
16446 (define_peephole2
16447   [(set (match_operand 0 "flags_reg_operand")
16448         (match_operator 1 "compare_operator"
16449           [(match_operand:SI 2 "memory_operand")
16450            (const_int 0)]))
16451    (match_scratch:SI 3 "r")]
16452   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16453   [(set (match_dup 3) (match_dup 2))
16454    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16456 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16457 ;; Don't split NOTs with a displacement operand, because resulting XOR
16458 ;; will not be pairable anyway.
16460 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16461 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16462 ;; so this split helps here as well.
16464 ;; Note: Can't do this as a regular split because we can't get proper
16465 ;; lifetime information then.
16467 (define_peephole2
16468   [(set (match_operand:SWI124 0 "nonimmediate_operand")
16469         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16470   "optimize_insn_for_speed_p ()
16471    && ((TARGET_NOT_UNPAIRABLE
16472         && (!MEM_P (operands[0])
16473             || !memory_displacement_operand (operands[0], <MODE>mode)))
16474        || (TARGET_NOT_VECTORMODE
16475            && long_memory_operand (operands[0], <MODE>mode)))
16476    && peep2_regno_dead_p (0, FLAGS_REG)"
16477   [(parallel [(set (match_dup 0)
16478                    (xor:SWI124 (match_dup 1) (const_int -1)))
16479               (clobber (reg:CC FLAGS_REG))])])
16481 ;; Non pairable "test imm, reg" instructions can be translated to
16482 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16483 ;; byte opcode instead of two, have a short form for byte operands),
16484 ;; so do it for other CPUs as well.  Given that the value was dead,
16485 ;; this should not create any new dependencies.  Pass on the sub-word
16486 ;; versions if we're concerned about partial register stalls.
16488 (define_peephole2
16489   [(set (match_operand 0 "flags_reg_operand")
16490         (match_operator 1 "compare_operator"
16491           [(and:SI (match_operand:SI 2 "register_operand")
16492                    (match_operand:SI 3 "immediate_operand"))
16493            (const_int 0)]))]
16494   "ix86_match_ccmode (insn, CCNOmode)
16495    && (true_regnum (operands[2]) != AX_REG
16496        || satisfies_constraint_K (operands[3]))
16497    && peep2_reg_dead_p (1, operands[2])"
16498   [(parallel
16499      [(set (match_dup 0)
16500            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16501                             (const_int 0)]))
16502       (set (match_dup 2)
16503            (and:SI (match_dup 2) (match_dup 3)))])])
16505 ;; We don't need to handle HImode case, because it will be promoted to SImode
16506 ;; on ! TARGET_PARTIAL_REG_STALL
16508 (define_peephole2
16509   [(set (match_operand 0 "flags_reg_operand")
16510         (match_operator 1 "compare_operator"
16511           [(and:QI (match_operand:QI 2 "register_operand")
16512                    (match_operand:QI 3 "immediate_operand"))
16513            (const_int 0)]))]
16514   "! TARGET_PARTIAL_REG_STALL
16515    && ix86_match_ccmode (insn, CCNOmode)
16516    && true_regnum (operands[2]) != AX_REG
16517    && peep2_reg_dead_p (1, operands[2])"
16518   [(parallel
16519      [(set (match_dup 0)
16520            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16521                             (const_int 0)]))
16522       (set (match_dup 2)
16523            (and:QI (match_dup 2) (match_dup 3)))])])
16525 (define_peephole2
16526   [(set (match_operand 0 "flags_reg_operand")
16527         (match_operator 1 "compare_operator"
16528           [(and:SI
16529              (zero_extract:SI
16530                (match_operand 2 "ext_register_operand")
16531                (const_int 8)
16532                (const_int 8))
16533              (match_operand 3 "const_int_operand"))
16534            (const_int 0)]))]
16535   "! TARGET_PARTIAL_REG_STALL
16536    && ix86_match_ccmode (insn, CCNOmode)
16537    && true_regnum (operands[2]) != AX_REG
16538    && peep2_reg_dead_p (1, operands[2])"
16539   [(parallel [(set (match_dup 0)
16540                    (match_op_dup 1
16541                      [(and:SI
16542                         (zero_extract:SI
16543                           (match_dup 2)
16544                           (const_int 8)
16545                           (const_int 8))
16546                         (match_dup 3))
16547                       (const_int 0)]))
16548               (set (zero_extract:SI (match_dup 2)
16549                                     (const_int 8)
16550                                     (const_int 8))
16551                    (and:SI
16552                      (zero_extract:SI
16553                        (match_dup 2)
16554                        (const_int 8)
16555                        (const_int 8))
16556                      (match_dup 3)))])])
16558 ;; Don't do logical operations with memory inputs.
16559 (define_peephole2
16560   [(match_scratch:SI 2 "r")
16561    (parallel [(set (match_operand:SI 0 "register_operand")
16562                    (match_operator:SI 3 "arith_or_logical_operator"
16563                      [(match_dup 0)
16564                       (match_operand:SI 1 "memory_operand")]))
16565               (clobber (reg:CC FLAGS_REG))])]
16566   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16567   [(set (match_dup 2) (match_dup 1))
16568    (parallel [(set (match_dup 0)
16569                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16570               (clobber (reg:CC FLAGS_REG))])])
16572 (define_peephole2
16573   [(match_scratch:SI 2 "r")
16574    (parallel [(set (match_operand:SI 0 "register_operand")
16575                    (match_operator:SI 3 "arith_or_logical_operator"
16576                      [(match_operand:SI 1 "memory_operand")
16577                       (match_dup 0)]))
16578               (clobber (reg:CC FLAGS_REG))])]
16579   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16580   [(set (match_dup 2) (match_dup 1))
16581    (parallel [(set (match_dup 0)
16582                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16583               (clobber (reg:CC FLAGS_REG))])])
16585 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16586 ;; refers to the destination of the load!
16588 (define_peephole2
16589   [(set (match_operand:SI 0 "register_operand")
16590         (match_operand:SI 1 "register_operand"))
16591    (parallel [(set (match_dup 0)
16592                    (match_operator:SI 3 "commutative_operator"
16593                      [(match_dup 0)
16594                       (match_operand:SI 2 "memory_operand")]))
16595               (clobber (reg:CC FLAGS_REG))])]
16596   "REGNO (operands[0]) != REGNO (operands[1])
16597    && GENERAL_REGNO_P (REGNO (operands[0]))
16598    && GENERAL_REGNO_P (REGNO (operands[1]))"
16599   [(set (match_dup 0) (match_dup 4))
16600    (parallel [(set (match_dup 0)
16601                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16602               (clobber (reg:CC FLAGS_REG))])]
16603   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16605 (define_peephole2
16606   [(set (match_operand 0 "register_operand")
16607         (match_operand 1 "register_operand"))
16608    (set (match_dup 0)
16609                    (match_operator 3 "commutative_operator"
16610                      [(match_dup 0)
16611                       (match_operand 2 "memory_operand")]))]
16612   "REGNO (operands[0]) != REGNO (operands[1])
16613    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16614        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16615   [(set (match_dup 0) (match_dup 2))
16616    (set (match_dup 0)
16617         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16619 ; Don't do logical operations with memory outputs
16621 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16622 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16623 ; the same decoder scheduling characteristics as the original.
16625 (define_peephole2
16626   [(match_scratch:SI 2 "r")
16627    (parallel [(set (match_operand:SI 0 "memory_operand")
16628                    (match_operator:SI 3 "arith_or_logical_operator"
16629                      [(match_dup 0)
16630                       (match_operand:SI 1 "nonmemory_operand")]))
16631               (clobber (reg:CC FLAGS_REG))])]
16632   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16633    /* Do not split stack checking probes.  */
16634    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16635   [(set (match_dup 2) (match_dup 0))
16636    (parallel [(set (match_dup 2)
16637                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16638               (clobber (reg:CC FLAGS_REG))])
16639    (set (match_dup 0) (match_dup 2))])
16641 (define_peephole2
16642   [(match_scratch:SI 2 "r")
16643    (parallel [(set (match_operand:SI 0 "memory_operand")
16644                    (match_operator:SI 3 "arith_or_logical_operator"
16645                      [(match_operand:SI 1 "nonmemory_operand")
16646                       (match_dup 0)]))
16647               (clobber (reg:CC FLAGS_REG))])]
16648   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16649    /* Do not split stack checking probes.  */
16650    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16651   [(set (match_dup 2) (match_dup 0))
16652    (parallel [(set (match_dup 2)
16653                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16654               (clobber (reg:CC FLAGS_REG))])
16655    (set (match_dup 0) (match_dup 2))])
16657 ;; Attempt to use arith or logical operations with memory outputs with
16658 ;; setting of flags.
16659 (define_peephole2
16660   [(set (match_operand:SWI 0 "register_operand")
16661         (match_operand:SWI 1 "memory_operand"))
16662    (parallel [(set (match_dup 0)
16663                    (match_operator:SWI 3 "plusminuslogic_operator"
16664                      [(match_dup 0)
16665                       (match_operand:SWI 2 "<nonmemory_operand>")]))
16666               (clobber (reg:CC FLAGS_REG))])
16667    (set (match_dup 1) (match_dup 0))
16668    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16669   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16670    && peep2_reg_dead_p (4, operands[0])
16671    && !reg_overlap_mentioned_p (operands[0], operands[1])
16672    && !reg_overlap_mentioned_p (operands[0], operands[2])
16673    && (<MODE>mode != QImode
16674        || immediate_operand (operands[2], QImode)
16675        || q_regs_operand (operands[2], QImode))
16676    && ix86_match_ccmode (peep2_next_insn (3),
16677                          (GET_CODE (operands[3]) == PLUS
16678                           || GET_CODE (operands[3]) == MINUS)
16679                          ? CCGOCmode : CCNOmode)"
16680   [(parallel [(set (match_dup 4) (match_dup 5))
16681               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16682                                                   (match_dup 2)]))])]
16684   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16685   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16686                                 copy_rtx (operands[1]),
16687                                 copy_rtx (operands[2]));
16688   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16689                                  operands[5], const0_rtx);
16692 (define_peephole2
16693   [(parallel [(set (match_operand:SWI 0 "register_operand")
16694                    (match_operator:SWI 2 "plusminuslogic_operator"
16695                      [(match_dup 0)
16696                       (match_operand:SWI 1 "memory_operand")]))
16697               (clobber (reg:CC FLAGS_REG))])
16698    (set (match_dup 1) (match_dup 0))
16699    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16700   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16701    && GET_CODE (operands[2]) != MINUS
16702    && peep2_reg_dead_p (3, operands[0])
16703    && !reg_overlap_mentioned_p (operands[0], operands[1])
16704    && ix86_match_ccmode (peep2_next_insn (2),
16705                          GET_CODE (operands[2]) == PLUS
16706                          ? CCGOCmode : CCNOmode)"
16707   [(parallel [(set (match_dup 3) (match_dup 4))
16708               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16709                                                   (match_dup 0)]))])]
16711   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16712   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16713                                 copy_rtx (operands[1]),
16714                                 copy_rtx (operands[0]));
16715   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16716                                  operands[4], const0_rtx);
16719 (define_peephole2
16720   [(set (match_operand:SWI12 0 "register_operand")
16721         (match_operand:SWI12 1 "memory_operand"))
16722    (parallel [(set (match_operand:SI 4 "register_operand")
16723                    (match_operator:SI 3 "plusminuslogic_operator"
16724                      [(match_dup 4)
16725                       (match_operand:SI 2 "nonmemory_operand")]))
16726               (clobber (reg:CC FLAGS_REG))])
16727    (set (match_dup 1) (match_dup 0))
16728    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16729   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16730    && REG_P (operands[0]) && REG_P (operands[4])
16731    && REGNO (operands[0]) == REGNO (operands[4])
16732    && peep2_reg_dead_p (4, operands[0])
16733    && (<MODE>mode != QImode
16734        || immediate_operand (operands[2], SImode)
16735        || q_regs_operand (operands[2], SImode))
16736    && !reg_overlap_mentioned_p (operands[0], operands[1])
16737    && !reg_overlap_mentioned_p (operands[0], operands[2])
16738    && ix86_match_ccmode (peep2_next_insn (3),
16739                          (GET_CODE (operands[3]) == PLUS
16740                           || GET_CODE (operands[3]) == MINUS)
16741                          ? CCGOCmode : CCNOmode)"
16742   [(parallel [(set (match_dup 4) (match_dup 5))
16743               (set (match_dup 1) (match_dup 6))])]
16745   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16746   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16747   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16748                                 copy_rtx (operands[1]), operands[2]);
16749   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16750                                  operands[5], const0_rtx);
16751   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16752                                 copy_rtx (operands[1]),
16753                                 copy_rtx (operands[2]));
16756 ;; Attempt to always use XOR for zeroing registers.
16757 (define_peephole2
16758   [(set (match_operand 0 "register_operand")
16759         (match_operand 1 "const0_operand"))]
16760   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16761    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16762    && GENERAL_REG_P (operands[0])
16763    && peep2_regno_dead_p (0, FLAGS_REG)"
16764   [(parallel [(set (match_dup 0) (const_int 0))
16765               (clobber (reg:CC FLAGS_REG))])]
16766   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16768 (define_peephole2
16769   [(set (strict_low_part (match_operand 0 "register_operand"))
16770         (const_int 0))]
16771   "(GET_MODE (operands[0]) == QImode
16772     || GET_MODE (operands[0]) == HImode)
16773    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16774    && peep2_regno_dead_p (0, FLAGS_REG)"
16775   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16776               (clobber (reg:CC FLAGS_REG))])])
16778 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16779 (define_peephole2
16780   [(set (match_operand:SWI248 0 "register_operand")
16781         (const_int -1))]
16782   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16783    && peep2_regno_dead_p (0, FLAGS_REG)"
16784   [(parallel [(set (match_dup 0) (const_int -1))
16785               (clobber (reg:CC FLAGS_REG))])]
16787   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16788     operands[0] = gen_lowpart (SImode, operands[0]);
16791 ;; Attempt to convert simple lea to add/shift.
16792 ;; These can be created by move expanders.
16793 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
16794 ;; relevant lea instructions were already split.
16796 (define_peephole2
16797   [(set (match_operand:SWI48 0 "register_operand")
16798         (plus:SWI48 (match_dup 0)
16799                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
16800   "!TARGET_OPT_AGU
16801    && peep2_regno_dead_p (0, FLAGS_REG)"
16802   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16803               (clobber (reg:CC FLAGS_REG))])])
16805 (define_peephole2
16806   [(set (match_operand:SWI48 0 "register_operand")
16807         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
16808                     (match_dup 0)))]
16809   "!TARGET_OPT_AGU
16810    && peep2_regno_dead_p (0, FLAGS_REG)"
16811   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16812               (clobber (reg:CC FLAGS_REG))])])
16814 (define_peephole2
16815   [(set (match_operand:DI 0 "register_operand")
16816         (zero_extend:DI
16817           (plus:SI (match_operand:SI 1 "register_operand")
16818                    (match_operand:SI 2 "nonmemory_operand"))))]
16819   "TARGET_64BIT && !TARGET_OPT_AGU
16820    && REGNO (operands[0]) == REGNO (operands[1])
16821    && peep2_regno_dead_p (0, FLAGS_REG)"
16822   [(parallel [(set (match_dup 0)
16823                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
16824               (clobber (reg:CC FLAGS_REG))])])
16826 (define_peephole2
16827   [(set (match_operand:DI 0 "register_operand")
16828         (zero_extend:DI
16829           (plus:SI (match_operand:SI 1 "nonmemory_operand")
16830                    (match_operand:SI 2 "register_operand"))))]
16831   "TARGET_64BIT && !TARGET_OPT_AGU
16832    && REGNO (operands[0]) == REGNO (operands[2])
16833    && peep2_regno_dead_p (0, FLAGS_REG)"
16834   [(parallel [(set (match_dup 0)
16835                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
16836               (clobber (reg:CC FLAGS_REG))])])
16838 (define_peephole2
16839   [(set (match_operand:SWI48 0 "register_operand")
16840         (mult:SWI48 (match_dup 0)
16841                     (match_operand:SWI48 1 "const_int_operand")))]
16842   "exact_log2 (INTVAL (operands[1])) >= 0
16843    && peep2_regno_dead_p (0, FLAGS_REG)"
16844   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
16845               (clobber (reg:CC FLAGS_REG))])]
16846   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16848 (define_peephole2
16849   [(set (match_operand:DI 0 "register_operand")
16850         (zero_extend:DI
16851           (mult:SI (match_operand:SI 1 "register_operand")
16852                    (match_operand:SI 2 "const_int_operand"))))]
16853   "TARGET_64BIT
16854    && exact_log2 (INTVAL (operands[2])) >= 0
16855    && REGNO (operands[0]) == REGNO (operands[1])
16856    && peep2_regno_dead_p (0, FLAGS_REG)"
16857   [(parallel [(set (match_dup 0)
16858                    (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
16859               (clobber (reg:CC FLAGS_REG))])]
16860   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16862 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16863 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16864 ;; On many CPUs it is also faster, since special hardware to avoid esp
16865 ;; dependencies is present.
16867 ;; While some of these conversions may be done using splitters, we use
16868 ;; peepholes in order to allow combine_stack_adjustments pass to see
16869 ;; nonobfuscated RTL.
16871 ;; Convert prologue esp subtractions to push.
16872 ;; We need register to push.  In order to keep verify_flow_info happy we have
16873 ;; two choices
16874 ;; - use scratch and clobber it in order to avoid dependencies
16875 ;; - use already live register
16876 ;; We can't use the second way right now, since there is no reliable way how to
16877 ;; verify that given register is live.  First choice will also most likely in
16878 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16879 ;; call clobbered registers are dead.  We may want to use base pointer as an
16880 ;; alternative when no register is available later.
16882 (define_peephole2
16883   [(match_scratch:W 1 "r")
16884    (parallel [(set (reg:P SP_REG)
16885                    (plus:P (reg:P SP_REG)
16886                            (match_operand:P 0 "const_int_operand")))
16887               (clobber (reg:CC FLAGS_REG))
16888               (clobber (mem:BLK (scratch)))])]
16889   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16890    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16891   [(clobber (match_dup 1))
16892    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16893               (clobber (mem:BLK (scratch)))])])
16895 (define_peephole2
16896   [(match_scratch:W 1 "r")
16897    (parallel [(set (reg:P SP_REG)
16898                    (plus:P (reg:P SP_REG)
16899                            (match_operand:P 0 "const_int_operand")))
16900               (clobber (reg:CC FLAGS_REG))
16901               (clobber (mem:BLK (scratch)))])]
16902   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16903    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16904   [(clobber (match_dup 1))
16905    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16906    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16907               (clobber (mem:BLK (scratch)))])])
16909 ;; Convert esp subtractions to push.
16910 (define_peephole2
16911   [(match_scratch:W 1 "r")
16912    (parallel [(set (reg:P SP_REG)
16913                    (plus:P (reg:P SP_REG)
16914                            (match_operand:P 0 "const_int_operand")))
16915               (clobber (reg:CC FLAGS_REG))])]
16916   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16917    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16918   [(clobber (match_dup 1))
16919    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16921 (define_peephole2
16922   [(match_scratch:W 1 "r")
16923    (parallel [(set (reg:P SP_REG)
16924                    (plus:P (reg:P SP_REG)
16925                            (match_operand:P 0 "const_int_operand")))
16926               (clobber (reg:CC FLAGS_REG))])]
16927   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16928    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16929   [(clobber (match_dup 1))
16930    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16931    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16933 ;; Convert epilogue deallocator to pop.
16934 (define_peephole2
16935   [(match_scratch:W 1 "r")
16936    (parallel [(set (reg:P SP_REG)
16937                    (plus:P (reg:P SP_REG)
16938                            (match_operand:P 0 "const_int_operand")))
16939               (clobber (reg:CC FLAGS_REG))
16940               (clobber (mem:BLK (scratch)))])]
16941   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16942    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16943   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16944               (clobber (mem:BLK (scratch)))])])
16946 ;; Two pops case is tricky, since pop causes dependency
16947 ;; on destination register.  We use two registers if available.
16948 (define_peephole2
16949   [(match_scratch:W 1 "r")
16950    (match_scratch:W 2 "r")
16951    (parallel [(set (reg:P SP_REG)
16952                    (plus:P (reg:P SP_REG)
16953                            (match_operand:P 0 "const_int_operand")))
16954               (clobber (reg:CC FLAGS_REG))
16955               (clobber (mem:BLK (scratch)))])]
16956   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16957    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16958   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16959               (clobber (mem:BLK (scratch)))])
16960    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16962 (define_peephole2
16963   [(match_scratch:W 1 "r")
16964    (parallel [(set (reg:P SP_REG)
16965                    (plus:P (reg:P SP_REG)
16966                            (match_operand:P 0 "const_int_operand")))
16967               (clobber (reg:CC FLAGS_REG))
16968               (clobber (mem:BLK (scratch)))])]
16969   "optimize_insn_for_size_p ()
16970    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16971   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16972               (clobber (mem:BLK (scratch)))])
16973    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16975 ;; Convert esp additions to pop.
16976 (define_peephole2
16977   [(match_scratch:W 1 "r")
16978    (parallel [(set (reg:P SP_REG)
16979                    (plus:P (reg:P SP_REG)
16980                            (match_operand:P 0 "const_int_operand")))
16981               (clobber (reg:CC FLAGS_REG))])]
16982   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16983   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16985 ;; Two pops case is tricky, since pop causes dependency
16986 ;; on destination register.  We use two registers if available.
16987 (define_peephole2
16988   [(match_scratch:W 1 "r")
16989    (match_scratch:W 2 "r")
16990    (parallel [(set (reg:P SP_REG)
16991                    (plus:P (reg:P SP_REG)
16992                            (match_operand:P 0 "const_int_operand")))
16993               (clobber (reg:CC FLAGS_REG))])]
16994   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16995   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16996    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16998 (define_peephole2
16999   [(match_scratch:W 1 "r")
17000    (parallel [(set (reg:P SP_REG)
17001                    (plus:P (reg:P SP_REG)
17002                            (match_operand:P 0 "const_int_operand")))
17003               (clobber (reg:CC FLAGS_REG))])]
17004   "optimize_insn_for_size_p ()
17005    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17006   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17007    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17009 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17010 ;; required and register dies.  Similarly for 128 to -128.
17011 (define_peephole2
17012   [(set (match_operand 0 "flags_reg_operand")
17013         (match_operator 1 "compare_operator"
17014           [(match_operand 2 "register_operand")
17015            (match_operand 3 "const_int_operand")]))]
17016   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17017      && incdec_operand (operands[3], GET_MODE (operands[3])))
17018     || (!TARGET_FUSE_CMP_AND_BRANCH
17019         && INTVAL (operands[3]) == 128))
17020    && ix86_match_ccmode (insn, CCGCmode)
17021    && peep2_reg_dead_p (1, operands[2])"
17022   [(parallel [(set (match_dup 0)
17023                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17024               (clobber (match_dup 2))])])
17026 ;; Convert imul by three, five and nine into lea
17027 (define_peephole2
17028   [(parallel
17029     [(set (match_operand:SWI48 0 "register_operand")
17030           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17031                       (match_operand:SWI48 2 "const359_operand")))
17032      (clobber (reg:CC FLAGS_REG))])]
17033   "!TARGET_PARTIAL_REG_STALL
17034    || <MODE>mode == SImode
17035    || optimize_function_for_size_p (cfun)"
17036   [(set (match_dup 0)
17037         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17038                     (match_dup 1)))]
17039   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17041 (define_peephole2
17042   [(parallel
17043     [(set (match_operand:SWI48 0 "register_operand")
17044           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17045                       (match_operand:SWI48 2 "const359_operand")))
17046      (clobber (reg:CC FLAGS_REG))])]
17047   "optimize_insn_for_speed_p ()
17048    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17049   [(set (match_dup 0) (match_dup 1))
17050    (set (match_dup 0)
17051         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17052                     (match_dup 0)))]
17053   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17055 ;; imul $32bit_imm, mem, reg is vector decoded, while
17056 ;; imul $32bit_imm, reg, reg is direct decoded.
17057 (define_peephole2
17058   [(match_scratch:SWI48 3 "r")
17059    (parallel [(set (match_operand:SWI48 0 "register_operand")
17060                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17061                                (match_operand:SWI48 2 "immediate_operand")))
17062               (clobber (reg:CC FLAGS_REG))])]
17063   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17064    && !satisfies_constraint_K (operands[2])"
17065   [(set (match_dup 3) (match_dup 1))
17066    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17067               (clobber (reg:CC FLAGS_REG))])])
17069 (define_peephole2
17070   [(match_scratch:SI 3 "r")
17071    (parallel [(set (match_operand:DI 0 "register_operand")
17072                    (zero_extend:DI
17073                      (mult:SI (match_operand:SI 1 "memory_operand")
17074                               (match_operand:SI 2 "immediate_operand"))))
17075               (clobber (reg:CC FLAGS_REG))])]
17076   "TARGET_64BIT
17077    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17078    && !satisfies_constraint_K (operands[2])"
17079   [(set (match_dup 3) (match_dup 1))
17080    (parallel [(set (match_dup 0)
17081                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17082               (clobber (reg:CC FLAGS_REG))])])
17084 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17085 ;; Convert it into imul reg, reg
17086 ;; It would be better to force assembler to encode instruction using long
17087 ;; immediate, but there is apparently no way to do so.
17088 (define_peephole2
17089   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17090                    (mult:SWI248
17091                     (match_operand:SWI248 1 "nonimmediate_operand")
17092                     (match_operand:SWI248 2 "const_int_operand")))
17093               (clobber (reg:CC FLAGS_REG))])
17094    (match_scratch:SWI248 3 "r")]
17095   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17096    && satisfies_constraint_K (operands[2])"
17097   [(set (match_dup 3) (match_dup 2))
17098    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17099               (clobber (reg:CC FLAGS_REG))])]
17101   if (!rtx_equal_p (operands[0], operands[1]))
17102     emit_move_insn (operands[0], operands[1]);
17105 ;; After splitting up read-modify operations, array accesses with memory
17106 ;; operands might end up in form:
17107 ;;  sall    $2, %eax
17108 ;;  movl    4(%esp), %edx
17109 ;;  addl    %edx, %eax
17110 ;; instead of pre-splitting:
17111 ;;  sall    $2, %eax
17112 ;;  addl    4(%esp), %eax
17113 ;; Turn it into:
17114 ;;  movl    4(%esp), %edx
17115 ;;  leal    (%edx,%eax,4), %eax
17117 (define_peephole2
17118   [(match_scratch:W 5 "r")
17119    (parallel [(set (match_operand 0 "register_operand")
17120                    (ashift (match_operand 1 "register_operand")
17121                            (match_operand 2 "const_int_operand")))
17122                (clobber (reg:CC FLAGS_REG))])
17123    (parallel [(set (match_operand 3 "register_operand")
17124                    (plus (match_dup 0)
17125                          (match_operand 4 "x86_64_general_operand")))
17126                    (clobber (reg:CC FLAGS_REG))])]
17127   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17128    /* Validate MODE for lea.  */
17129    && ((!TARGET_PARTIAL_REG_STALL
17130         && (GET_MODE (operands[0]) == QImode
17131             || GET_MODE (operands[0]) == HImode))
17132        || GET_MODE (operands[0]) == SImode
17133        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17134    && (rtx_equal_p (operands[0], operands[3])
17135        || peep2_reg_dead_p (2, operands[0]))
17136    /* We reorder load and the shift.  */
17137    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17138   [(set (match_dup 5) (match_dup 4))
17139    (set (match_dup 0) (match_dup 1))]
17141   enum machine_mode op1mode = GET_MODE (operands[1]);
17142   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17143   int scale = 1 << INTVAL (operands[2]);
17144   rtx index = gen_lowpart (word_mode, operands[1]);
17145   rtx base = gen_lowpart (word_mode, operands[5]);
17146   rtx dest = gen_lowpart (mode, operands[3]);
17148   operands[1] = gen_rtx_PLUS (word_mode, base,
17149                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17150   operands[5] = base;
17151   if (mode != word_mode)
17152     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17153   if (op1mode != word_mode)
17154     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17155   operands[0] = dest;
17158 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17159 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17160 ;; caught for use by garbage collectors and the like.  Using an insn that
17161 ;; maps to SIGILL makes it more likely the program will rightfully die.
17162 ;; Keeping with tradition, "6" is in honor of #UD.
17163 (define_insn "trap"
17164   [(trap_if (const_int 1) (const_int 6))]
17165   ""
17166   { return ASM_SHORT "0x0b0f"; }
17167   [(set_attr "length" "2")])
17169 (define_expand "prefetch"
17170   [(prefetch (match_operand 0 "address_operand")
17171              (match_operand:SI 1 "const_int_operand")
17172              (match_operand:SI 2 "const_int_operand"))]
17173   "TARGET_PREFETCH_SSE || TARGET_PRFCHW"
17175   bool write = INTVAL (operands[1]) != 0;
17176   int locality = INTVAL (operands[2]);
17178   gcc_assert (IN_RANGE (locality, 0, 3));
17180   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17181      supported by SSE counterpart or the SSE prefetch is not available
17182      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17183      of locality.  */
17184   if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17185     operands[2] = GEN_INT (3);
17186   else
17187     operands[1] = const0_rtx;
17190 (define_insn "*prefetch_sse"
17191   [(prefetch (match_operand 0 "address_operand" "p")
17192              (const_int 0)
17193              (match_operand:SI 1 "const_int_operand"))]
17194   "TARGET_PREFETCH_SSE"
17196   static const char * const patterns[4] = {
17197    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17198   };
17200   int locality = INTVAL (operands[1]);
17201   gcc_assert (IN_RANGE (locality, 0, 3));
17203   return patterns[locality];
17205   [(set_attr "type" "sse")
17206    (set_attr "atom_sse_attr" "prefetch")
17207    (set (attr "length_address")
17208         (symbol_ref "memory_address_length (operands[0], false)"))
17209    (set_attr "memory" "none")])
17211 (define_insn "*prefetch_3dnow"
17212   [(prefetch (match_operand 0 "address_operand" "p")
17213              (match_operand:SI 1 "const_int_operand" "n")
17214              (const_int 3))]
17215   "TARGET_PRFCHW"
17217   if (INTVAL (operands[1]) == 0)
17218     return "prefetch\t%a0";
17219   else
17220     return "prefetchw\t%a0";
17222   [(set_attr "type" "mmx")
17223    (set (attr "length_address")
17224         (symbol_ref "memory_address_length (operands[0], false)"))
17225    (set_attr "memory" "none")])
17227 (define_expand "stack_protect_set"
17228   [(match_operand 0 "memory_operand")
17229    (match_operand 1 "memory_operand")]
17230   "TARGET_SSP_TLS_GUARD"
17232   rtx (*insn)(rtx, rtx);
17234 #ifdef TARGET_THREAD_SSP_OFFSET
17235   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17236   insn = (TARGET_LP64
17237           ? gen_stack_tls_protect_set_di
17238           : gen_stack_tls_protect_set_si);
17239 #else
17240   insn = (TARGET_LP64
17241           ? gen_stack_protect_set_di
17242           : gen_stack_protect_set_si);
17243 #endif
17245   emit_insn (insn (operands[0], operands[1]));
17246   DONE;
17249 (define_insn "stack_protect_set_<mode>"
17250   [(set (match_operand:PTR 0 "memory_operand" "=m")
17251         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17252                     UNSPEC_SP_SET))
17253    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17254    (clobber (reg:CC FLAGS_REG))]
17255   "TARGET_SSP_TLS_GUARD"
17256   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17257   [(set_attr "type" "multi")])
17259 (define_insn "stack_tls_protect_set_<mode>"
17260   [(set (match_operand:PTR 0 "memory_operand" "=m")
17261         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17262                     UNSPEC_SP_TLS_SET))
17263    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17264    (clobber (reg:CC FLAGS_REG))]
17265   ""
17266   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17267   [(set_attr "type" "multi")])
17269 (define_expand "stack_protect_test"
17270   [(match_operand 0 "memory_operand")
17271    (match_operand 1 "memory_operand")
17272    (match_operand 2)]
17273   "TARGET_SSP_TLS_GUARD"
17275   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17277   rtx (*insn)(rtx, rtx, rtx);
17279 #ifdef TARGET_THREAD_SSP_OFFSET
17280   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17281   insn = (TARGET_LP64
17282           ? gen_stack_tls_protect_test_di
17283           : gen_stack_tls_protect_test_si);
17284 #else
17285   insn = (TARGET_LP64
17286           ? gen_stack_protect_test_di
17287           : gen_stack_protect_test_si);
17288 #endif
17290   emit_insn (insn (flags, operands[0], operands[1]));
17292   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17293                                   flags, const0_rtx, operands[2]));
17294   DONE;
17297 (define_insn "stack_protect_test_<mode>"
17298   [(set (match_operand:CCZ 0 "flags_reg_operand")
17299         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17300                      (match_operand:PTR 2 "memory_operand" "m")]
17301                     UNSPEC_SP_TEST))
17302    (clobber (match_scratch:PTR 3 "=&r"))]
17303   "TARGET_SSP_TLS_GUARD"
17304   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17305   [(set_attr "type" "multi")])
17307 (define_insn "stack_tls_protect_test_<mode>"
17308   [(set (match_operand:CCZ 0 "flags_reg_operand")
17309         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17310                      (match_operand:PTR 2 "const_int_operand" "i")]
17311                     UNSPEC_SP_TLS_TEST))
17312    (clobber (match_scratch:PTR 3 "=r"))]
17313   ""
17314   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17315   [(set_attr "type" "multi")])
17317 (define_insn "sse4_2_crc32<mode>"
17318   [(set (match_operand:SI 0 "register_operand" "=r")
17319         (unspec:SI
17320           [(match_operand:SI 1 "register_operand" "0")
17321            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17322           UNSPEC_CRC32))]
17323   "TARGET_SSE4_2 || TARGET_CRC32"
17324   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17325   [(set_attr "type" "sselog1")
17326    (set_attr "prefix_rep" "1")
17327    (set_attr "prefix_extra" "1")
17328    (set (attr "prefix_data16")
17329      (if_then_else (match_operand:HI 2)
17330        (const_string "1")
17331        (const_string "*")))
17332    (set (attr "prefix_rex")
17333      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17334        (const_string "1")
17335        (const_string "*")))
17336    (set_attr "mode" "SI")])
17338 (define_insn "sse4_2_crc32di"
17339   [(set (match_operand:DI 0 "register_operand" "=r")
17340         (unspec:DI
17341           [(match_operand:DI 1 "register_operand" "0")
17342            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17343           UNSPEC_CRC32))]
17344   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17345   "crc32{q}\t{%2, %0|%0, %2}"
17346   [(set_attr "type" "sselog1")
17347    (set_attr "prefix_rep" "1")
17348    (set_attr "prefix_extra" "1")
17349    (set_attr "mode" "DI")])
17351 (define_insn "rdpmc"
17352   [(set (match_operand:DI 0 "register_operand" "=A")
17353         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17354                             UNSPECV_RDPMC))]
17355   "!TARGET_64BIT"
17356   "rdpmc"
17357   [(set_attr "type" "other")
17358    (set_attr "length" "2")])
17360 (define_insn "rdpmc_rex64"
17361   [(set (match_operand:DI 0 "register_operand" "=a")
17362         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17363                             UNSPECV_RDPMC))
17364    (set (match_operand:DI 1 "register_operand" "=d")
17365         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17366   "TARGET_64BIT"
17367   "rdpmc"
17368   [(set_attr "type" "other")
17369    (set_attr "length" "2")])
17371 (define_insn "rdtsc"
17372   [(set (match_operand:DI 0 "register_operand" "=A")
17373         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17374   "!TARGET_64BIT"
17375   "rdtsc"
17376   [(set_attr "type" "other")
17377    (set_attr "length" "2")])
17379 (define_insn "rdtsc_rex64"
17380   [(set (match_operand:DI 0 "register_operand" "=a")
17381         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17382    (set (match_operand:DI 1 "register_operand" "=d")
17383         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17384   "TARGET_64BIT"
17385   "rdtsc"
17386   [(set_attr "type" "other")
17387    (set_attr "length" "2")])
17389 (define_insn "rdtscp"
17390   [(set (match_operand:DI 0 "register_operand" "=A")
17391         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17392    (set (match_operand:SI 1 "register_operand" "=c")
17393         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17394   "!TARGET_64BIT"
17395   "rdtscp"
17396   [(set_attr "type" "other")
17397    (set_attr "length" "3")])
17399 (define_insn "rdtscp_rex64"
17400   [(set (match_operand:DI 0 "register_operand" "=a")
17401         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17402    (set (match_operand:DI 1 "register_operand" "=d")
17403         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17404    (set (match_operand:SI 2 "register_operand" "=c")
17405         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17406   "TARGET_64BIT"
17407   "rdtscp"
17408   [(set_attr "type" "other")
17409    (set_attr "length" "3")])
17411 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17413 ;; FXSR, XSAVE and XSAVEOPT instructions
17415 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17417 (define_insn "fxsave"
17418   [(set (match_operand:BLK 0 "memory_operand" "=m")
17419         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17420   "TARGET_FXSR"
17421   "fxsave\t%0"
17422   [(set_attr "type" "other")
17423    (set_attr "memory" "store")
17424    (set (attr "length")
17425         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17427 (define_insn "fxsave64"
17428   [(set (match_operand:BLK 0 "memory_operand" "=m")
17429         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17430   "TARGET_64BIT && TARGET_FXSR"
17431   "fxsave64\t%0"
17432   [(set_attr "type" "other")
17433    (set_attr "memory" "store")
17434    (set (attr "length")
17435         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17437 (define_insn "fxrstor"
17438   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17439                     UNSPECV_FXRSTOR)]
17440   "TARGET_FXSR"
17441   "fxrstor\t%0"
17442   [(set_attr "type" "other")
17443    (set_attr "memory" "load")
17444    (set (attr "length")
17445         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17447 (define_insn "fxrstor64"
17448   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17449                     UNSPECV_FXRSTOR64)]
17450   "TARGET_64BIT && TARGET_FXSR"
17451   "fxrstor64\t%0"
17452   [(set_attr "type" "other")
17453    (set_attr "memory" "load")
17454    (set (attr "length")
17455         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17457 (define_int_iterator ANY_XSAVE
17458         [UNSPECV_XSAVE
17459          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17461 (define_int_iterator ANY_XSAVE64
17462         [UNSPECV_XSAVE64
17463          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17465 (define_int_attr xsave
17466         [(UNSPECV_XSAVE "xsave")
17467          (UNSPECV_XSAVE64 "xsave64")
17468          (UNSPECV_XSAVEOPT "xsaveopt")
17469          (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17471 (define_insn "<xsave>"
17472   [(set (match_operand:BLK 0 "memory_operand" "=m")
17473         (unspec_volatile:BLK
17474          [(match_operand:DI 1 "register_operand" "A")]
17475          ANY_XSAVE))]
17476   "!TARGET_64BIT && TARGET_XSAVE"
17477   "<xsave>\t%0"
17478   [(set_attr "type" "other")
17479    (set_attr "memory" "store")
17480    (set (attr "length")
17481         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17483 (define_insn "<xsave>_rex64"
17484   [(set (match_operand:BLK 0 "memory_operand" "=m")
17485         (unspec_volatile:BLK
17486          [(match_operand:SI 1 "register_operand" "a")
17487           (match_operand:SI 2 "register_operand" "d")]
17488          ANY_XSAVE))]
17489   "TARGET_64BIT && TARGET_XSAVE"
17490   "<xsave>\t%0"
17491   [(set_attr "type" "other")
17492    (set_attr "memory" "store")
17493    (set (attr "length")
17494         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17496 (define_insn "<xsave>"
17497   [(set (match_operand:BLK 0 "memory_operand" "=m")
17498         (unspec_volatile:BLK
17499          [(match_operand:SI 1 "register_operand" "a")
17500           (match_operand:SI 2 "register_operand" "d")]
17501          ANY_XSAVE64))]
17502   "TARGET_64BIT && TARGET_XSAVE"
17503   "<xsave>\t%0"
17504   [(set_attr "type" "other")
17505    (set_attr "memory" "store")
17506    (set (attr "length")
17507         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17509 (define_insn "xrstor"
17510    [(unspec_volatile:BLK
17511      [(match_operand:BLK 0 "memory_operand" "m")
17512       (match_operand:DI 1 "register_operand" "A")]
17513      UNSPECV_XRSTOR)]
17514   "!TARGET_64BIT && TARGET_XSAVE"
17515   "xrstor\t%0"
17516   [(set_attr "type" "other")
17517    (set_attr "memory" "load")
17518    (set (attr "length")
17519         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17521 (define_insn "xrstor_rex64"
17522    [(unspec_volatile:BLK
17523      [(match_operand:BLK 0 "memory_operand" "m")
17524       (match_operand:SI 1 "register_operand" "a")
17525       (match_operand:SI 2 "register_operand" "d")]
17526      UNSPECV_XRSTOR)]
17527   "TARGET_64BIT && TARGET_XSAVE"
17528   "xrstor\t%0"
17529   [(set_attr "type" "other")
17530    (set_attr "memory" "load")
17531    (set (attr "length")
17532         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17534 (define_insn "xrstor64"
17535    [(unspec_volatile:BLK
17536      [(match_operand:BLK 0 "memory_operand" "m")
17537       (match_operand:SI 1 "register_operand" "a")
17538       (match_operand:SI 2 "register_operand" "d")]
17539      UNSPECV_XRSTOR64)]
17540   "TARGET_64BIT && TARGET_XSAVE"
17541   "xrstor64\t%0"
17542   [(set_attr "type" "other")
17543    (set_attr "memory" "load")
17544    (set (attr "length")
17545         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17547 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17549 ;; LWP instructions
17551 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17553 (define_expand "lwp_llwpcb"
17554   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17555                     UNSPECV_LLWP_INTRINSIC)]
17556   "TARGET_LWP")
17558 (define_insn "*lwp_llwpcb<mode>1"
17559   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17560                     UNSPECV_LLWP_INTRINSIC)]
17561   "TARGET_LWP"
17562   "llwpcb\t%0"
17563   [(set_attr "type" "lwp")
17564    (set_attr "mode" "<MODE>")
17565    (set_attr "length" "5")])
17567 (define_expand "lwp_slwpcb"
17568   [(set (match_operand 0 "register_operand" "=r")
17569         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17570   "TARGET_LWP"
17572   rtx (*insn)(rtx);
17574   insn = (Pmode == DImode
17575           ? gen_lwp_slwpcbdi
17576           : gen_lwp_slwpcbsi);
17578   emit_insn (insn (operands[0]));
17579   DONE;
17582 (define_insn "lwp_slwpcb<mode>"
17583   [(set (match_operand:P 0 "register_operand" "=r")
17584         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17585   "TARGET_LWP"
17586   "slwpcb\t%0"
17587   [(set_attr "type" "lwp")
17588    (set_attr "mode" "<MODE>")
17589    (set_attr "length" "5")])
17591 (define_expand "lwp_lwpval<mode>3"
17592   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17593                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17594                      (match_operand:SI 3 "const_int_operand" "i")]
17595                     UNSPECV_LWPVAL_INTRINSIC)]
17596   "TARGET_LWP"
17597   ;; Avoid unused variable warning.
17598   "(void) operands[0];")
17600 (define_insn "*lwp_lwpval<mode>3_1"
17601   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17602                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17603                      (match_operand:SI 2 "const_int_operand" "i")]
17604                     UNSPECV_LWPVAL_INTRINSIC)]
17605   "TARGET_LWP"
17606   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17607   [(set_attr "type" "lwp")
17608    (set_attr "mode" "<MODE>")
17609    (set (attr "length")
17610         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17612 (define_expand "lwp_lwpins<mode>3"
17613   [(set (reg:CCC FLAGS_REG)
17614         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17615                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17616                               (match_operand:SI 3 "const_int_operand" "i")]
17617                              UNSPECV_LWPINS_INTRINSIC))
17618    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17619         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17620   "TARGET_LWP")
17622 (define_insn "*lwp_lwpins<mode>3_1"
17623   [(set (reg:CCC FLAGS_REG)
17624         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17625                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17626                               (match_operand:SI 2 "const_int_operand" "i")]
17627                              UNSPECV_LWPINS_INTRINSIC))]
17628   "TARGET_LWP"
17629   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17630   [(set_attr "type" "lwp")
17631    (set_attr "mode" "<MODE>")
17632    (set (attr "length")
17633         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17635 (define_int_iterator RDFSGSBASE
17636         [UNSPECV_RDFSBASE
17637          UNSPECV_RDGSBASE])
17639 (define_int_iterator WRFSGSBASE
17640         [UNSPECV_WRFSBASE
17641          UNSPECV_WRGSBASE])
17643 (define_int_attr fsgs
17644         [(UNSPECV_RDFSBASE "fs")
17645          (UNSPECV_RDGSBASE "gs")
17646          (UNSPECV_WRFSBASE "fs")
17647          (UNSPECV_WRGSBASE "gs")])
17649 (define_insn "rd<fsgs>base<mode>"
17650   [(set (match_operand:SWI48 0 "register_operand" "=r")
17651         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
17652   "TARGET_64BIT && TARGET_FSGSBASE"
17653   "rd<fsgs>base\t%0"
17654   [(set_attr "type" "other")
17655    (set_attr "prefix_extra" "2")])
17657 (define_insn "wr<fsgs>base<mode>"
17658   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17659                     WRFSGSBASE)]
17660   "TARGET_64BIT && TARGET_FSGSBASE"
17661   "wr<fsgs>base\t%0"
17662   [(set_attr "type" "other")
17663    (set_attr "prefix_extra" "2")])
17665 (define_insn "rdrand<mode>_1"
17666   [(set (match_operand:SWI248 0 "register_operand" "=r")
17667         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
17668    (set (reg:CCC FLAGS_REG)
17669         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
17670   "TARGET_RDRND"
17671   "rdrand\t%0"
17672   [(set_attr "type" "other")
17673    (set_attr "prefix_extra" "1")])
17675 (define_insn "rdseed<mode>_1"
17676   [(set (match_operand:SWI248 0 "register_operand" "=r")
17677         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
17678    (set (reg:CCC FLAGS_REG)
17679         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
17680   "TARGET_RDSEED"
17681   "rdseed\t%0"
17682   [(set_attr "type" "other")
17683    (set_attr "prefix_extra" "1")])
17685 (define_expand "pause"
17686   [(set (match_dup 0)
17687         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17688   ""
17690   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17691   MEM_VOLATILE_P (operands[0]) = 1;
17694 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17695 ;; They have the same encoding.
17696 (define_insn "*pause"
17697   [(set (match_operand:BLK 0)
17698         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17699   ""
17700   "rep%; nop"
17701   [(set_attr "length" "2")
17702    (set_attr "memory" "unknown")])
17704 (define_expand "xbegin"
17705   [(set (match_operand:SI 0 "register_operand")
17706         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
17707   "TARGET_RTM"
17709   rtx label = gen_label_rtx ();
17711   /* xbegin is emitted as jump_insn, so reload won't be able
17712      to reload its operand.  Force the value into AX hard register.  */
17713   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
17714   emit_move_insn (ax_reg, constm1_rtx);
17716   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
17718   emit_label (label);
17719   LABEL_NUSES (label) = 1;
17721   emit_move_insn (operands[0], ax_reg);
17723   DONE;
17726 (define_insn "xbegin_1"
17727   [(set (pc)
17728         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
17729                           (const_int 0))
17730                       (label_ref (match_operand 1))
17731                       (pc)))
17732    (set (match_operand:SI 0 "register_operand" "+a")
17733         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
17734   "TARGET_RTM"
17735   "xbegin\t%l1"
17736   [(set_attr "type" "other")
17737    (set_attr "length" "6")])
17739 (define_insn "xend"
17740   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
17741   "TARGET_RTM"
17742   "xend"
17743   [(set_attr "type" "other")
17744    (set_attr "length" "3")])
17746 (define_insn "xabort"
17747   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
17748                     UNSPECV_XABORT)]
17749   "TARGET_RTM"
17750   "xabort\t%0"
17751   [(set_attr "type" "other")
17752    (set_attr "length" "3")])
17754 (define_expand "xtest"
17755   [(set (match_operand:QI 0 "register_operand")
17756         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
17757   "TARGET_RTM"
17759   emit_insn (gen_xtest_1 ());
17761   ix86_expand_setcc (operands[0], NE,
17762                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17763   DONE;
17766 (define_insn "xtest_1"
17767   [(set (reg:CCZ FLAGS_REG)
17768         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
17769   "TARGET_RTM"
17770   "xtest"
17771   [(set_attr "type" "other")
17772    (set_attr "length" "3")])
17774 (include "mmx.md")
17775 (include "sse.md")
17776 (include "sync.md")