* config/i386/i386.md (*movti_internal): Set prefix attribute to
[official-gcc.git] / gcc / config / i386 / i386.md
blobe74785aaab2e420cb702e8247feaf483156312c2
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2013 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
67 (define_c_enum "unspec" [
68   ;; Relocation specifiers
69   UNSPEC_GOT
70   UNSPEC_GOTOFF
71   UNSPEC_GOTPCREL
72   UNSPEC_GOTTPOFF
73   UNSPEC_TPOFF
74   UNSPEC_NTPOFF
75   UNSPEC_DTPOFF
76   UNSPEC_GOTNTPOFF
77   UNSPEC_INDNTPOFF
78   UNSPEC_PLTOFF
79   UNSPEC_MACHOPIC_OFFSET
80   UNSPEC_PCREL
82   ;; Prologue support
83   UNSPEC_STACK_ALLOC
84   UNSPEC_SET_GOT
85   UNSPEC_SET_RIP
86   UNSPEC_SET_GOT_OFFSET
87   UNSPEC_MEMORY_BLOCKAGE
88   UNSPEC_STACK_CHECK
90   ;; TLS support
91   UNSPEC_TP
92   UNSPEC_TLS_GD
93   UNSPEC_TLS_LD_BASE
94   UNSPEC_TLSDESC
95   UNSPEC_TLS_IE_SUN
97   ;; Other random patterns
98   UNSPEC_SCAS
99   UNSPEC_FNSTSW
100   UNSPEC_SAHF
101   UNSPEC_PARITY
102   UNSPEC_FSTCW
103   UNSPEC_ADD_CARRY
104   UNSPEC_FLDCW
105   UNSPEC_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_MS_TO_SYSV_CALL
110   UNSPEC_PAUSE
111   UNSPEC_LEA_ADDR
112   UNSPEC_XBEGIN_ABORT
113   UNSPEC_STOS
115   ;; For SSE/MMX support:
116   UNSPEC_FIX_NOTRUNC
117   UNSPEC_MASKMOV
118   UNSPEC_MOVMSK
119   UNSPEC_RCP
120   UNSPEC_RSQRT
121   UNSPEC_PSADBW
123   ;; Generic math support
124   UNSPEC_COPYSIGN
125   UNSPEC_IEEE_MIN       ; not commutative
126   UNSPEC_IEEE_MAX       ; not commutative
128   ;; x87 Floating point
129   UNSPEC_SIN
130   UNSPEC_COS
131   UNSPEC_FPATAN
132   UNSPEC_FYL2X
133   UNSPEC_FYL2XP1
134   UNSPEC_FRNDINT
135   UNSPEC_FIST
136   UNSPEC_F2XM1
137   UNSPEC_TAN
138   UNSPEC_FXAM
140   ;; x87 Rounding
141   UNSPEC_FRNDINT_FLOOR
142   UNSPEC_FRNDINT_CEIL
143   UNSPEC_FRNDINT_TRUNC
144   UNSPEC_FRNDINT_MASK_PM
145   UNSPEC_FIST_FLOOR
146   UNSPEC_FIST_CEIL
148   ;; x87 Double output FP
149   UNSPEC_SINCOS_COS
150   UNSPEC_SINCOS_SIN
151   UNSPEC_XTRACT_FRACT
152   UNSPEC_XTRACT_EXP
153   UNSPEC_FSCALE_FRACT
154   UNSPEC_FSCALE_EXP
155   UNSPEC_FPREM_F
156   UNSPEC_FPREM_U
157   UNSPEC_FPREM1_F
158   UNSPEC_FPREM1_U
160   UNSPEC_C2_FLAG
161   UNSPEC_FXAM_MEM
163   ;; SSP patterns
164   UNSPEC_SP_SET
165   UNSPEC_SP_TEST
166   UNSPEC_SP_TLS_SET
167   UNSPEC_SP_TLS_TEST
169   ;; For ROUND support
170   UNSPEC_ROUND
172   ;; For CRC32 support
173   UNSPEC_CRC32
175   ;; For BMI support
176   UNSPEC_BEXTR
178   ;; For BMI2 support
179   UNSPEC_PDEP
180   UNSPEC_PEXT
183 (define_c_enum "unspecv" [
184   UNSPECV_BLOCKAGE
185   UNSPECV_STACK_PROBE
186   UNSPECV_PROBE_STACK_RANGE
187   UNSPECV_ALIGN
188   UNSPECV_PROLOGUE_USE
189   UNSPECV_SPLIT_STACK_RETURN
190   UNSPECV_CLD
191   UNSPECV_NOPS
192   UNSPECV_RDTSC
193   UNSPECV_RDTSCP
194   UNSPECV_RDPMC
195   UNSPECV_LLWP_INTRINSIC
196   UNSPECV_SLWP_INTRINSIC
197   UNSPECV_LWPVAL_INTRINSIC
198   UNSPECV_LWPINS_INTRINSIC
199   UNSPECV_RDFSBASE
200   UNSPECV_RDGSBASE
201   UNSPECV_WRFSBASE
202   UNSPECV_WRGSBASE
203   UNSPECV_FXSAVE
204   UNSPECV_FXRSTOR
205   UNSPECV_FXSAVE64
206   UNSPECV_FXRSTOR64
207   UNSPECV_XSAVE
208   UNSPECV_XRSTOR
209   UNSPECV_XSAVE64
210   UNSPECV_XRSTOR64
211   UNSPECV_XSAVEOPT
212   UNSPECV_XSAVEOPT64
214   ;; For RDRAND support
215   UNSPECV_RDRAND
217   ;; For RDSEED support
218   UNSPECV_RDSEED
220   ;; For RTM support
221   UNSPECV_XBEGIN
222   UNSPECV_XEND
223   UNSPECV_XABORT
224   UNSPECV_XTEST
227 ;; Constants to represent rounding modes in the ROUND instruction
228 (define_constants
229   [(ROUND_FLOOR                 0x1)
230    (ROUND_CEIL                  0x2)
231    (ROUND_TRUNC                 0x3)
232    (ROUND_MXCSR                 0x4)
233    (ROUND_NO_EXC                0x8)
234   ])
236 ;; Constants to represent pcomtrue/pcomfalse variants
237 (define_constants
238   [(PCOM_FALSE                  0)
239    (PCOM_TRUE                   1)
240    (COM_FALSE_S                 2)
241    (COM_FALSE_P                 3)
242    (COM_TRUE_S                  4)
243    (COM_TRUE_P                  5)
244   ])
246 ;; Constants used in the XOP pperm instruction
247 (define_constants
248   [(PPERM_SRC                   0x00)   /* copy source */
249    (PPERM_INVERT                0x20)   /* invert source */
250    (PPERM_REVERSE               0x40)   /* bit reverse source */
251    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
252    (PPERM_ZERO                  0x80)   /* all 0's */
253    (PPERM_ONES                  0xa0)   /* all 1's */
254    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
255    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
256    (PPERM_SRC1                  0x00)   /* use first source byte */
257    (PPERM_SRC2                  0x10)   /* use second source byte */
258    ])
260 ;; Registers by name.
261 (define_constants
262   [(AX_REG                       0)
263    (DX_REG                       1)
264    (CX_REG                       2)
265    (BX_REG                       3)
266    (SI_REG                       4)
267    (DI_REG                       5)
268    (BP_REG                       6)
269    (SP_REG                       7)
270    (ST0_REG                      8)
271    (ST1_REG                      9)
272    (ST2_REG                     10)
273    (ST3_REG                     11)
274    (ST4_REG                     12)
275    (ST5_REG                     13)
276    (ST6_REG                     14)
277    (ST7_REG                     15)
278    (FLAGS_REG                   17)
279    (FPSR_REG                    18)
280    (FPCR_REG                    19)
281    (XMM0_REG                    21)
282    (XMM1_REG                    22)
283    (XMM2_REG                    23)
284    (XMM3_REG                    24)
285    (XMM4_REG                    25)
286    (XMM5_REG                    26)
287    (XMM6_REG                    27)
288    (XMM7_REG                    28)
289    (MM0_REG                     29)
290    (MM1_REG                     30)
291    (MM2_REG                     31)
292    (MM3_REG                     32)
293    (MM4_REG                     33)
294    (MM5_REG                     34)
295    (MM6_REG                     35)
296    (MM7_REG                     36)
297    (R8_REG                      37)
298    (R9_REG                      38)
299    (R10_REG                     39)
300    (R11_REG                     40)
301    (R12_REG                     41)
302    (R13_REG                     42)
303    (R14_REG                     43)
304    (R15_REG                     44)
305    (XMM8_REG                    45)
306    (XMM9_REG                    46)
307    (XMM10_REG                   47)
308    (XMM11_REG                   48)
309    (XMM12_REG                   49)
310    (XMM13_REG                   50)
311    (XMM14_REG                   51)
312    (XMM15_REG                   52)
313   ])
315 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
316 ;; from i386.c.
318 ;; In C guard expressions, put expressions which may be compile-time
319 ;; constants first.  This allows for better optimization.  For
320 ;; example, write "TARGET_64BIT && reload_completed", not
321 ;; "reload_completed && TARGET_64BIT".
324 ;; Processor type.
325 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
326                     atom,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
327   (const (symbol_ref "ix86_schedule")))
329 ;; A basic instruction type.  Refinements due to arguments to be
330 ;; provided in other attributes.
331 (define_attr "type"
332   "other,multi,
333    alu,alu1,negnot,imov,imovx,lea,
334    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
335    icmp,test,ibr,setcc,icmov,
336    push,pop,call,callv,leave,
337    str,bitmanip,
338    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
339    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
340    sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
341    sseshuf,sseshuf1,ssediv,sseins,ssemuladd,sse4arg,lwp,
342    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
343   (const_string "other"))
345 ;; Main data type used by the insn
346 (define_attr "mode"
347   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
348   (const_string "unknown"))
350 ;; The CPU unit operations uses.
351 (define_attr "unit" "integer,i387,sse,mmx,unknown"
352   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
353            (const_string "i387")
354          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
355                           sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,
356                           sseshuf,sseshuf1,ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
357            (const_string "sse")
358          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
359            (const_string "mmx")
360          (eq_attr "type" "other")
361            (const_string "unknown")]
362          (const_string "integer")))
364 ;; The (bounding maximum) length of an instruction immediate.
365 (define_attr "length_immediate" ""
366   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
367                           bitmanip,imulx")
368            (const_int 0)
369          (eq_attr "unit" "i387,sse,mmx")
370            (const_int 0)
371          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
372                           rotate,rotatex,rotate1,imul,icmp,push,pop")
373            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
374          (eq_attr "type" "imov,test")
375            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
376          (eq_attr "type" "call")
377            (if_then_else (match_operand 0 "constant_call_address_operand")
378              (const_int 4)
379              (const_int 0))
380          (eq_attr "type" "callv")
381            (if_then_else (match_operand 1 "constant_call_address_operand")
382              (const_int 4)
383              (const_int 0))
384          ;; We don't know the size before shorten_branches.  Expect
385          ;; the instruction to fit for better scheduling.
386          (eq_attr "type" "ibr")
387            (const_int 1)
388          ]
389          (symbol_ref "/* Update immediate_length and other attributes! */
390                       gcc_unreachable (),1")))
392 ;; The (bounding maximum) length of an instruction address.
393 (define_attr "length_address" ""
394   (cond [(eq_attr "type" "str,other,multi,fxch")
395            (const_int 0)
396          (and (eq_attr "type" "call")
397               (match_operand 0 "constant_call_address_operand"))
398              (const_int 0)
399          (and (eq_attr "type" "callv")
400               (match_operand 1 "constant_call_address_operand"))
401              (const_int 0)
402          ]
403          (symbol_ref "ix86_attr_length_address_default (insn)")))
405 ;; Set when length prefix is used.
406 (define_attr "prefix_data16" ""
407   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
408            (const_int 0)
409          (eq_attr "mode" "HI")
410            (const_int 1)
411          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
412            (const_int 1)
413         ]
414         (const_int 0)))
416 ;; Set when string REP prefix is used.
417 (define_attr "prefix_rep" ""
418   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
419            (const_int 0)
420          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
421            (const_int 1)
422         ]
423         (const_int 0)))
425 ;; Set when 0f opcode prefix is used.
426 (define_attr "prefix_0f" ""
427   (if_then_else
428     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
429          (eq_attr "unit" "sse,mmx"))
430     (const_int 1)
431     (const_int 0)))
433 ;; Set when REX opcode prefix is used.
434 (define_attr "prefix_rex" ""
435   (cond [(not (match_test "TARGET_64BIT"))
436            (const_int 0)
437          (and (eq_attr "mode" "DI")
438               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
439                    (eq_attr "unit" "!mmx")))
440            (const_int 1)
441          (and (eq_attr "mode" "QI")
442               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
443            (const_int 1)
444          (match_test "x86_extended_reg_mentioned_p (insn)")
445            (const_int 1)
446          (and (eq_attr "type" "imovx")
447               (match_operand:QI 1 "ext_QIreg_operand"))
448            (const_int 1)
449         ]
450         (const_int 0)))
452 ;; There are also additional prefixes in 3DNOW, SSSE3.
453 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
454 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
455 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
456 (define_attr "prefix_extra" ""
457   (cond [(eq_attr "type" "ssemuladd,sse4arg")
458            (const_int 2)
459          (eq_attr "type" "sseiadd1,ssecvt1")
460            (const_int 1)
461         ]
462         (const_int 0)))
464 ;; Prefix used: original, VEX or maybe VEX.
465 (define_attr "prefix" "orig,vex,maybe_vex"
466   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
467     (const_string "vex")
468     (const_string "orig")))
470 ;; VEX W bit is used.
471 (define_attr "prefix_vex_w" "" (const_int 0))
473 ;; The length of VEX prefix
474 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
475 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
476 ;; still prefix_0f 1, with prefix_extra 1.
477 (define_attr "length_vex" ""
478   (if_then_else (and (eq_attr "prefix_0f" "1")
479                      (eq_attr "prefix_extra" "0"))
480     (if_then_else (eq_attr "prefix_vex_w" "1")
481       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
482       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
483     (if_then_else (eq_attr "prefix_vex_w" "1")
484       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
485       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
487 ;; Set when modrm byte is used.
488 (define_attr "modrm" ""
489   (cond [(eq_attr "type" "str,leave")
490            (const_int 0)
491          (eq_attr "unit" "i387")
492            (const_int 0)
493          (and (eq_attr "type" "incdec")
494               (and (not (match_test "TARGET_64BIT"))
495                    (ior (match_operand:SI 1 "register_operand")
496                         (match_operand:HI 1 "register_operand"))))
497            (const_int 0)
498          (and (eq_attr "type" "push")
499               (not (match_operand 1 "memory_operand")))
500            (const_int 0)
501          (and (eq_attr "type" "pop")
502               (not (match_operand 0 "memory_operand")))
503            (const_int 0)
504          (and (eq_attr "type" "imov")
505               (and (not (eq_attr "mode" "DI"))
506                    (ior (and (match_operand 0 "register_operand")
507                              (match_operand 1 "immediate_operand"))
508                         (ior (and (match_operand 0 "ax_reg_operand")
509                                   (match_operand 1 "memory_displacement_only_operand"))
510                              (and (match_operand 0 "memory_displacement_only_operand")
511                                   (match_operand 1 "ax_reg_operand"))))))
512            (const_int 0)
513          (and (eq_attr "type" "call")
514               (match_operand 0 "constant_call_address_operand"))
515              (const_int 0)
516          (and (eq_attr "type" "callv")
517               (match_operand 1 "constant_call_address_operand"))
518              (const_int 0)
519          (and (eq_attr "type" "alu,alu1,icmp,test")
520               (match_operand 0 "ax_reg_operand"))
521              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
522          ]
523          (const_int 1)))
525 ;; The (bounding maximum) length of an instruction in bytes.
526 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
527 ;; Later we may want to split them and compute proper length as for
528 ;; other insns.
529 (define_attr "length" ""
530   (cond [(eq_attr "type" "other,multi,fistp,frndint")
531            (const_int 16)
532          (eq_attr "type" "fcmp")
533            (const_int 4)
534          (eq_attr "unit" "i387")
535            (plus (const_int 2)
536                  (plus (attr "prefix_data16")
537                        (attr "length_address")))
538          (ior (eq_attr "prefix" "vex")
539               (and (eq_attr "prefix" "maybe_vex")
540                    (match_test "TARGET_AVX")))
541            (plus (attr "length_vex")
542                  (plus (attr "length_immediate")
543                        (plus (attr "modrm")
544                              (attr "length_address"))))]
545          (plus (plus (attr "modrm")
546                      (plus (attr "prefix_0f")
547                            (plus (attr "prefix_rex")
548                                  (plus (attr "prefix_extra")
549                                        (const_int 1)))))
550                (plus (attr "prefix_rep")
551                      (plus (attr "prefix_data16")
552                            (plus (attr "length_immediate")
553                                  (attr "length_address")))))))
555 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
556 ;; `store' if there is a simple memory reference therein, or `unknown'
557 ;; if the instruction is complex.
559 (define_attr "memory" "none,load,store,both,unknown"
560   (cond [(eq_attr "type" "other,multi,str,lwp")
561            (const_string "unknown")
562          (eq_attr "type" "lea,fcmov,fpspc")
563            (const_string "none")
564          (eq_attr "type" "fistp,leave")
565            (const_string "both")
566          (eq_attr "type" "frndint")
567            (const_string "load")
568          (eq_attr "type" "push")
569            (if_then_else (match_operand 1 "memory_operand")
570              (const_string "both")
571              (const_string "store"))
572          (eq_attr "type" "pop")
573            (if_then_else (match_operand 0 "memory_operand")
574              (const_string "both")
575              (const_string "load"))
576          (eq_attr "type" "setcc")
577            (if_then_else (match_operand 0 "memory_operand")
578              (const_string "store")
579              (const_string "none"))
580          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
581            (if_then_else (ior (match_operand 0 "memory_operand")
582                               (match_operand 1 "memory_operand"))
583              (const_string "load")
584              (const_string "none"))
585          (eq_attr "type" "ibr")
586            (if_then_else (match_operand 0 "memory_operand")
587              (const_string "load")
588              (const_string "none"))
589          (eq_attr "type" "call")
590            (if_then_else (match_operand 0 "constant_call_address_operand")
591              (const_string "none")
592              (const_string "load"))
593          (eq_attr "type" "callv")
594            (if_then_else (match_operand 1 "constant_call_address_operand")
595              (const_string "none")
596              (const_string "load"))
597          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
598               (match_operand 1 "memory_operand"))
599            (const_string "both")
600          (and (match_operand 0 "memory_operand")
601               (match_operand 1 "memory_operand"))
602            (const_string "both")
603          (match_operand 0 "memory_operand")
604            (const_string "store")
605          (match_operand 1 "memory_operand")
606            (const_string "load")
607          (and (eq_attr "type"
608                  "!alu1,negnot,ishift1,
609                    imov,imovx,icmp,test,bitmanip,
610                    fmov,fcmp,fsgn,
611                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
612                    sseshuf1,sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
613               (match_operand 2 "memory_operand"))
614            (const_string "load")
615          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
616               (match_operand 3 "memory_operand"))
617            (const_string "load")
618         ]
619         (const_string "none")))
621 ;; Indicates if an instruction has both an immediate and a displacement.
623 (define_attr "imm_disp" "false,true,unknown"
624   (cond [(eq_attr "type" "other,multi")
625            (const_string "unknown")
626          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
627               (and (match_operand 0 "memory_displacement_operand")
628                    (match_operand 1 "immediate_operand")))
629            (const_string "true")
630          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
631               (and (match_operand 0 "memory_displacement_operand")
632                    (match_operand 2 "immediate_operand")))
633            (const_string "true")
634         ]
635         (const_string "false")))
637 ;; Indicates if an FP operation has an integer source.
639 (define_attr "fp_int_src" "false,true"
640   (const_string "false"))
642 ;; Defines rounding mode of an FP operation.
644 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
645   (const_string "any"))
647 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
648 (define_attr "use_carry" "0,1" (const_string "0"))
650 ;; Define attribute to indicate unaligned ssemov insns
651 (define_attr "movu" "0,1" (const_string "0"))
653 ;; Used to control the "enabled" attribute on a per-instruction basis.
654 (define_attr "isa" "base,x64,nox64,sse2,sse2_noavx,sse3,sse4,sse4_noavx,
655                     noavx,avx,avx2,noavx2,bmi2,fma4,fma"
656   (const_string "base"))
658 (define_attr "enabled" ""
659   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
660          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
661          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
662          (eq_attr "isa" "sse2_noavx")
663            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
664          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
665          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
666          (eq_attr "isa" "sse4_noavx")
667            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
668          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
669          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
670          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
671          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
672          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
673          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
674          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
675         ]
676         (const_int 1)))
678 ;; Describe a user's asm statement.
679 (define_asm_attributes
680   [(set_attr "length" "128")
681    (set_attr "type" "multi")])
683 (define_code_iterator plusminus [plus minus])
685 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
687 ;; Base name for define_insn
688 (define_code_attr plusminus_insn
689   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
690    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
692 ;; Base name for insn mnemonic.
693 (define_code_attr plusminus_mnemonic
694   [(plus "add") (ss_plus "adds") (us_plus "addus")
695    (minus "sub") (ss_minus "subs") (us_minus "subus")])
696 (define_code_attr plusminus_carry_mnemonic
697   [(plus "adc") (minus "sbb")])
699 ;; Mark commutative operators as such in constraints.
700 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
701                         (minus "") (ss_minus "") (us_minus "")])
703 ;; Mapping of max and min
704 (define_code_iterator maxmin [smax smin umax umin])
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
712 ;; Base name for integer and FP insn mnemonic
713 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
714                               (umax "maxu") (umin "minu")])
715 (define_code_attr maxmin_float [(smax "max") (smin "min")])
717 ;; Mapping of logic operators
718 (define_code_iterator any_logic [and ior xor])
719 (define_code_iterator any_or [ior xor])
721 ;; Base name for insn mnemonic.
722 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
724 ;; Mapping of logic-shift operators
725 (define_code_iterator any_lshift [ashift lshiftrt])
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730 ;; Mapping of all shift operators
731 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
733 ;; Base name for define_insn
734 (define_code_attr shift_insn
735   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
737 ;; Base name for insn mnemonic.
738 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
739 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
741 ;; Mapping of rotate operators
742 (define_code_iterator any_rotate [rotate rotatert])
744 ;; Base name for define_insn
745 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
747 ;; Base name for insn mnemonic.
748 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
750 ;; Mapping of abs neg operators
751 (define_code_iterator absneg [abs neg])
753 ;; Base name for x87 insn mnemonic.
754 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
756 ;; Used in signed and unsigned widening multiplications.
757 (define_code_iterator any_extend [sign_extend zero_extend])
759 ;; Prefix for insn menmonic.
760 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
762 ;; Prefix for define_insn
763 (define_code_attr u [(sign_extend "") (zero_extend "u")])
764 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
765 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
767 ;; All integer modes.
768 (define_mode_iterator SWI1248x [QI HI SI DI])
770 ;; All integer modes without QImode.
771 (define_mode_iterator SWI248x [HI SI DI])
773 ;; All integer modes without QImode and HImode.
774 (define_mode_iterator SWI48x [SI DI])
776 ;; All integer modes without SImode and DImode.
777 (define_mode_iterator SWI12 [QI HI])
779 ;; All integer modes without DImode.
780 (define_mode_iterator SWI124 [QI HI SI])
782 ;; All integer modes without QImode and DImode.
783 (define_mode_iterator SWI24 [HI SI])
785 ;; Single word integer modes.
786 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
788 ;; Single word integer modes without QImode.
789 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
791 ;; Single word integer modes without QImode and HImode.
792 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
794 ;; All math-dependant single and double word integer modes.
795 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
796                              (HI "TARGET_HIMODE_MATH")
797                              SI DI (TI "TARGET_64BIT")])
799 ;; Math-dependant single word integer modes.
800 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
801                             (HI "TARGET_HIMODE_MATH")
802                             SI (DI "TARGET_64BIT")])
804 ;; Math-dependant integer modes without DImode.
805 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
806                                (HI "TARGET_HIMODE_MATH")
807                                SI])
809 ;; Math-dependant single word integer modes without QImode.
810 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
811                                SI (DI "TARGET_64BIT")])
813 ;; Double word integer modes.
814 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
815                            (TI "TARGET_64BIT")])
817 ;; Double word integer modes as mode attribute.
818 (define_mode_attr DWI [(SI "DI") (DI "TI")])
819 (define_mode_attr dwi [(SI "di") (DI "ti")])
821 ;; Half mode for double word integer modes.
822 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
823                             (DI "TARGET_64BIT")])
825 ;; Instruction suffix for integer modes.
826 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
828 ;; Pointer size prefix for integer modes (Intel asm dialect)
829 (define_mode_attr iptrsize [(QI "BYTE")
830                             (HI "WORD")
831                             (SI "DWORD")
832                             (DI "QWORD")])
834 ;; Register class for integer modes.
835 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
837 ;; Immediate operand constraint for integer modes.
838 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
840 ;; General operand constraint for word modes.
841 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
843 ;; Immediate operand constraint for double integer modes.
844 (define_mode_attr di [(SI "nF") (DI "e")])
846 ;; Immediate operand constraint for shifts.
847 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
849 ;; General operand predicate for integer modes.
850 (define_mode_attr general_operand
851         [(QI "general_operand")
852          (HI "general_operand")
853          (SI "x86_64_general_operand")
854          (DI "x86_64_general_operand")
855          (TI "x86_64_general_operand")])
857 ;; General sign/zero extend operand predicate for integer modes.
858 (define_mode_attr general_szext_operand
859         [(QI "general_operand")
860          (HI "general_operand")
861          (SI "x86_64_szext_general_operand")
862          (DI "x86_64_szext_general_operand")])
864 ;; Immediate operand predicate for integer modes.
865 (define_mode_attr immediate_operand
866         [(QI "immediate_operand")
867          (HI "immediate_operand")
868          (SI "x86_64_immediate_operand")
869          (DI "x86_64_immediate_operand")])
871 ;; Nonmemory operand predicate for integer modes.
872 (define_mode_attr nonmemory_operand
873         [(QI "nonmemory_operand")
874          (HI "nonmemory_operand")
875          (SI "x86_64_nonmemory_operand")
876          (DI "x86_64_nonmemory_operand")])
878 ;; Operand predicate for shifts.
879 (define_mode_attr shift_operand
880         [(QI "nonimmediate_operand")
881          (HI "nonimmediate_operand")
882          (SI "nonimmediate_operand")
883          (DI "shiftdi_operand")
884          (TI "register_operand")])
886 ;; Operand predicate for shift argument.
887 (define_mode_attr shift_immediate_operand
888         [(QI "const_1_to_31_operand")
889          (HI "const_1_to_31_operand")
890          (SI "const_1_to_31_operand")
891          (DI "const_1_to_63_operand")])
893 ;; Input operand predicate for arithmetic left shifts.
894 (define_mode_attr ashl_input_operand
895         [(QI "nonimmediate_operand")
896          (HI "nonimmediate_operand")
897          (SI "nonimmediate_operand")
898          (DI "ashldi_input_operand")
899          (TI "reg_or_pm1_operand")])
901 ;; SSE and x87 SFmode and DFmode floating point modes
902 (define_mode_iterator MODEF [SF DF])
904 ;; All x87 floating point modes
905 (define_mode_iterator X87MODEF [SF DF XF])
907 ;; SSE instruction suffix for various modes
908 (define_mode_attr ssemodesuffix
909   [(SF "ss") (DF "sd")
910    (V8SF "ps") (V4DF "pd")
911    (V4SF "ps") (V2DF "pd")
912    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
913    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
915 ;; SSE vector suffix for floating point modes
916 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
918 ;; SSE vector mode corresponding to a scalar mode
919 (define_mode_attr ssevecmode
920   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
922 ;; Instruction suffix for REX 64bit operators.
923 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
925 ;; This mode iterator allows :P to be used for patterns that operate on
926 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
927 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
929 ;; This mode iterator allows :W to be used for patterns that operate on
930 ;; word_mode sized quantities.
931 (define_mode_iterator W
932   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
934 ;; This mode iterator allows :PTR to be used for patterns that operate on
935 ;; ptr_mode sized quantities.
936 (define_mode_iterator PTR
937   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
939 ;; Scheduling descriptions
941 (include "pentium.md")
942 (include "ppro.md")
943 (include "k6.md")
944 (include "athlon.md")
945 (include "bdver1.md")
946 (include "bdver3.md")
947 (include "btver2.md")
948 (include "geode.md")
949 (include "atom.md")
950 (include "core2.md")
953 ;; Operand and operator predicates and constraints
955 (include "predicates.md")
956 (include "constraints.md")
959 ;; Compare and branch/compare and store instructions.
961 (define_expand "cbranch<mode>4"
962   [(set (reg:CC FLAGS_REG)
963         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
964                     (match_operand:SDWIM 2 "<general_operand>")))
965    (set (pc) (if_then_else
966                (match_operator 0 "ordered_comparison_operator"
967                 [(reg:CC FLAGS_REG) (const_int 0)])
968                (label_ref (match_operand 3))
969                (pc)))]
970   ""
972   if (MEM_P (operands[1]) && MEM_P (operands[2]))
973     operands[1] = force_reg (<MODE>mode, operands[1]);
974   ix86_expand_branch (GET_CODE (operands[0]),
975                       operands[1], operands[2], operands[3]);
976   DONE;
979 (define_expand "cstore<mode>4"
980   [(set (reg:CC FLAGS_REG)
981         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
982                     (match_operand:SWIM 3 "<general_operand>")))
983    (set (match_operand:QI 0 "register_operand")
984         (match_operator 1 "ordered_comparison_operator"
985           [(reg:CC FLAGS_REG) (const_int 0)]))]
986   ""
988   if (MEM_P (operands[2]) && MEM_P (operands[3]))
989     operands[2] = force_reg (<MODE>mode, operands[2]);
990   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
991                      operands[2], operands[3]);
992   DONE;
995 (define_expand "cmp<mode>_1"
996   [(set (reg:CC FLAGS_REG)
997         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
998                     (match_operand:SWI48 1 "<general_operand>")))])
1000 (define_insn "*cmp<mode>_ccno_1"
1001   [(set (reg FLAGS_REG)
1002         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1003                  (match_operand:SWI 1 "const0_operand")))]
1004   "ix86_match_ccmode (insn, CCNOmode)"
1005   "@
1006    test{<imodesuffix>}\t%0, %0
1007    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1008   [(set_attr "type" "test,icmp")
1009    (set_attr "length_immediate" "0,1")
1010    (set_attr "mode" "<MODE>")])
1012 (define_insn "*cmp<mode>_1"
1013   [(set (reg FLAGS_REG)
1014         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1015                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1016   "ix86_match_ccmode (insn, CCmode)"
1017   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1018   [(set_attr "type" "icmp")
1019    (set_attr "mode" "<MODE>")])
1021 (define_insn "*cmp<mode>_minus_1"
1022   [(set (reg FLAGS_REG)
1023         (compare
1024           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1025                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1026           (const_int 0)))]
1027   "ix86_match_ccmode (insn, CCGOCmode)"
1028   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1029   [(set_attr "type" "icmp")
1030    (set_attr "mode" "<MODE>")])
1032 (define_insn "*cmpqi_ext_1"
1033   [(set (reg FLAGS_REG)
1034         (compare
1035           (match_operand:QI 0 "general_operand" "Qm")
1036           (subreg:QI
1037             (zero_extract:SI
1038               (match_operand 1 "ext_register_operand" "Q")
1039               (const_int 8)
1040               (const_int 8)) 0)))]
1041   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1042   "cmp{b}\t{%h1, %0|%0, %h1}"
1043   [(set_attr "type" "icmp")
1044    (set_attr "mode" "QI")])
1046 (define_insn "*cmpqi_ext_1_rex64"
1047   [(set (reg FLAGS_REG)
1048         (compare
1049           (match_operand:QI 0 "register_operand" "Q")
1050           (subreg:QI
1051             (zero_extract:SI
1052               (match_operand 1 "ext_register_operand" "Q")
1053               (const_int 8)
1054               (const_int 8)) 0)))]
1055   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056   "cmp{b}\t{%h1, %0|%0, %h1}"
1057   [(set_attr "type" "icmp")
1058    (set_attr "mode" "QI")])
1060 (define_insn "*cmpqi_ext_2"
1061   [(set (reg FLAGS_REG)
1062         (compare
1063           (subreg:QI
1064             (zero_extract:SI
1065               (match_operand 0 "ext_register_operand" "Q")
1066               (const_int 8)
1067               (const_int 8)) 0)
1068           (match_operand:QI 1 "const0_operand")))]
1069   "ix86_match_ccmode (insn, CCNOmode)"
1070   "test{b}\t%h0, %h0"
1071   [(set_attr "type" "test")
1072    (set_attr "length_immediate" "0")
1073    (set_attr "mode" "QI")])
1075 (define_expand "cmpqi_ext_3"
1076   [(set (reg:CC FLAGS_REG)
1077         (compare:CC
1078           (subreg:QI
1079             (zero_extract:SI
1080               (match_operand 0 "ext_register_operand")
1081               (const_int 8)
1082               (const_int 8)) 0)
1083           (match_operand:QI 1 "immediate_operand")))])
1085 (define_insn "*cmpqi_ext_3_insn"
1086   [(set (reg FLAGS_REG)
1087         (compare
1088           (subreg:QI
1089             (zero_extract:SI
1090               (match_operand 0 "ext_register_operand" "Q")
1091               (const_int 8)
1092               (const_int 8)) 0)
1093           (match_operand:QI 1 "general_operand" "Qmn")))]
1094   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1095   "cmp{b}\t{%1, %h0|%h0, %1}"
1096   [(set_attr "type" "icmp")
1097    (set_attr "modrm" "1")
1098    (set_attr "mode" "QI")])
1100 (define_insn "*cmpqi_ext_3_insn_rex64"
1101   [(set (reg FLAGS_REG)
1102         (compare
1103           (subreg:QI
1104             (zero_extract:SI
1105               (match_operand 0 "ext_register_operand" "Q")
1106               (const_int 8)
1107               (const_int 8)) 0)
1108           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1109   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1110   "cmp{b}\t{%1, %h0|%h0, %1}"
1111   [(set_attr "type" "icmp")
1112    (set_attr "modrm" "1")
1113    (set_attr "mode" "QI")])
1115 (define_insn "*cmpqi_ext_4"
1116   [(set (reg FLAGS_REG)
1117         (compare
1118           (subreg:QI
1119             (zero_extract:SI
1120               (match_operand 0 "ext_register_operand" "Q")
1121               (const_int 8)
1122               (const_int 8)) 0)
1123           (subreg:QI
1124             (zero_extract:SI
1125               (match_operand 1 "ext_register_operand" "Q")
1126               (const_int 8)
1127               (const_int 8)) 0)))]
1128   "ix86_match_ccmode (insn, CCmode)"
1129   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1130   [(set_attr "type" "icmp")
1131    (set_attr "mode" "QI")])
1133 ;; These implement float point compares.
1134 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1135 ;; which would allow mix and match FP modes on the compares.  Which is what
1136 ;; the old patterns did, but with many more of them.
1138 (define_expand "cbranchxf4"
1139   [(set (reg:CC FLAGS_REG)
1140         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1141                     (match_operand:XF 2 "nonmemory_operand")))
1142    (set (pc) (if_then_else
1143               (match_operator 0 "ix86_fp_comparison_operator"
1144                [(reg:CC FLAGS_REG)
1145                 (const_int 0)])
1146               (label_ref (match_operand 3))
1147               (pc)))]
1148   "TARGET_80387"
1150   ix86_expand_branch (GET_CODE (operands[0]),
1151                       operands[1], operands[2], operands[3]);
1152   DONE;
1155 (define_expand "cstorexf4"
1156   [(set (reg:CC FLAGS_REG)
1157         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1158                     (match_operand:XF 3 "nonmemory_operand")))
1159    (set (match_operand:QI 0 "register_operand")
1160               (match_operator 1 "ix86_fp_comparison_operator"
1161                [(reg:CC FLAGS_REG)
1162                 (const_int 0)]))]
1163   "TARGET_80387"
1165   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1166                      operands[2], operands[3]);
1167   DONE;
1170 (define_expand "cbranch<mode>4"
1171   [(set (reg:CC FLAGS_REG)
1172         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1173                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1174    (set (pc) (if_then_else
1175               (match_operator 0 "ix86_fp_comparison_operator"
1176                [(reg:CC FLAGS_REG)
1177                 (const_int 0)])
1178               (label_ref (match_operand 3))
1179               (pc)))]
1180   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1182   ix86_expand_branch (GET_CODE (operands[0]),
1183                       operands[1], operands[2], operands[3]);
1184   DONE;
1187 (define_expand "cstore<mode>4"
1188   [(set (reg:CC FLAGS_REG)
1189         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1190                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1191    (set (match_operand:QI 0 "register_operand")
1192               (match_operator 1 "ix86_fp_comparison_operator"
1193                [(reg:CC FLAGS_REG)
1194                 (const_int 0)]))]
1195   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1197   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1198                      operands[2], operands[3]);
1199   DONE;
1202 (define_expand "cbranchcc4"
1203   [(set (pc) (if_then_else
1204               (match_operator 0 "comparison_operator"
1205                [(match_operand 1 "flags_reg_operand")
1206                 (match_operand 2 "const0_operand")])
1207               (label_ref (match_operand 3))
1208               (pc)))]
1209   ""
1211   ix86_expand_branch (GET_CODE (operands[0]),
1212                       operands[1], operands[2], operands[3]);
1213   DONE;
1216 (define_expand "cstorecc4"
1217   [(set (match_operand:QI 0 "register_operand")
1218               (match_operator 1 "comparison_operator"
1219                [(match_operand 2 "flags_reg_operand")
1220                 (match_operand 3 "const0_operand")]))]
1221   ""
1223   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1224                      operands[2], operands[3]);
1225   DONE;
1229 ;; FP compares, step 1:
1230 ;; Set the FP condition codes.
1232 ;; CCFPmode     compare with exceptions
1233 ;; CCFPUmode    compare with no exceptions
1235 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1236 ;; used to manage the reg stack popping would not be preserved.
1238 (define_insn "*cmp<mode>_0_i387"
1239   [(set (match_operand:HI 0 "register_operand" "=a")
1240         (unspec:HI
1241           [(compare:CCFP
1242              (match_operand:X87MODEF 1 "register_operand" "f")
1243              (match_operand:X87MODEF 2 "const0_operand"))]
1244         UNSPEC_FNSTSW))]
1245   "TARGET_80387"
1246   "* return output_fp_compare (insn, operands, false, false);"
1247   [(set_attr "type" "multi")
1248    (set_attr "unit" "i387")
1249    (set_attr "mode" "<MODE>")])
1251 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1252   [(set (reg:CCFP FLAGS_REG)
1253         (compare:CCFP
1254           (match_operand:X87MODEF 1 "register_operand" "f")
1255           (match_operand:X87MODEF 2 "const0_operand")))
1256    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1257   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1258   "#"
1259   "&& reload_completed"
1260   [(set (match_dup 0)
1261         (unspec:HI
1262           [(compare:CCFP (match_dup 1)(match_dup 2))]
1263         UNSPEC_FNSTSW))
1264    (set (reg:CC FLAGS_REG)
1265         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1266   ""
1267   [(set_attr "type" "multi")
1268    (set_attr "unit" "i387")
1269    (set_attr "mode" "<MODE>")])
1271 (define_insn "*cmpxf_i387"
1272   [(set (match_operand:HI 0 "register_operand" "=a")
1273         (unspec:HI
1274           [(compare:CCFP
1275              (match_operand:XF 1 "register_operand" "f")
1276              (match_operand:XF 2 "register_operand" "f"))]
1277           UNSPEC_FNSTSW))]
1278   "TARGET_80387"
1279   "* return output_fp_compare (insn, operands, false, false);"
1280   [(set_attr "type" "multi")
1281    (set_attr "unit" "i387")
1282    (set_attr "mode" "XF")])
1284 (define_insn_and_split "*cmpxf_cc_i387"
1285   [(set (reg:CCFP FLAGS_REG)
1286         (compare:CCFP
1287           (match_operand:XF 1 "register_operand" "f")
1288           (match_operand:XF 2 "register_operand" "f")))
1289    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1290   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1291   "#"
1292   "&& reload_completed"
1293   [(set (match_dup 0)
1294         (unspec:HI
1295           [(compare:CCFP (match_dup 1)(match_dup 2))]
1296         UNSPEC_FNSTSW))
1297    (set (reg:CC FLAGS_REG)
1298         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1299   ""
1300   [(set_attr "type" "multi")
1301    (set_attr "unit" "i387")
1302    (set_attr "mode" "XF")])
1304 (define_insn "*cmp<mode>_i387"
1305   [(set (match_operand:HI 0 "register_operand" "=a")
1306         (unspec:HI
1307           [(compare:CCFP
1308              (match_operand:MODEF 1 "register_operand" "f")
1309              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1310           UNSPEC_FNSTSW))]
1311   "TARGET_80387"
1312   "* return output_fp_compare (insn, operands, false, false);"
1313   [(set_attr "type" "multi")
1314    (set_attr "unit" "i387")
1315    (set_attr "mode" "<MODE>")])
1317 (define_insn_and_split "*cmp<mode>_cc_i387"
1318   [(set (reg:CCFP FLAGS_REG)
1319         (compare:CCFP
1320           (match_operand:MODEF 1 "register_operand" "f")
1321           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1322    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1323   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1324   "#"
1325   "&& reload_completed"
1326   [(set (match_dup 0)
1327         (unspec:HI
1328           [(compare:CCFP (match_dup 1)(match_dup 2))]
1329         UNSPEC_FNSTSW))
1330    (set (reg:CC FLAGS_REG)
1331         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1332   ""
1333   [(set_attr "type" "multi")
1334    (set_attr "unit" "i387")
1335    (set_attr "mode" "<MODE>")])
1337 (define_insn "*cmpu<mode>_i387"
1338   [(set (match_operand:HI 0 "register_operand" "=a")
1339         (unspec:HI
1340           [(compare:CCFPU
1341              (match_operand:X87MODEF 1 "register_operand" "f")
1342              (match_operand:X87MODEF 2 "register_operand" "f"))]
1343           UNSPEC_FNSTSW))]
1344   "TARGET_80387"
1345   "* return output_fp_compare (insn, operands, false, true);"
1346   [(set_attr "type" "multi")
1347    (set_attr "unit" "i387")
1348    (set_attr "mode" "<MODE>")])
1350 (define_insn_and_split "*cmpu<mode>_cc_i387"
1351   [(set (reg:CCFPU FLAGS_REG)
1352         (compare:CCFPU
1353           (match_operand:X87MODEF 1 "register_operand" "f")
1354           (match_operand:X87MODEF 2 "register_operand" "f")))
1355    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1356   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1357   "#"
1358   "&& reload_completed"
1359   [(set (match_dup 0)
1360         (unspec:HI
1361           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1362         UNSPEC_FNSTSW))
1363    (set (reg:CC FLAGS_REG)
1364         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1365   ""
1366   [(set_attr "type" "multi")
1367    (set_attr "unit" "i387")
1368    (set_attr "mode" "<MODE>")])
1370 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1371   [(set (match_operand:HI 0 "register_operand" "=a")
1372         (unspec:HI
1373           [(compare:CCFP
1374              (match_operand:X87MODEF 1 "register_operand" "f")
1375              (match_operator:X87MODEF 3 "float_operator"
1376                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1377           UNSPEC_FNSTSW))]
1378   "TARGET_80387
1379    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1380        || optimize_function_for_size_p (cfun))"
1381   "* return output_fp_compare (insn, operands, false, false);"
1382   [(set_attr "type" "multi")
1383    (set_attr "unit" "i387")
1384    (set_attr "fp_int_src" "true")
1385    (set_attr "mode" "<SWI24:MODE>")])
1387 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1388   [(set (reg:CCFP FLAGS_REG)
1389         (compare:CCFP
1390           (match_operand:X87MODEF 1 "register_operand" "f")
1391           (match_operator:X87MODEF 3 "float_operator"
1392             [(match_operand:SWI24 2 "memory_operand" "m")])))
1393    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1395    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1396        || optimize_function_for_size_p (cfun))"
1397   "#"
1398   "&& reload_completed"
1399   [(set (match_dup 0)
1400         (unspec:HI
1401           [(compare:CCFP
1402              (match_dup 1)
1403              (match_op_dup 3 [(match_dup 2)]))]
1404         UNSPEC_FNSTSW))
1405    (set (reg:CC FLAGS_REG)
1406         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1407   ""
1408   [(set_attr "type" "multi")
1409    (set_attr "unit" "i387")
1410    (set_attr "fp_int_src" "true")
1411    (set_attr "mode" "<SWI24:MODE>")])
1413 ;; FP compares, step 2
1414 ;; Move the fpsw to ax.
1416 (define_insn "x86_fnstsw_1"
1417   [(set (match_operand:HI 0 "register_operand" "=a")
1418         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1419   "TARGET_80387"
1420   "fnstsw\t%0"
1421   [(set (attr "length")
1422         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1423    (set_attr "mode" "SI")
1424    (set_attr "unit" "i387")])
1426 ;; FP compares, step 3
1427 ;; Get ax into flags, general case.
1429 (define_insn "x86_sahf_1"
1430   [(set (reg:CC FLAGS_REG)
1431         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1432                    UNSPEC_SAHF))]
1433   "TARGET_SAHF"
1435 #ifndef HAVE_AS_IX86_SAHF
1436   if (TARGET_64BIT)
1437     return ASM_BYTE "0x9e";
1438   else
1439 #endif
1440   return "sahf";
1442   [(set_attr "length" "1")
1443    (set_attr "athlon_decode" "vector")
1444    (set_attr "amdfam10_decode" "direct")
1445    (set_attr "bdver1_decode" "direct")
1446    (set_attr "mode" "SI")])
1448 ;; Pentium Pro can do steps 1 through 3 in one go.
1449 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1450 ;; (these i387 instructions set flags directly)
1452 (define_mode_iterator FPCMP [CCFP CCFPU])
1453 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1455 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1456   [(set (reg:FPCMP FLAGS_REG)
1457         (compare:FPCMP
1458           (match_operand:MODEF 0 "register_operand" "f,x")
1459           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1460   "TARGET_MIX_SSE_I387
1461    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1462   "* return output_fp_compare (insn, operands, true,
1463                                <FPCMP:MODE>mode == CCFPUmode);"
1464   [(set_attr "type" "fcmp,ssecomi")
1465    (set_attr "prefix" "orig,maybe_vex")
1466    (set_attr "mode" "<MODEF:MODE>")
1467    (set (attr "prefix_rep")
1468         (if_then_else (eq_attr "type" "ssecomi")
1469                       (const_string "0")
1470                       (const_string "*")))
1471    (set (attr "prefix_data16")
1472         (cond [(eq_attr "type" "fcmp")
1473                  (const_string "*")
1474                (eq_attr "mode" "DF")
1475                  (const_string "1")
1476               ]
1477               (const_string "0")))
1478    (set_attr "athlon_decode" "vector")
1479    (set_attr "amdfam10_decode" "direct")
1480    (set_attr "bdver1_decode" "double")])
1482 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1483   [(set (reg:FPCMP FLAGS_REG)
1484         (compare:FPCMP
1485           (match_operand:MODEF 0 "register_operand" "x")
1486           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1487   "TARGET_SSE_MATH
1488    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1489   "* return output_fp_compare (insn, operands, true,
1490                                <FPCMP:MODE>mode == CCFPUmode);"
1491   [(set_attr "type" "ssecomi")
1492    (set_attr "prefix" "maybe_vex")
1493    (set_attr "mode" "<MODEF:MODE>")
1494    (set_attr "prefix_rep" "0")
1495    (set (attr "prefix_data16")
1496         (if_then_else (eq_attr "mode" "DF")
1497                       (const_string "1")
1498                       (const_string "0")))
1499    (set_attr "athlon_decode" "vector")
1500    (set_attr "amdfam10_decode" "direct")
1501    (set_attr "bdver1_decode" "double")])
1503 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1504   [(set (reg:FPCMP FLAGS_REG)
1505         (compare:FPCMP
1506           (match_operand:X87MODEF 0 "register_operand" "f")
1507           (match_operand:X87MODEF 1 "register_operand" "f")))]
1508   "TARGET_80387 && TARGET_CMOVE
1509    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1510   "* return output_fp_compare (insn, operands, true,
1511                                <FPCMP:MODE>mode == CCFPUmode);"
1512   [(set_attr "type" "fcmp")
1513    (set_attr "mode" "<X87MODEF:MODE>")
1514    (set_attr "athlon_decode" "vector")
1515    (set_attr "amdfam10_decode" "direct")
1516    (set_attr "bdver1_decode" "double")])
1518 ;; Push/pop instructions.
1520 (define_insn "*push<mode>2"
1521   [(set (match_operand:DWI 0 "push_operand" "=<")
1522         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1523   ""
1524   "#"
1525   [(set_attr "type" "multi")
1526    (set_attr "mode" "<MODE>")])
1528 (define_split
1529   [(set (match_operand:TI 0 "push_operand")
1530         (match_operand:TI 1 "general_operand"))]
1531   "TARGET_64BIT && reload_completed
1532    && !SSE_REG_P (operands[1])"
1533   [(const_int 0)]
1534   "ix86_split_long_move (operands); DONE;")
1536 (define_insn "*pushdi2_rex64"
1537   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1538         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1539   "TARGET_64BIT"
1540   "@
1541    push{q}\t%1
1542    #"
1543   [(set_attr "type" "push,multi")
1544    (set_attr "mode" "DI")])
1546 ;; Convert impossible pushes of immediate to existing instructions.
1547 ;; First try to get scratch register and go through it.  In case this
1548 ;; fails, push sign extended lower part first and then overwrite
1549 ;; upper part by 32bit move.
1550 (define_peephole2
1551   [(match_scratch:DI 2 "r")
1552    (set (match_operand:DI 0 "push_operand")
1553         (match_operand:DI 1 "immediate_operand"))]
1554   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1555    && !x86_64_immediate_operand (operands[1], DImode)"
1556   [(set (match_dup 2) (match_dup 1))
1557    (set (match_dup 0) (match_dup 2))])
1559 ;; We need to define this as both peepholer and splitter for case
1560 ;; peephole2 pass is not run.
1561 ;; "&& 1" is needed to keep it from matching the previous pattern.
1562 (define_peephole2
1563   [(set (match_operand:DI 0 "push_operand")
1564         (match_operand:DI 1 "immediate_operand"))]
1565   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1566    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1567   [(set (match_dup 0) (match_dup 1))
1568    (set (match_dup 2) (match_dup 3))]
1570   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1572   operands[1] = gen_lowpart (DImode, operands[2]);
1573   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1574                                                    GEN_INT (4)));
1577 (define_split
1578   [(set (match_operand:DI 0 "push_operand")
1579         (match_operand:DI 1 "immediate_operand"))]
1580   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1581                     ? epilogue_completed : reload_completed)
1582    && !symbolic_operand (operands[1], DImode)
1583    && !x86_64_immediate_operand (operands[1], DImode)"
1584   [(set (match_dup 0) (match_dup 1))
1585    (set (match_dup 2) (match_dup 3))]
1587   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1589   operands[1] = gen_lowpart (DImode, operands[2]);
1590   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1591                                                    GEN_INT (4)));
1594 (define_split
1595   [(set (match_operand:DI 0 "push_operand")
1596         (match_operand:DI 1 "general_operand"))]
1597   "!TARGET_64BIT && reload_completed
1598    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1599   [(const_int 0)]
1600   "ix86_split_long_move (operands); DONE;")
1602 (define_insn "*pushsi2"
1603   [(set (match_operand:SI 0 "push_operand" "=<")
1604         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1605   "!TARGET_64BIT"
1606   "push{l}\t%1"
1607   [(set_attr "type" "push")
1608    (set_attr "mode" "SI")])
1610 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1611 ;; "push a byte/word".  But actually we use pushl, which has the effect
1612 ;; of rounding the amount pushed up to a word.
1614 ;; For TARGET_64BIT we always round up to 8 bytes.
1615 (define_insn "*push<mode>2_rex64"
1616   [(set (match_operand:SWI124 0 "push_operand" "=X")
1617         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1618   "TARGET_64BIT"
1619   "push{q}\t%q1"
1620   [(set_attr "type" "push")
1621    (set_attr "mode" "DI")])
1623 (define_insn "*push<mode>2"
1624   [(set (match_operand:SWI12 0 "push_operand" "=X")
1625         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1626   "!TARGET_64BIT"
1627   "push{l}\t%k1"
1628   [(set_attr "type" "push")
1629    (set_attr "mode" "SI")])
1631 (define_insn "*push<mode>2_prologue"
1632   [(set (match_operand:W 0 "push_operand" "=<")
1633         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1634    (clobber (mem:BLK (scratch)))]
1635   ""
1636   "push{<imodesuffix>}\t%1"
1637   [(set_attr "type" "push")
1638    (set_attr "mode" "<MODE>")])
1640 (define_insn "*pop<mode>1"
1641   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1642         (match_operand:W 1 "pop_operand" ">"))]
1643   ""
1644   "pop{<imodesuffix>}\t%0"
1645   [(set_attr "type" "pop")
1646    (set_attr "mode" "<MODE>")])
1648 (define_insn "*pop<mode>1_epilogue"
1649   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1650         (match_operand:W 1 "pop_operand" ">"))
1651    (clobber (mem:BLK (scratch)))]
1652   ""
1653   "pop{<imodesuffix>}\t%0"
1654   [(set_attr "type" "pop")
1655    (set_attr "mode" "<MODE>")])
1657 ;; Move instructions.
1659 ;; Reload patterns to support multi-word load/store
1660 ;; with non-offsetable address.
1661 (define_expand "reload_noff_store"
1662   [(parallel [(match_operand 0 "memory_operand" "=m")
1663               (match_operand 1 "register_operand" "r")
1664               (match_operand:DI 2 "register_operand" "=&r")])]
1665   "TARGET_64BIT"
1667   rtx mem = operands[0];
1668   rtx addr = XEXP (mem, 0);
1670   emit_move_insn (operands[2], addr);
1671   mem = replace_equiv_address_nv (mem, operands[2]);
1673   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1674   DONE;
1677 (define_expand "reload_noff_load"
1678   [(parallel [(match_operand 0 "register_operand" "=r")
1679               (match_operand 1 "memory_operand" "m")
1680               (match_operand:DI 2 "register_operand" "=r")])]
1681   "TARGET_64BIT"
1683   rtx mem = operands[1];
1684   rtx addr = XEXP (mem, 0);
1686   emit_move_insn (operands[2], addr);
1687   mem = replace_equiv_address_nv (mem, operands[2]);
1689   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1690   DONE;
1693 (define_expand "movoi"
1694   [(set (match_operand:OI 0 "nonimmediate_operand")
1695         (match_operand:OI 1 "general_operand"))]
1696   "TARGET_AVX"
1697   "ix86_expand_move (OImode, operands); DONE;")
1699 (define_expand "movti"
1700   [(set (match_operand:TI 0 "nonimmediate_operand")
1701         (match_operand:TI 1 "nonimmediate_operand"))]
1702   "TARGET_64BIT || TARGET_SSE"
1704   if (TARGET_64BIT)
1705     ix86_expand_move (TImode, operands);
1706   else if (push_operand (operands[0], TImode))
1707     ix86_expand_push (TImode, operands[1]);
1708   else
1709     ix86_expand_vector_move (TImode, operands);
1710   DONE;
1713 ;; This expands to what emit_move_complex would generate if we didn't
1714 ;; have a movti pattern.  Having this avoids problems with reload on
1715 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1716 ;; to have around all the time.
1717 (define_expand "movcdi"
1718   [(set (match_operand:CDI 0 "nonimmediate_operand")
1719         (match_operand:CDI 1 "general_operand"))]
1720   ""
1722   if (push_operand (operands[0], CDImode))
1723     emit_move_complex_push (CDImode, operands[0], operands[1]);
1724   else
1725     emit_move_complex_parts (operands[0], operands[1]);
1726   DONE;
1729 (define_expand "mov<mode>"
1730   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1731         (match_operand:SWI1248x 1 "general_operand"))]
1732   ""
1733   "ix86_expand_move (<MODE>mode, operands); DONE;")
1735 (define_insn "*mov<mode>_xor"
1736   [(set (match_operand:SWI48 0 "register_operand" "=r")
1737         (match_operand:SWI48 1 "const0_operand"))
1738    (clobber (reg:CC FLAGS_REG))]
1739   "reload_completed"
1740   "xor{l}\t%k0, %k0"
1741   [(set_attr "type" "alu1")
1742    (set_attr "mode" "SI")
1743    (set_attr "length_immediate" "0")])
1745 (define_insn "*mov<mode>_or"
1746   [(set (match_operand:SWI48 0 "register_operand" "=r")
1747         (match_operand:SWI48 1 "const_int_operand"))
1748    (clobber (reg:CC FLAGS_REG))]
1749   "reload_completed
1750    && operands[1] == constm1_rtx"
1751   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1752   [(set_attr "type" "alu1")
1753    (set_attr "mode" "<MODE>")
1754    (set_attr "length_immediate" "1")])
1756 (define_insn "*movoi_internal_avx"
1757   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1758         (match_operand:OI 1 "vector_move_operand"  "C ,xm,x"))]
1759   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1761   switch (which_alternative)
1762     {
1763     case 0:
1764       return standard_sse_constant_opcode (insn, operands[1]);
1765     case 1:
1766     case 2:
1767       if (misaligned_operand (operands[0], OImode)
1768           || misaligned_operand (operands[1], OImode))
1769         {
1770           if (get_attr_mode (insn) == MODE_V8SF)
1771             return "vmovups\t{%1, %0|%0, %1}";
1772           else
1773             return "vmovdqu\t{%1, %0|%0, %1}";
1774         }
1775       else
1776         {
1777           if (get_attr_mode (insn) == MODE_V8SF)
1778             return "vmovaps\t{%1, %0|%0, %1}";
1779           else
1780             return "vmovdqa\t{%1, %0|%0, %1}";
1781         }
1782     default:
1783       gcc_unreachable ();
1784     }
1786   [(set_attr "type" "sselog1,ssemov,ssemov")
1787    (set_attr "prefix" "vex")
1788    (set (attr "mode")
1789         (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1790                  (const_string "V8SF")
1791                (and (eq_attr "alternative" "2")
1792                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1793                  (const_string "V8SF")
1794               ]
1795               (const_string "OI")))])
1797 (define_insn "*movti_internal"
1798   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1799         (match_operand:TI 1 "general_operand"      "riFo,re,C,xm,x"))]
1800   "(TARGET_64BIT || TARGET_SSE)
1801    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1803   switch (which_alternative)
1804     {
1805     case 0:
1806     case 1:
1807       return "#";
1808     case 2:
1809       return standard_sse_constant_opcode (insn, operands[1]);
1810     case 3:
1811     case 4:
1812       /* TDmode values are passed as TImode on the stack.  Moving them
1813          to stack may result in unaligned memory access.  */
1814       if (misaligned_operand (operands[0], TImode)
1815           || misaligned_operand (operands[1], TImode))
1816         {
1817           if (get_attr_mode (insn) == MODE_V4SF)
1818             return "%vmovups\t{%1, %0|%0, %1}";
1819           else
1820             return "%vmovdqu\t{%1, %0|%0, %1}";
1821         }
1822       else
1823         {
1824           if (get_attr_mode (insn) == MODE_V4SF)
1825             return "%vmovaps\t{%1, %0|%0, %1}";
1826           else
1827             return "%vmovdqa\t{%1, %0|%0, %1}";
1828         }
1829     default:
1830       gcc_unreachable ();
1831     }
1833   [(set_attr "isa" "x64,x64,*,*,*")
1834    (set_attr "type" "*,*,sselog1,ssemov,ssemov")
1835    (set (attr "prefix")
1836      (if_then_else (eq_attr "type" "sselog1,ssemov")
1837        (const_string "maybe_vex")
1838        (const_string "orig")))
1839    (set (attr "mode")
1840         (cond [(eq_attr "alternative" "0,1")
1841                  (const_string "DI")
1842                (ior (not (match_test "TARGET_SSE2"))
1843                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1844                  (const_string "V4SF")
1845                (and (eq_attr "alternative" "4")
1846                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1847                  (const_string "V4SF")
1848                (match_test "TARGET_AVX")
1849                  (const_string "TI")
1850                (match_test "optimize_function_for_size_p (cfun)")
1851                  (const_string "V4SF")
1852                ]
1853                (const_string "TI")))])
1855 (define_split
1856   [(set (match_operand:TI 0 "nonimmediate_operand")
1857         (match_operand:TI 1 "general_operand"))]
1858   "reload_completed
1859    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1860   [(const_int 0)]
1861   "ix86_split_long_move (operands); DONE;")
1863 (define_insn "*movdi_internal"
1864   [(set (match_operand:DI 0 "nonimmediate_operand"
1865     "=r  ,o  ,r,r  ,r,m ,*y,m*y,*y,?*y,?r ,?*Ym,*x,*x,*x,m ,?r ,?*Yi,?*x,?*Ym")
1866         (match_operand:DI 1 "general_operand"
1867     "riFo,riF,Z,rem,i,re,C ,*y ,m ,m  ,*Ym,r   ,C ,*x,m ,*x,*Yi,r   ,*Ym,*x"))]
1868   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1870   switch (get_attr_type (insn))
1871     {
1872     case TYPE_MULTI:
1873       return "#";
1875     case TYPE_MMX:
1876       return "pxor\t%0, %0";
1878     case TYPE_MMXMOV:
1879       /* Handle broken assemblers that require movd instead of movq.  */
1880       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1881         return "movd\t{%1, %0|%0, %1}";
1882       return "movq\t{%1, %0|%0, %1}";
1884     case TYPE_SSELOG1:
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           /* Handle broken assemblers that require movd instead of movq.  */
1892           if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1893             return "%vmovd\t{%1, %0|%0, %1}";
1894           return "%vmovq\t{%1, %0|%0, %1}";
1895         case MODE_TI:
1896           return "%vmovdqa\t{%1, %0|%0, %1}";
1898         case MODE_V2SF:
1899           gcc_assert (!TARGET_AVX);
1900           return "movlps\t{%1, %0|%0, %1}";
1901         case MODE_V4SF:
1902           return "%vmovaps\t{%1, %0|%0, %1}";
1904         default:
1905           gcc_unreachable ();
1906         }
1908     case TYPE_SSECVT:
1909       if (SSE_REG_P (operands[0]))
1910         return "movq2dq\t{%1, %0|%0, %1}";
1911       else
1912         return "movdq2q\t{%1, %0|%0, %1}";
1914     case TYPE_LEA:
1915       return "lea{q}\t{%E1, %0|%0, %E1}";
1917     default:
1918       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1919       if (get_attr_mode (insn) == MODE_SI)
1920         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1921       else if (which_alternative == 4)
1922         return "movabs{q}\t{%1, %0|%0, %1}";
1923       else if (ix86_use_lea_for_mov (insn, operands))
1924         return "lea{q}\t{%E1, %0|%0, %E1}";
1925       else
1926         return "mov{q}\t{%1, %0|%0, %1}";
1927     }
1929   [(set (attr "isa")
1930      (cond [(eq_attr "alternative" "0,1,8")
1931               (const_string "nox64")
1932             (eq_attr "alternative" "2,3,4,5,9,10,11,16,17")
1933               (const_string "x64")
1934             (eq_attr "alternative" "18,19")
1935               (const_string "sse2")
1936            ]
1937            (const_string "*")))
1938    (set (attr "type")
1939      (cond [(eq_attr "alternative" "0,1")
1940               (const_string "multi")
1941             (eq_attr "alternative" "6")
1942               (const_string "mmx")
1943             (eq_attr "alternative" "7,8,9,10,11")
1944               (const_string "mmxmov")
1945             (eq_attr "alternative" "12")
1946               (const_string "sselog1")
1947             (eq_attr "alternative" "13,14,15,16,17")
1948               (const_string "ssemov")
1949             (eq_attr "alternative" "18,19")
1950               (const_string "ssecvt")
1951             (match_operand 1 "pic_32bit_operand")
1952               (const_string "lea")
1953            ]
1954            (const_string "imov")))
1955    (set (attr "modrm")
1956      (if_then_else
1957        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1958          (const_string "0")
1959          (const_string "*")))
1960    (set (attr "length_immediate")
1961      (if_then_else
1962        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1963          (const_string "8")
1964          (const_string "*")))
1965    (set (attr "prefix_rex")
1966      (if_then_else (eq_attr "alternative" "10,11")
1967        (const_string "1")
1968        (const_string "*")))
1969    (set (attr "prefix")
1970      (if_then_else (eq_attr "type" "sselog1,ssemov")
1971        (const_string "maybe_vex")
1972        (const_string "orig")))
1973    (set (attr "prefix_data16")
1974      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
1975        (const_string "1")
1976        (const_string "*")))
1977    (set (attr "mode")
1978      (cond [(eq_attr "alternative" "2")
1979               (const_string "SI")
1980             (eq_attr "alternative" "12,13")
1981               (cond [(ior (not (match_test "TARGET_SSE2"))
1982                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1983                        (const_string "V4SF")
1984                      (match_test "TARGET_AVX")
1985                        (const_string "TI")
1986                      (match_test "optimize_function_for_size_p (cfun)")
1987                        (const_string "V4SF")
1988                     ]
1989                     (const_string "TI"))
1991             (and (eq_attr "alternative" "14,15")
1992                  (not (match_test "TARGET_SSE2")))
1993               (const_string "V2SF")
1994            ]
1995            (const_string "DI")))])
1997 (define_split
1998   [(set (match_operand:DI 0 "nonimmediate_operand")
1999         (match_operand:DI 1 "general_operand"))]
2000   "!TARGET_64BIT && reload_completed
2001    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2002    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2003   [(const_int 0)]
2004   "ix86_split_long_move (operands); DONE;")
2006 (define_insn "*movsi_internal"
2007   [(set (match_operand:SI 0 "nonimmediate_operand"
2008                         "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?*Yi")
2009         (match_operand:SI 1 "general_operand"
2010                         "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yi,r"))]
2011   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2013   switch (get_attr_type (insn))
2014     {
2015     case TYPE_SSELOG1:
2016       return standard_sse_constant_opcode (insn, operands[1]);
2018     case TYPE_SSEMOV:
2019       switch (get_attr_mode (insn))
2020         {
2021         case MODE_TI:
2022           return "%vmovdqa\t{%1, %0|%0, %1}";
2023         case MODE_V4SF:
2024           return "%vmovaps\t{%1, %0|%0, %1}";
2025         case MODE_SI:
2026           return "%vmovd\t{%1, %0|%0, %1}";
2027         case MODE_SF:
2028           return "%vmovss\t{%1, %0|%0, %1}";
2029         default:
2030           gcc_unreachable ();
2031         }
2033     case TYPE_MMX:
2034       return "pxor\t%0, %0";
2036     case TYPE_MMXMOV:
2037       if (get_attr_mode (insn) == MODE_DI)
2038         return "movq\t{%1, %0|%0, %1}";
2039       return "movd\t{%1, %0|%0, %1}";
2041     case TYPE_LEA:
2042       return "lea{l}\t{%E1, %0|%0, %E1}";
2044     default:
2045       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2046       if (ix86_use_lea_for_mov (insn, operands))
2047         return "lea{l}\t{%E1, %0|%0, %E1}";
2048       else
2049         return "mov{l}\t{%1, %0|%0, %1}";
2050     }
2052   [(set (attr "type")
2053      (cond [(eq_attr "alternative" "2")
2054               (const_string "mmx")
2055             (eq_attr "alternative" "3,4,5")
2056               (const_string "mmxmov")
2057             (eq_attr "alternative" "6")
2058               (const_string "sselog1")
2059             (eq_attr "alternative" "7,8,9,10,11")
2060               (const_string "ssemov")
2061             (match_operand 1 "pic_32bit_operand")
2062               (const_string "lea")
2063            ]
2064            (const_string "imov")))
2065    (set (attr "prefix")
2066      (if_then_else (eq_attr "type" "sselog1,ssemov")
2067        (const_string "maybe_vex")
2068        (const_string "orig")))
2069    (set (attr "prefix_data16")
2070      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2071        (const_string "1")
2072        (const_string "*")))
2073    (set (attr "mode")
2074      (cond [(eq_attr "alternative" "2,3")
2075               (const_string "DI")
2076             (eq_attr "alternative" "6,7")
2077               (cond [(ior (not (match_test "TARGET_SSE2"))
2078                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2079                        (const_string "V4SF")
2080                      (match_test "TARGET_AVX")
2081                        (const_string "TI")
2082                      (match_test "optimize_function_for_size_p (cfun)")
2083                        (const_string "V4SF")
2084                     ]
2085                     (const_string "TI"))
2087             (and (eq_attr "alternative" "8,9")
2088                  (not (match_test "TARGET_SSE2")))
2089               (const_string "SF")
2090            ]
2091            (const_string "SI")))])
2093 (define_insn "*movhi_internal"
2094   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
2095         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn"))]
2096   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2098   switch (get_attr_type (insn))
2099     {
2100     case TYPE_IMOVX:
2101       /* movzwl is faster than movw on p2 due to partial word stalls,
2102          though not as fast as an aligned movl.  */
2103       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2104     default:
2105       if (get_attr_mode (insn) == MODE_SI)
2106         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2107       else
2108         return "mov{w}\t{%1, %0|%0, %1}";
2109     }
2111   [(set (attr "type")
2112      (cond [(match_test "optimize_function_for_size_p (cfun)")
2113               (const_string "imov")
2114             (and (eq_attr "alternative" "0")
2115                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2116                       (not (match_test "TARGET_HIMODE_MATH"))))
2117               (const_string "imov")
2118             (and (eq_attr "alternative" "1,2")
2119                  (match_operand:HI 1 "aligned_operand"))
2120               (const_string "imov")
2121             (and (match_test "TARGET_MOVX")
2122                  (eq_attr "alternative" "0,2"))
2123               (const_string "imovx")
2124            ]
2125            (const_string "imov")))
2126     (set (attr "mode")
2127       (cond [(eq_attr "type" "imovx")
2128                (const_string "SI")
2129              (and (eq_attr "alternative" "1,2")
2130                   (match_operand:HI 1 "aligned_operand"))
2131                (const_string "SI")
2132              (and (eq_attr "alternative" "0")
2133                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2134                        (not (match_test "TARGET_HIMODE_MATH"))))
2135                (const_string "SI")
2136             ]
2137             (const_string "HI")))])
2139 ;; Situation is quite tricky about when to choose full sized (SImode) move
2140 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2141 ;; partial register dependency machines (such as AMD Athlon), where QImode
2142 ;; moves issue extra dependency and for partial register stalls machines
2143 ;; that don't use QImode patterns (and QImode move cause stall on the next
2144 ;; instruction).
2146 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2147 ;; register stall machines with, where we use QImode instructions, since
2148 ;; partial register stall can be caused there.  Then we use movzx.
2149 (define_insn "*movqi_internal"
2150   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2151         (match_operand:QI 1 "general_operand"      "q ,qn,qm,q,rn,qm,qn"))]
2152   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2154   switch (get_attr_type (insn))
2155     {
2156     case TYPE_IMOVX:
2157       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2158       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2159     default:
2160       if (get_attr_mode (insn) == MODE_SI)
2161         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2162       else
2163         return "mov{b}\t{%1, %0|%0, %1}";
2164     }
2166   [(set (attr "type")
2167      (cond [(and (eq_attr "alternative" "5")
2168                  (not (match_operand:QI 1 "aligned_operand")))
2169               (const_string "imovx")
2170             (match_test "optimize_function_for_size_p (cfun)")
2171               (const_string "imov")
2172             (and (eq_attr "alternative" "3")
2173                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2174                       (not (match_test "TARGET_QIMODE_MATH"))))
2175               (const_string "imov")
2176             (eq_attr "alternative" "3,5")
2177               (const_string "imovx")
2178             (and (match_test "TARGET_MOVX")
2179                  (eq_attr "alternative" "2"))
2180               (const_string "imovx")
2181            ]
2182            (const_string "imov")))
2183    (set (attr "mode")
2184       (cond [(eq_attr "alternative" "3,4,5")
2185                (const_string "SI")
2186              (eq_attr "alternative" "6")
2187                (const_string "QI")
2188              (eq_attr "type" "imovx")
2189                (const_string "SI")
2190              (and (eq_attr "type" "imov")
2191                   (and (eq_attr "alternative" "0,1")
2192                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2193                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2194                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2195                (const_string "SI")
2196              ;; Avoid partial register stalls when not using QImode arithmetic
2197              (and (eq_attr "type" "imov")
2198                   (and (eq_attr "alternative" "0,1")
2199                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2200                             (not (match_test "TARGET_QIMODE_MATH")))))
2201                (const_string "SI")
2202            ]
2203            (const_string "QI")))])
2205 ;; Stores and loads of ax to arbitrary constant address.
2206 ;; We fake an second form of instruction to force reload to load address
2207 ;; into register when rax is not available
2208 (define_insn "*movabs<mode>_1"
2209   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2210         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2211   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2212   "@
2213    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2214    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2215   [(set_attr "type" "imov")
2216    (set_attr "modrm" "0,*")
2217    (set_attr "length_address" "8,0")
2218    (set_attr "length_immediate" "0,*")
2219    (set_attr "memory" "store")
2220    (set_attr "mode" "<MODE>")])
2222 (define_insn "*movabs<mode>_2"
2223   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2224         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2225   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2226   "@
2227    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2228    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2229   [(set_attr "type" "imov")
2230    (set_attr "modrm" "0,*")
2231    (set_attr "length_address" "8,0")
2232    (set_attr "length_immediate" "0")
2233    (set_attr "memory" "load")
2234    (set_attr "mode" "<MODE>")])
2236 (define_insn "swap<mode>"
2237   [(set (match_operand:SWI48 0 "register_operand" "+r")
2238         (match_operand:SWI48 1 "register_operand" "+r"))
2239    (set (match_dup 1)
2240         (match_dup 0))]
2241   ""
2242   "xchg{<imodesuffix>}\t%1, %0"
2243   [(set_attr "type" "imov")
2244    (set_attr "mode" "<MODE>")
2245    (set_attr "pent_pair" "np")
2246    (set_attr "athlon_decode" "vector")
2247    (set_attr "amdfam10_decode" "double")
2248    (set_attr "bdver1_decode" "double")])
2250 (define_insn "*swap<mode>_1"
2251   [(set (match_operand:SWI12 0 "register_operand" "+r")
2252         (match_operand:SWI12 1 "register_operand" "+r"))
2253    (set (match_dup 1)
2254         (match_dup 0))]
2255   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2256   "xchg{l}\t%k1, %k0"
2257   [(set_attr "type" "imov")
2258    (set_attr "mode" "SI")
2259    (set_attr "pent_pair" "np")
2260    (set_attr "athlon_decode" "vector")
2261    (set_attr "amdfam10_decode" "double")
2262    (set_attr "bdver1_decode" "double")])
2264 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2265 ;; is disabled for AMDFAM10
2266 (define_insn "*swap<mode>_2"
2267   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2268         (match_operand:SWI12 1 "register_operand" "+<r>"))
2269    (set (match_dup 1)
2270         (match_dup 0))]
2271   "TARGET_PARTIAL_REG_STALL"
2272   "xchg{<imodesuffix>}\t%1, %0"
2273   [(set_attr "type" "imov")
2274    (set_attr "mode" "<MODE>")
2275    (set_attr "pent_pair" "np")
2276    (set_attr "athlon_decode" "vector")])
2278 (define_expand "movstrict<mode>"
2279   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2280         (match_operand:SWI12 1 "general_operand"))]
2281   ""
2283   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2284     FAIL;
2285   if (GET_CODE (operands[0]) == SUBREG
2286       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2287     FAIL;
2288   /* Don't generate memory->memory moves, go through a register */
2289   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2290     operands[1] = force_reg (<MODE>mode, operands[1]);
2293 (define_insn "*movstrict<mode>_1"
2294   [(set (strict_low_part
2295           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2296         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2297   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2298    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2299   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2300   [(set_attr "type" "imov")
2301    (set_attr "mode" "<MODE>")])
2303 (define_insn "*movstrict<mode>_xor"
2304   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2305         (match_operand:SWI12 1 "const0_operand"))
2306    (clobber (reg:CC FLAGS_REG))]
2307   "reload_completed"
2308   "xor{<imodesuffix>}\t%0, %0"
2309   [(set_attr "type" "alu1")
2310    (set_attr "mode" "<MODE>")
2311    (set_attr "length_immediate" "0")])
2313 (define_insn "*mov<mode>_extv_1"
2314   [(set (match_operand:SWI24 0 "register_operand" "=R")
2315         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2316                             (const_int 8)
2317                             (const_int 8)))]
2318   ""
2319   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2320   [(set_attr "type" "imovx")
2321    (set_attr "mode" "SI")])
2323 (define_insn "*movqi_extv_1_rex64"
2324   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2325         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2326                          (const_int 8)
2327                          (const_int 8)))]
2328   "TARGET_64BIT"
2330   switch (get_attr_type (insn))
2331     {
2332     case TYPE_IMOVX:
2333       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2334     default:
2335       return "mov{b}\t{%h1, %0|%0, %h1}";
2336     }
2338   [(set (attr "type")
2339      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2340                         (match_test "TARGET_MOVX"))
2341         (const_string "imovx")
2342         (const_string "imov")))
2343    (set (attr "mode")
2344      (if_then_else (eq_attr "type" "imovx")
2345         (const_string "SI")
2346         (const_string "QI")))])
2348 (define_insn "*movqi_extv_1"
2349   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2350         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2351                          (const_int 8)
2352                          (const_int 8)))]
2353   "!TARGET_64BIT"
2355   switch (get_attr_type (insn))
2356     {
2357     case TYPE_IMOVX:
2358       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2359     default:
2360       return "mov{b}\t{%h1, %0|%0, %h1}";
2361     }
2363   [(set (attr "type")
2364      (if_then_else (and (match_operand:QI 0 "register_operand")
2365                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2366                              (match_test "TARGET_MOVX")))
2367         (const_string "imovx")
2368         (const_string "imov")))
2369    (set (attr "mode")
2370      (if_then_else (eq_attr "type" "imovx")
2371         (const_string "SI")
2372         (const_string "QI")))])
2374 (define_insn "*mov<mode>_extzv_1"
2375   [(set (match_operand:SWI48 0 "register_operand" "=R")
2376         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2377                             (const_int 8)
2378                             (const_int 8)))]
2379   ""
2380   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2381   [(set_attr "type" "imovx")
2382    (set_attr "mode" "SI")])
2384 (define_insn "*movqi_extzv_2_rex64"
2385   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2386         (subreg:QI
2387           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2388                            (const_int 8)
2389                            (const_int 8)) 0))]
2390   "TARGET_64BIT"
2392   switch (get_attr_type (insn))
2393     {
2394     case TYPE_IMOVX:
2395       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2396     default:
2397       return "mov{b}\t{%h1, %0|%0, %h1}";
2398     }
2400   [(set (attr "type")
2401      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2402                         (match_test "TARGET_MOVX"))
2403         (const_string "imovx")
2404         (const_string "imov")))
2405    (set (attr "mode")
2406      (if_then_else (eq_attr "type" "imovx")
2407         (const_string "SI")
2408         (const_string "QI")))])
2410 (define_insn "*movqi_extzv_2"
2411   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2412         (subreg:QI
2413           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2414                            (const_int 8)
2415                            (const_int 8)) 0))]
2416   "!TARGET_64BIT"
2418   switch (get_attr_type (insn))
2419     {
2420     case TYPE_IMOVX:
2421       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2422     default:
2423       return "mov{b}\t{%h1, %0|%0, %h1}";
2424     }
2426   [(set (attr "type")
2427      (if_then_else (and (match_operand:QI 0 "register_operand")
2428                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2429                              (match_test "TARGET_MOVX")))
2430         (const_string "imovx")
2431         (const_string "imov")))
2432    (set (attr "mode")
2433      (if_then_else (eq_attr "type" "imovx")
2434         (const_string "SI")
2435         (const_string "QI")))])
2437 (define_expand "mov<mode>_insv_1"
2438   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2439                             (const_int 8)
2440                             (const_int 8))
2441         (match_operand:SWI48 1 "nonmemory_operand"))])
2443 (define_insn "*mov<mode>_insv_1_rex64"
2444   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2445                              (const_int 8)
2446                              (const_int 8))
2447         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2448   "TARGET_64BIT"
2450   if (CONST_INT_P (operands[1]))
2451     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2452   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2454   [(set_attr "type" "imov")
2455    (set_attr "mode" "QI")])
2457 (define_insn "*movsi_insv_1"
2458   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2459                          (const_int 8)
2460                          (const_int 8))
2461         (match_operand:SI 1 "general_operand" "Qmn"))]
2462   "!TARGET_64BIT"
2464   if (CONST_INT_P (operands[1]))
2465     operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2466   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2468   [(set_attr "type" "imov")
2469    (set_attr "mode" "QI")])
2471 (define_insn "*movqi_insv_2"
2472   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2473                          (const_int 8)
2474                          (const_int 8))
2475         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2476                      (const_int 8)))]
2477   ""
2478   "mov{b}\t{%h1, %h0|%h0, %h1}"
2479   [(set_attr "type" "imov")
2480    (set_attr "mode" "QI")])
2482 ;; Floating point push instructions.
2484 (define_insn "*pushtf"
2485   [(set (match_operand:TF 0 "push_operand" "=<,<")
2486         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2487   "TARGET_64BIT || TARGET_SSE"
2489   /* This insn should be already split before reg-stack.  */
2490   gcc_unreachable ();
2492   [(set_attr "isa" "*,x64")
2493    (set_attr "type" "multi")
2494    (set_attr "unit" "sse,*")
2495    (set_attr "mode" "TF,DI")])
2497 ;; %%% Kill this when call knows how to work this out.
2498 (define_split
2499   [(set (match_operand:TF 0 "push_operand")
2500         (match_operand:TF 1 "sse_reg_operand"))]
2501   "TARGET_SSE && reload_completed"
2502   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2503    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2505 (define_insn "*pushxf"
2506   [(set (match_operand:XF 0 "push_operand" "=<,<")
2507         (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2508   ""
2510   /* This insn should be already split before reg-stack.  */
2511   gcc_unreachable ();
2513   [(set_attr "type" "multi")
2514    (set_attr "unit" "i387,*")
2515    (set (attr "mode")
2516         (cond [(eq_attr "alternative" "1")
2517                  (if_then_else (match_test "TARGET_64BIT")
2518                    (const_string "DI")
2519                    (const_string "SI"))
2520               ]
2521               (const_string "XF")))])
2523 ;; %%% Kill this when call knows how to work this out.
2524 (define_split
2525   [(set (match_operand:XF 0 "push_operand")
2526         (match_operand:XF 1 "fp_register_operand"))]
2527   "reload_completed"
2528   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2529    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2530   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2532 (define_insn "*pushdf"
2533   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2534         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2535   ""
2537   /* This insn should be already split before reg-stack.  */
2538   gcc_unreachable ();
2540   [(set_attr "isa" "*,nox64,x64,sse2")
2541    (set_attr "type" "multi")
2542    (set_attr "unit" "i387,*,*,sse")
2543    (set_attr "mode" "DF,SI,DI,DF")])
2545 ;; %%% Kill this when call knows how to work this out.
2546 (define_split
2547   [(set (match_operand:DF 0 "push_operand")
2548         (match_operand:DF 1 "any_fp_register_operand"))]
2549   "reload_completed"
2550   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2551    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2553 (define_insn "*pushsf_rex64"
2554   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2555         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2556   "TARGET_64BIT"
2558   /* Anything else should be already split before reg-stack.  */
2559   gcc_assert (which_alternative == 1);
2560   return "push{q}\t%q1";
2562   [(set_attr "type" "multi,push,multi")
2563    (set_attr "unit" "i387,*,*")
2564    (set_attr "mode" "SF,DI,SF")])
2566 (define_insn "*pushsf"
2567   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2568         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2569   "!TARGET_64BIT"
2571   /* Anything else should be already split before reg-stack.  */
2572   gcc_assert (which_alternative == 1);
2573   return "push{l}\t%1";
2575   [(set_attr "type" "multi,push,multi")
2576    (set_attr "unit" "i387,*,*")
2577    (set_attr "mode" "SF,SI,SF")])
2579 ;; %%% Kill this when call knows how to work this out.
2580 (define_split
2581   [(set (match_operand:SF 0 "push_operand")
2582         (match_operand:SF 1 "any_fp_register_operand"))]
2583   "reload_completed"
2584   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2585    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2586   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2588 (define_split
2589   [(set (match_operand:SF 0 "push_operand")
2590         (match_operand:SF 1 "memory_operand"))]
2591   "reload_completed
2592    && (operands[2] = find_constant_src (insn))"
2593   [(set (match_dup 0) (match_dup 2))])
2595 (define_split
2596   [(set (match_operand 0 "push_operand")
2597         (match_operand 1 "general_operand"))]
2598   "reload_completed
2599    && (GET_MODE (operands[0]) == TFmode
2600        || GET_MODE (operands[0]) == XFmode
2601        || GET_MODE (operands[0]) == DFmode)
2602    && !ANY_FP_REG_P (operands[1])"
2603   [(const_int 0)]
2604   "ix86_split_long_move (operands); DONE;")
2606 ;; Floating point move instructions.
2608 (define_expand "movtf"
2609   [(set (match_operand:TF 0 "nonimmediate_operand")
2610         (match_operand:TF 1 "nonimmediate_operand"))]
2611   "TARGET_64BIT || TARGET_SSE"
2612   "ix86_expand_move (TFmode, operands); DONE;")
2614 (define_expand "mov<mode>"
2615   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2616         (match_operand:X87MODEF 1 "general_operand"))]
2617   ""
2618   "ix86_expand_move (<MODE>mode, operands); DONE;")
2620 (define_insn "*movtf_internal"
2621   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2622         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2623   "(TARGET_64BIT || TARGET_SSE)
2624    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2625    && (!can_create_pseudo_p ()
2626        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2627        || GET_CODE (operands[1]) != CONST_DOUBLE
2628        || (optimize_function_for_size_p (cfun)
2629            && standard_sse_constant_p (operands[1])
2630            && !memory_operand (operands[0], TFmode))
2631        || (!TARGET_MEMORY_MISMATCH_STALL
2632            && memory_operand (operands[0], TFmode)))"
2634   switch (which_alternative)
2635     {
2636     case 0:
2637       return standard_sse_constant_opcode (insn, operands[1]);
2638     case 1:
2639     case 2:
2640       /* Handle misaligned load/store since we
2641          don't have movmisaligntf pattern. */
2642       if (misaligned_operand (operands[0], TFmode)
2643           || misaligned_operand (operands[1], TFmode))
2644         {
2645           if (get_attr_mode (insn) == MODE_V4SF)
2646             return "%vmovups\t{%1, %0|%0, %1}";
2647           else
2648             return "%vmovdqu\t{%1, %0|%0, %1}";
2649         }
2650       else
2651         {
2652           if (get_attr_mode (insn) == MODE_V4SF)
2653             return "%vmovaps\t{%1, %0|%0, %1}";
2654           else
2655             return "%vmovdqa\t{%1, %0|%0, %1}";
2656         }
2658     case 3:
2659     case 4:
2660         return "#";
2662     default:
2663       gcc_unreachable ();
2664     }
2666   [(set_attr "isa" "*,*,*,x64,x64")
2667    (set_attr "type" "sselog1,ssemov,ssemov,*,*")
2668    (set (attr "prefix")
2669      (if_then_else (eq_attr "type" "sselog1,ssemov")
2670        (const_string "maybe_vex")
2671        (const_string "orig")))
2672    (set (attr "mode")
2673         (cond [(eq_attr "alternative" "3,4")
2674                  (const_string "DI")
2675                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2676                  (const_string "V4SF")
2677                (and (eq_attr "alternative" "2")
2678                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2679                  (const_string "V4SF")
2680                (match_test "TARGET_AVX")
2681                  (const_string "TI")
2682                (ior (not (match_test "TARGET_SSE2"))
2683                     (match_test "optimize_function_for_size_p (cfun)"))
2684                  (const_string "V4SF")
2685                ]
2686                (const_string "TI")))])
2688 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2689 (define_insn "*movxf_internal"
2690   [(set (match_operand:XF 0 "nonimmediate_operand"
2691          "=f,m,f,?Yx*r ,!o   ,!o")
2692         (match_operand:XF 1 "general_operand"
2693          "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2694   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2695    && (!can_create_pseudo_p ()
2696        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2697        || GET_CODE (operands[1]) != CONST_DOUBLE
2698        || (optimize_function_for_size_p (cfun)
2699            && standard_80387_constant_p (operands[1]) > 0
2700            && !memory_operand (operands[0], XFmode))
2701        || (!TARGET_MEMORY_MISMATCH_STALL
2702            && memory_operand (operands[0], XFmode)))"
2704   switch (which_alternative)
2705     {
2706     case 0:
2707     case 1:
2708       return output_387_reg_move (insn, operands);
2710     case 2:
2711       return standard_80387_constant_opcode (operands[1]);
2713     case 3:
2714     case 4:
2715     case 5:
2716       return "#";
2718     default:
2719       gcc_unreachable ();
2720     }
2722   [(set_attr "isa" "*,*,*,*,nox64,x64")
2723    (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2724    (set (attr "mode")
2725         (cond [(eq_attr "alternative" "3,4,5")
2726                  (if_then_else (match_test "TARGET_64BIT")
2727                    (const_string "DI")
2728                    (const_string "SI"))
2729               ]
2730               (const_string "XF")))])
2732 ;; Possible store forwarding (partial memory) stall in alternative 4.
2733 (define_insn "*movdf_internal"
2734   [(set (match_operand:DF 0 "nonimmediate_operand"
2735     "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,?r,?m,?r,?r,x,x,x,m,*x,*x,*x,m ,r ,Yi")
2736         (match_operand:DF 1 "general_operand"
2737     "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,x,m,x,C ,*x,m ,*x,Yi,r"))]
2738   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2739    && (!can_create_pseudo_p ()
2740        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2741        || GET_CODE (operands[1]) != CONST_DOUBLE
2742        || (optimize_function_for_size_p (cfun)
2743            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2744                 && standard_80387_constant_p (operands[1]) > 0)
2745                || (TARGET_SSE2 && TARGET_SSE_MATH
2746                    && standard_sse_constant_p (operands[1])))
2747            && !memory_operand (operands[0], DFmode))
2748        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2749            && memory_operand (operands[0], DFmode)))"
2751   switch (which_alternative)
2752     {
2753     case 0:
2754     case 1:
2755       return output_387_reg_move (insn, operands);
2757     case 2:
2758       return standard_80387_constant_opcode (operands[1]);
2760     case 3:
2761     case 4:
2762       return "#";
2764     case 5:
2765     case 6:
2766       return "mov{q}\t{%1, %0|%0, %1}";
2768     case 7:
2769       return "mov{l}\t{%1, %k0|%k0, %1}";
2771     case 8:
2772       return "movabs{q}\t{%1, %0|%0, %1}";
2774     case 9:
2775     case 13:
2776       return standard_sse_constant_opcode (insn, operands[1]);
2778     case 10:
2779     case 11:
2780     case 12:
2781     case 14:
2782     case 15:
2783     case 16:
2784     case 17:
2785     case 18:
2786       switch (get_attr_mode (insn))
2787         {
2788         case MODE_DF:
2789           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2790             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2791           return "%vmovsd\t{%1, %0|%0, %1}";
2793         case MODE_V1DF:
2794           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2795         case MODE_V2DF:
2796           return "%vmovapd\t{%1, %0|%0, %1}";
2797         case MODE_V2SF:
2798           gcc_assert (!TARGET_AVX);
2799           return "movlps\t{%1, %0|%0, %1}";
2800         case MODE_V4SF:
2801           return "%vmovaps\t{%1, %0|%0, %1}";
2803         case MODE_DI:
2804           /* Handle broken assemblers that require movd instead of movq.  */
2805           if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2806             return "%vmovd\t{%1, %0|%0, %1}";
2807           return "%vmovq\t{%1, %0|%0, %1}";
2809         default:
2810           gcc_unreachable ();
2811         }
2813     default:
2814       gcc_unreachable ();
2815     }
2817   [(set (attr "isa")
2818         (cond [(eq_attr "alternative" "3,4")
2819                  (const_string "nox64")
2820                (eq_attr "alternative" "5,6,7,8,17,18")
2821                  (const_string "x64")
2822                (eq_attr "alternative" "9,10,11,12")
2823                  (const_string "sse2")
2824               ]
2825               (const_string "*")))
2826    (set (attr "type")
2827         (cond [(eq_attr "alternative" "0,1,2")
2828                  (const_string "fmov")
2829                (eq_attr "alternative" "3,4")
2830                  (const_string "multi")
2831                (eq_attr "alternative" "5,6,7,8")
2832                  (const_string "imov")
2833                (eq_attr "alternative" "9,13")
2834                  (const_string "sselog1")
2835               ]
2836               (const_string "ssemov")))
2837    (set (attr "modrm")
2838      (if_then_else (eq_attr "alternative" "8")
2839        (const_string "0")
2840        (const_string "*")))
2841    (set (attr "length_immediate")
2842      (if_then_else (eq_attr "alternative" "8")
2843        (const_string "8")
2844        (const_string "*")))
2845    (set (attr "prefix")
2846      (if_then_else (eq_attr "type" "sselog1,ssemov")
2847        (const_string "maybe_vex")
2848        (const_string "orig")))
2849    (set (attr "prefix_data16")
2850      (if_then_else
2851        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2852             (eq_attr "mode" "V1DF"))
2853        (const_string "1")
2854        (const_string "*")))
2855    (set (attr "mode")
2856         (cond [(eq_attr "alternative" "3,4,7")
2857                  (const_string "SI")
2858                (eq_attr "alternative" "5,6,8,17,18")
2859                  (const_string "DI")
2861                /* xorps is one byte shorter for !TARGET_AVX.  */
2862                (eq_attr "alternative" "9,13")
2863                  (cond [(not (match_test "TARGET_SSE2"))
2864                           (const_string "V4SF")
2865                         (match_test "TARGET_AVX")
2866                           (const_string "V2DF")
2867                         (match_test "optimize_function_for_size_p (cfun)")
2868                           (const_string "V4SF")
2869                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2870                           (const_string "TI")
2871                        ]
2872                        (const_string "V2DF"))
2874                /* For architectures resolving dependencies on
2875                   whole SSE registers use APD move to break dependency
2876                   chains, otherwise use short move to avoid extra work.
2878                   movaps encodes one byte shorter for !TARGET_AVX.  */
2879                (eq_attr "alternative" "10,14")
2880                  (cond [(ior (not (match_test "TARGET_SSE2"))
2881                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2882                           (const_string "V4SF")
2883                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2884                           (const_string "V2DF")
2885                         (match_test "TARGET_AVX")
2886                           (const_string "DF")
2887                         (match_test "optimize_function_for_size_p (cfun)")
2888                           (const_string "V4SF")
2889                        ]
2890                        (const_string "DF"))
2892                /* For architectures resolving dependencies on register
2893                   parts we may avoid extra work to zero out upper part
2894                   of register.  */
2895                (eq_attr "alternative" "11,15")
2896                  (cond [(not (match_test "TARGET_SSE2"))
2897                           (const_string "V2SF")
2898                         (match_test "TARGET_SSE_SPLIT_REGS")
2899                           (const_string "V1DF")
2900                        ]
2901                        (const_string "DF"))
2903                (and (eq_attr "alternative" "12,16")
2904                     (not (match_test "TARGET_SSE2")))
2905                  (const_string "V2SF")
2906               ]
2907               (const_string "DF")))])
2909 (define_insn "*movsf_internal"
2910   [(set (match_operand:SF 0 "nonimmediate_operand"
2911           "=Yf*f,m   ,Yf*f,?r ,?m,x,x,x,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
2912         (match_operand:SF 1 "general_operand"
2913           "Yf*fm,Yf*f,G   ,rmF,rF,C,x,m,x,Yi,r  ,*y ,m  ,*y,*Ym,r"))]
2914   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2915    && (!can_create_pseudo_p ()
2916        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2917        || GET_CODE (operands[1]) != CONST_DOUBLE
2918        || (optimize_function_for_size_p (cfun)
2919            && ((!TARGET_SSE_MATH
2920                 && standard_80387_constant_p (operands[1]) > 0)
2921                || (TARGET_SSE_MATH
2922                    && standard_sse_constant_p (operands[1]))))
2923        || memory_operand (operands[0], SFmode))"
2925   switch (which_alternative)
2926     {
2927     case 0:
2928     case 1:
2929       return output_387_reg_move (insn, operands);
2931     case 2:
2932       return standard_80387_constant_opcode (operands[1]);
2934     case 3:
2935     case 4:
2936       return "mov{l}\t{%1, %0|%0, %1}";
2938     case 5:
2939       return standard_sse_constant_opcode (insn, operands[1]);
2941     case 6:
2942     case 7:
2943     case 8:
2944       switch (get_attr_mode (insn))
2945         {
2946         case MODE_V4SF:
2947           return "%vmovaps\t{%1, %0|%0, %1}";
2948         case MODE_SF:
2949           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2950             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
2951           return "%vmovss\t{%1, %0|%0, %1}";
2952         default:
2953           gcc_unreachable ();
2954         }
2956     case 9:
2957     case 10:
2958       return "%vmovd\t{%1, %0|%0, %1}";
2960     case 11:
2961     case 12:
2962     case 13:
2963     case 14:
2964     case 15:
2965       if (get_attr_mode (insn) == MODE_DI)
2966         return "movq\t{%1, %0|%0, %1}";
2967       return "movd\t{%1, %0|%0, %1}";
2969     default:
2970       gcc_unreachable ();
2971     }
2973   [(set (attr "type")
2974         (cond [(eq_attr "alternative" "0,1,2")
2975                  (const_string "fmov")
2976                (eq_attr "alternative" "3,4")
2977                  (const_string "imov")
2978                (eq_attr "alternative" "5")
2979                  (const_string "sselog1")
2980                (eq_attr "alternative" "11,12,13,14,15")
2981                  (const_string "mmxmov")
2982               ]
2983               (const_string "ssemov")))
2984    (set (attr "prefix")
2985      (if_then_else (eq_attr "type" "sselog1,ssemov")
2986        (const_string "maybe_vex")
2987        (const_string "orig")))
2988    (set (attr "prefix_data16")
2989      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2990        (const_string "1")
2991        (const_string "*")))
2992    (set (attr "mode")
2993         (cond [(eq_attr "alternative" "3,4,9,10,14,15")
2994                  (const_string "SI")
2995                (eq_attr "alternative" "11")
2996                  (const_string "DI")
2997                (eq_attr "alternative" "5")
2998                  (cond [(not (match_test "TARGET_SSE2"))
2999                           (const_string "V4SF")
3000                         (match_test "TARGET_AVX")
3001                           (const_string "V4SF")
3002                         (match_test "optimize_function_for_size_p (cfun)")
3003                           (const_string "V4SF")
3004                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3005                           (const_string "TI")
3006                        ]
3007                        (const_string "V4SF"))
3009                /* For architectures resolving dependencies on
3010                   whole SSE registers use APS move to break dependency
3011                   chains, otherwise use short move to avoid extra work.
3013                   Do the same for architectures resolving dependencies on
3014                   the parts.  While in DF mode it is better to always handle
3015                   just register parts, the SF mode is different due to lack
3016                   of instructions to load just part of the register.  It is
3017                   better to maintain the whole registers in single format
3018                   to avoid problems on using packed logical operations.  */
3019                (and (eq_attr "alternative" "6")
3020                     (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3021                          (match_test "TARGET_SSE_SPLIT_REGS")))
3022                  (const_string "V4SF")
3023               ]
3024               (const_string "SF")))])
3026 (define_split
3027   [(set (match_operand 0 "any_fp_register_operand")
3028         (match_operand 1 "memory_operand"))]
3029   "reload_completed
3030    && (GET_MODE (operands[0]) == TFmode
3031        || GET_MODE (operands[0]) == XFmode
3032        || GET_MODE (operands[0]) == DFmode
3033        || GET_MODE (operands[0]) == SFmode)
3034    && (operands[2] = find_constant_src (insn))"
3035   [(set (match_dup 0) (match_dup 2))]
3037   rtx c = operands[2];
3038   int r = REGNO (operands[0]);
3040   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3041       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3042     FAIL;
3045 (define_split
3046   [(set (match_operand 0 "any_fp_register_operand")
3047         (float_extend (match_operand 1 "memory_operand")))]
3048   "reload_completed
3049    && (GET_MODE (operands[0]) == TFmode
3050        || GET_MODE (operands[0]) == XFmode
3051        || GET_MODE (operands[0]) == DFmode)
3052    && (operands[2] = find_constant_src (insn))"
3053   [(set (match_dup 0) (match_dup 2))]
3055   rtx c = operands[2];
3056   int r = REGNO (operands[0]);
3058   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3059       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3060     FAIL;
3063 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3064 (define_split
3065   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3066         (match_operand:X87MODEF 1 "immediate_operand"))]
3067   "reload_completed
3068    && (standard_80387_constant_p (operands[1]) == 8
3069        || standard_80387_constant_p (operands[1]) == 9)"
3070   [(set (match_dup 0)(match_dup 1))
3071    (set (match_dup 0)
3072         (neg:X87MODEF (match_dup 0)))]
3074   REAL_VALUE_TYPE r;
3076   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3077   if (real_isnegzero (&r))
3078     operands[1] = CONST0_RTX (<MODE>mode);
3079   else
3080     operands[1] = CONST1_RTX (<MODE>mode);
3083 (define_split
3084   [(set (match_operand 0 "nonimmediate_operand")
3085         (match_operand 1 "general_operand"))]
3086   "reload_completed
3087    && (GET_MODE (operands[0]) == TFmode
3088        || GET_MODE (operands[0]) == XFmode
3089        || GET_MODE (operands[0]) == DFmode)
3090    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3091   [(const_int 0)]
3092   "ix86_split_long_move (operands); DONE;")
3094 (define_insn "swapxf"
3095   [(set (match_operand:XF 0 "register_operand" "+f")
3096         (match_operand:XF 1 "register_operand" "+f"))
3097    (set (match_dup 1)
3098         (match_dup 0))]
3099   "TARGET_80387"
3101   if (STACK_TOP_P (operands[0]))
3102     return "fxch\t%1";
3103   else
3104     return "fxch\t%0";
3106   [(set_attr "type" "fxch")
3107    (set_attr "mode" "XF")])
3109 (define_insn "*swap<mode>"
3110   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3111         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3112    (set (match_dup 1)
3113         (match_dup 0))]
3114   "TARGET_80387 || reload_completed"
3116   if (STACK_TOP_P (operands[0]))
3117     return "fxch\t%1";
3118   else
3119     return "fxch\t%0";
3121   [(set_attr "type" "fxch")
3122    (set_attr "mode" "<MODE>")])
3124 ;; Zero extension instructions
3126 (define_expand "zero_extendsidi2"
3127   [(set (match_operand:DI 0 "nonimmediate_operand")
3128         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3130 (define_insn "*zero_extendsidi2_rex64"
3131   [(set (match_operand:DI 0 "nonimmediate_operand"
3132                         "=r  ,o,?*Ym,?*y,?*Yi,?*x")
3133         (zero_extend:DI
3134          (match_operand:SI 1 "x86_64_zext_general_operand"
3135                         "rmWz,0,r   ,m  ,r   ,m")))]
3136   "TARGET_64BIT"
3138   switch (get_attr_type (insn))
3139     {
3140     case TYPE_IMOVX:
3141       if (ix86_use_lea_for_mov (insn, operands))
3142         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3143       else
3144         return "mov{l}\t{%1, %k0|%k0, %1}";
3146     case TYPE_MULTI:
3147       return "#";
3149     case TYPE_MMXMOV:
3150       return "movd\t{%1, %0|%0, %1}";
3152     case TYPE_SSEMOV:
3153       return "%vmovd\t{%1, %0|%0, %1}";
3155     default:
3156       gcc_unreachable ();
3157     }
3159   [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3160    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3161    (set_attr "prefix_0f" "0,*,*,*,*,*")
3162    (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3164 (define_insn "*zero_extendsidi2"
3165   [(set (match_operand:DI 0 "nonimmediate_operand"
3166                         "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3167         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3168                         "0  ,rm,r ,r   ,m  ,r   ,m")))]
3169   "!TARGET_64BIT"
3170   "@
3171    #
3172    #
3173    #
3174    movd\t{%1, %0|%0, %1}
3175    movd\t{%1, %0|%0, %1}
3176    %vmovd\t{%1, %0|%0, %1}
3177    %vmovd\t{%1, %0|%0, %1}"
3178   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3179    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3180    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3181    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3183 (define_split
3184   [(set (match_operand:DI 0 "memory_operand")
3185         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3186   "reload_completed"
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 "register_operand")
3192         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3193   "!TARGET_64BIT && reload_completed
3194    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3195    && true_regnum (operands[0]) == true_regnum (operands[1])"
3196   [(set (match_dup 4) (const_int 0))]
3197   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3199 (define_split
3200   [(set (match_operand:DI 0 "nonimmediate_operand")
3201         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3202   "!TARGET_64BIT && reload_completed
3203    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3204    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3205   [(set (match_dup 3) (match_dup 1))
3206    (set (match_dup 4) (const_int 0))]
3207   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3209 (define_insn "zero_extend<mode>di2"
3210   [(set (match_operand:DI 0 "register_operand" "=r")
3211         (zero_extend:DI
3212          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3213   "TARGET_64BIT"
3214   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3215   [(set_attr "type" "imovx")
3216    (set_attr "mode" "SI")])
3218 (define_expand "zero_extend<mode>si2"
3219   [(set (match_operand:SI 0 "register_operand")
3220         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3221   ""
3223   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3224     {
3225       operands[1] = force_reg (<MODE>mode, operands[1]);
3226       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3227       DONE;
3228     }
3231 (define_insn_and_split "zero_extend<mode>si2_and"
3232   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3233         (zero_extend:SI
3234           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3235    (clobber (reg:CC FLAGS_REG))]
3236   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3237   "#"
3238   "&& reload_completed"
3239   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3240               (clobber (reg:CC FLAGS_REG))])]
3242   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3243     {
3244       ix86_expand_clear (operands[0]);
3246       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3247       emit_insn (gen_movstrict<mode>
3248                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3249       DONE;
3250     }
3252   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3254   [(set_attr "type" "alu1")
3255    (set_attr "mode" "SI")])
3257 (define_insn "*zero_extend<mode>si2"
3258   [(set (match_operand:SI 0 "register_operand" "=r")
3259         (zero_extend:SI
3260           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3261   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3262   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3263   [(set_attr "type" "imovx")
3264    (set_attr "mode" "SI")])
3266 (define_expand "zero_extendqihi2"
3267   [(set (match_operand:HI 0 "register_operand")
3268         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3269   ""
3271   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3272     {
3273       operands[1] = force_reg (QImode, operands[1]);
3274       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3275       DONE;
3276     }
3279 (define_insn_and_split "zero_extendqihi2_and"
3280   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3281         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3282    (clobber (reg:CC FLAGS_REG))]
3283   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3284   "#"
3285   "&& reload_completed"
3286   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3287               (clobber (reg:CC FLAGS_REG))])]
3289   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3290     {
3291       ix86_expand_clear (operands[0]);
3293       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3294       emit_insn (gen_movstrictqi
3295                   (gen_lowpart (QImode, operands[0]), operands[1]));
3296       DONE;
3297     }
3299   operands[0] = gen_lowpart (SImode, operands[0]);
3301   [(set_attr "type" "alu1")
3302    (set_attr "mode" "SI")])
3304 ; zero extend to SImode to avoid partial register stalls
3305 (define_insn "*zero_extendqihi2"
3306   [(set (match_operand:HI 0 "register_operand" "=r")
3307         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3308   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3309   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3310   [(set_attr "type" "imovx")
3311    (set_attr "mode" "SI")])
3313 ;; Sign extension instructions
3315 (define_expand "extendsidi2"
3316   [(set (match_operand:DI 0 "register_operand")
3317         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3318   ""
3320   if (!TARGET_64BIT)
3321     {
3322       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3323       DONE;
3324     }
3327 (define_insn "*extendsidi2_rex64"
3328   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3329         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3330   "TARGET_64BIT"
3331   "@
3332    {cltq|cdqe}
3333    movs{lq|x}\t{%1, %0|%0, %1}"
3334   [(set_attr "type" "imovx")
3335    (set_attr "mode" "DI")
3336    (set_attr "prefix_0f" "0")
3337    (set_attr "modrm" "0,1")])
3339 (define_insn "extendsidi2_1"
3340   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3341         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3342    (clobber (reg:CC FLAGS_REG))
3343    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3344   "!TARGET_64BIT"
3345   "#")
3347 ;; Extend to memory case when source register does die.
3348 (define_split
3349   [(set (match_operand:DI 0 "memory_operand")
3350         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3351    (clobber (reg:CC FLAGS_REG))
3352    (clobber (match_operand:SI 2 "register_operand"))]
3353   "(reload_completed
3354     && dead_or_set_p (insn, operands[1])
3355     && !reg_mentioned_p (operands[1], operands[0]))"
3356   [(set (match_dup 3) (match_dup 1))
3357    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3358               (clobber (reg:CC FLAGS_REG))])
3359    (set (match_dup 4) (match_dup 1))]
3360   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3362 ;; Extend to memory case when source register does not die.
3363 (define_split
3364   [(set (match_operand:DI 0 "memory_operand")
3365         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3366    (clobber (reg:CC FLAGS_REG))
3367    (clobber (match_operand:SI 2 "register_operand"))]
3368   "reload_completed"
3369   [(const_int 0)]
3371   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3373   emit_move_insn (operands[3], operands[1]);
3375   /* Generate a cltd if possible and doing so it profitable.  */
3376   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3377       && true_regnum (operands[1]) == AX_REG
3378       && true_regnum (operands[2]) == DX_REG)
3379     {
3380       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3381     }
3382   else
3383     {
3384       emit_move_insn (operands[2], operands[1]);
3385       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3386     }
3387   emit_move_insn (operands[4], operands[2]);
3388   DONE;
3391 ;; Extend to register case.  Optimize case where source and destination
3392 ;; registers match and cases where we can use cltd.
3393 (define_split
3394   [(set (match_operand:DI 0 "register_operand")
3395         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3396    (clobber (reg:CC FLAGS_REG))
3397    (clobber (match_scratch:SI 2))]
3398   "reload_completed"
3399   [(const_int 0)]
3401   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3403   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3404     emit_move_insn (operands[3], operands[1]);
3406   /* Generate a cltd if possible and doing so it profitable.  */
3407   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3408       && true_regnum (operands[3]) == AX_REG
3409       && true_regnum (operands[4]) == DX_REG)
3410     {
3411       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3412       DONE;
3413     }
3415   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3416     emit_move_insn (operands[4], operands[1]);
3418   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3419   DONE;
3422 (define_insn "extend<mode>di2"
3423   [(set (match_operand:DI 0 "register_operand" "=r")
3424         (sign_extend:DI
3425          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3426   "TARGET_64BIT"
3427   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3428   [(set_attr "type" "imovx")
3429    (set_attr "mode" "DI")])
3431 (define_insn "extendhisi2"
3432   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3433         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3434   ""
3436   switch (get_attr_prefix_0f (insn))
3437     {
3438     case 0:
3439       return "{cwtl|cwde}";
3440     default:
3441       return "movs{wl|x}\t{%1, %0|%0, %1}";
3442     }
3444   [(set_attr "type" "imovx")
3445    (set_attr "mode" "SI")
3446    (set (attr "prefix_0f")
3447      ;; movsx is short decodable while cwtl is vector decoded.
3448      (if_then_else (and (eq_attr "cpu" "!k6")
3449                         (eq_attr "alternative" "0"))
3450         (const_string "0")
3451         (const_string "1")))
3452    (set (attr "modrm")
3453      (if_then_else (eq_attr "prefix_0f" "0")
3454         (const_string "0")
3455         (const_string "1")))])
3457 (define_insn "*extendhisi2_zext"
3458   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3459         (zero_extend:DI
3460          (sign_extend:SI
3461           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3462   "TARGET_64BIT"
3464   switch (get_attr_prefix_0f (insn))
3465     {
3466     case 0:
3467       return "{cwtl|cwde}";
3468     default:
3469       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3470     }
3472   [(set_attr "type" "imovx")
3473    (set_attr "mode" "SI")
3474    (set (attr "prefix_0f")
3475      ;; movsx is short decodable while cwtl is vector decoded.
3476      (if_then_else (and (eq_attr "cpu" "!k6")
3477                         (eq_attr "alternative" "0"))
3478         (const_string "0")
3479         (const_string "1")))
3480    (set (attr "modrm")
3481      (if_then_else (eq_attr "prefix_0f" "0")
3482         (const_string "0")
3483         (const_string "1")))])
3485 (define_insn "extendqisi2"
3486   [(set (match_operand:SI 0 "register_operand" "=r")
3487         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3488   ""
3489   "movs{bl|x}\t{%1, %0|%0, %1}"
3490    [(set_attr "type" "imovx")
3491     (set_attr "mode" "SI")])
3493 (define_insn "*extendqisi2_zext"
3494   [(set (match_operand:DI 0 "register_operand" "=r")
3495         (zero_extend:DI
3496           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3497   "TARGET_64BIT"
3498   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3499    [(set_attr "type" "imovx")
3500     (set_attr "mode" "SI")])
3502 (define_insn "extendqihi2"
3503   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3504         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3505   ""
3507   switch (get_attr_prefix_0f (insn))
3508     {
3509     case 0:
3510       return "{cbtw|cbw}";
3511     default:
3512       return "movs{bw|x}\t{%1, %0|%0, %1}";
3513     }
3515   [(set_attr "type" "imovx")
3516    (set_attr "mode" "HI")
3517    (set (attr "prefix_0f")
3518      ;; movsx is short decodable while cwtl is vector decoded.
3519      (if_then_else (and (eq_attr "cpu" "!k6")
3520                         (eq_attr "alternative" "0"))
3521         (const_string "0")
3522         (const_string "1")))
3523    (set (attr "modrm")
3524      (if_then_else (eq_attr "prefix_0f" "0")
3525         (const_string "0")
3526         (const_string "1")))])
3528 ;; Conversions between float and double.
3530 ;; These are all no-ops in the model used for the 80387.
3531 ;; So just emit moves.
3533 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3534 (define_split
3535   [(set (match_operand:DF 0 "push_operand")
3536         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3537   "reload_completed"
3538   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3539    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3541 (define_split
3542   [(set (match_operand:XF 0 "push_operand")
3543         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3544   "reload_completed"
3545   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3546    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3547   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3549 (define_expand "extendsfdf2"
3550   [(set (match_operand:DF 0 "nonimmediate_operand")
3551         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3552   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3554   /* ??? Needed for compress_float_constant since all fp constants
3555      are TARGET_LEGITIMATE_CONSTANT_P.  */
3556   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3557     {
3558       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3559           && standard_80387_constant_p (operands[1]) > 0)
3560         {
3561           operands[1] = simplify_const_unary_operation
3562             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3563           emit_move_insn_1 (operands[0], operands[1]);
3564           DONE;
3565         }
3566       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3567     }
3570 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3571    cvtss2sd:
3572       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3573       cvtps2pd xmm2,xmm1
3574    We do the conversion post reload to avoid producing of 128bit spills
3575    that might lead to ICE on 32bit target.  The sequence unlikely combine
3576    anyway.  */
3577 (define_split
3578   [(set (match_operand:DF 0 "register_operand")
3579         (float_extend:DF
3580           (match_operand:SF 1 "nonimmediate_operand")))]
3581   "TARGET_USE_VECTOR_FP_CONVERTS
3582    && optimize_insn_for_speed_p ()
3583    && reload_completed && SSE_REG_P (operands[0])"
3584    [(set (match_dup 2)
3585          (float_extend:V2DF
3586            (vec_select:V2SF
3587              (match_dup 3)
3588              (parallel [(const_int 0) (const_int 1)]))))]
3590   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3591   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3592   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3593      Try to avoid move when unpacking can be done in source.  */
3594   if (REG_P (operands[1]))
3595     {
3596       /* If it is unsafe to overwrite upper half of source, we need
3597          to move to destination and unpack there.  */
3598       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3599            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3600           && true_regnum (operands[0]) != true_regnum (operands[1]))
3601         {
3602           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3603           emit_move_insn (tmp, operands[1]);
3604         }
3605       else
3606         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3607       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3608                                              operands[3]));
3609     }
3610   else
3611     emit_insn (gen_vec_setv4sf_0 (operands[3],
3612                                   CONST0_RTX (V4SFmode), operands[1]));
3615 (define_insn "*extendsfdf2_mixed"
3616   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3617         (float_extend:DF
3618           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3619   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3621   switch (which_alternative)
3622     {
3623     case 0:
3624     case 1:
3625       return output_387_reg_move (insn, operands);
3627     case 2:
3628       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3630     default:
3631       gcc_unreachable ();
3632     }
3634   [(set_attr "type" "fmov,fmov,ssecvt")
3635    (set_attr "prefix" "orig,orig,maybe_vex")
3636    (set_attr "mode" "SF,XF,DF")])
3638 (define_insn "*extendsfdf2_sse"
3639   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3640         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3641   "TARGET_SSE2 && TARGET_SSE_MATH"
3642   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3643   [(set_attr "type" "ssecvt")
3644    (set_attr "prefix" "maybe_vex")
3645    (set_attr "mode" "DF")])
3647 (define_insn "*extendsfdf2_i387"
3648   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3649         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3650   "TARGET_80387"
3651   "* return output_387_reg_move (insn, operands);"
3652   [(set_attr "type" "fmov")
3653    (set_attr "mode" "SF,XF")])
3655 (define_expand "extend<mode>xf2"
3656   [(set (match_operand:XF 0 "nonimmediate_operand")
3657         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3658   "TARGET_80387"
3660   /* ??? Needed for compress_float_constant since all fp constants
3661      are TARGET_LEGITIMATE_CONSTANT_P.  */
3662   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3663     {
3664       if (standard_80387_constant_p (operands[1]) > 0)
3665         {
3666           operands[1] = simplify_const_unary_operation
3667             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3668           emit_move_insn_1 (operands[0], operands[1]);
3669           DONE;
3670         }
3671       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3672     }
3675 (define_insn "*extend<mode>xf2_i387"
3676   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3677         (float_extend:XF
3678           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3679   "TARGET_80387"
3680   "* return output_387_reg_move (insn, operands);"
3681   [(set_attr "type" "fmov")
3682    (set_attr "mode" "<MODE>,XF")])
3684 ;; %%% This seems bad bad news.
3685 ;; This cannot output into an f-reg because there is no way to be sure
3686 ;; of truncating in that case.  Otherwise this is just like a simple move
3687 ;; insn.  So we pretend we can output to a reg in order to get better
3688 ;; register preferencing, but we really use a stack slot.
3690 ;; Conversion from DFmode to SFmode.
3692 (define_expand "truncdfsf2"
3693   [(set (match_operand:SF 0 "nonimmediate_operand")
3694         (float_truncate:SF
3695           (match_operand:DF 1 "nonimmediate_operand")))]
3696   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3698   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3699     ;
3700   else if (flag_unsafe_math_optimizations)
3701     ;
3702   else
3703     {
3704       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3705       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3706       DONE;
3707     }
3710 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3711    cvtsd2ss:
3712       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3713       cvtpd2ps xmm2,xmm1
3714    We do the conversion post reload to avoid producing of 128bit spills
3715    that might lead to ICE on 32bit target.  The sequence unlikely combine
3716    anyway.  */
3717 (define_split
3718   [(set (match_operand:SF 0 "register_operand")
3719         (float_truncate:SF
3720           (match_operand:DF 1 "nonimmediate_operand")))]
3721   "TARGET_USE_VECTOR_FP_CONVERTS
3722    && optimize_insn_for_speed_p ()
3723    && reload_completed && SSE_REG_P (operands[0])"
3724    [(set (match_dup 2)
3725          (vec_concat:V4SF
3726            (float_truncate:V2SF
3727              (match_dup 4))
3728            (match_dup 3)))]
3730   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3731   operands[3] = CONST0_RTX (V2SFmode);
3732   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3733   /* Use movsd for loading from memory, unpcklpd for registers.
3734      Try to avoid move when unpacking can be done in source, or SSE3
3735      movddup is available.  */
3736   if (REG_P (operands[1]))
3737     {
3738       if (!TARGET_SSE3
3739           && true_regnum (operands[0]) != true_regnum (operands[1])
3740           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3741               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3742         {
3743           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3744           emit_move_insn (tmp, operands[1]);
3745           operands[1] = tmp;
3746         }
3747       else if (!TARGET_SSE3)
3748         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3749       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3750     }
3751   else
3752     emit_insn (gen_sse2_loadlpd (operands[4],
3753                                  CONST0_RTX (V2DFmode), operands[1]));
3756 (define_expand "truncdfsf2_with_temp"
3757   [(parallel [(set (match_operand:SF 0)
3758                    (float_truncate:SF (match_operand:DF 1)))
3759               (clobber (match_operand:SF 2))])])
3761 (define_insn "*truncdfsf_fast_mixed"
3762   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
3763         (float_truncate:SF
3764           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
3765   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3767   switch (which_alternative)
3768     {
3769     case 0:
3770       return output_387_reg_move (insn, operands);
3771     case 1:
3772       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3773     default:
3774       gcc_unreachable ();
3775     }
3777   [(set_attr "type" "fmov,ssecvt")
3778    (set_attr "prefix" "orig,maybe_vex")
3779    (set_attr "mode" "SF")])
3781 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3782 ;; because nothing we do here is unsafe.
3783 (define_insn "*truncdfsf_fast_sse"
3784   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3785         (float_truncate:SF
3786           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3787   "TARGET_SSE2 && TARGET_SSE_MATH"
3788   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
3789   [(set_attr "type" "ssecvt")
3790    (set_attr "prefix" "maybe_vex")
3791    (set_attr "mode" "SF")])
3793 (define_insn "*truncdfsf_fast_i387"
3794   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3795         (float_truncate:SF
3796           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3797   "TARGET_80387 && flag_unsafe_math_optimizations"
3798   "* return output_387_reg_move (insn, operands);"
3799   [(set_attr "type" "fmov")
3800    (set_attr "mode" "SF")])
3802 (define_insn "*truncdfsf_mixed"
3803   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
3804         (float_truncate:SF
3805           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
3806    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
3807   "TARGET_MIX_SSE_I387"
3809   switch (which_alternative)
3810     {
3811     case 0:
3812       return output_387_reg_move (insn, operands);
3813     case 1:
3814       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3816     default:
3817       return "#";
3818     }
3820   [(set_attr "isa" "*,sse2,*,*,*")
3821    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
3822    (set_attr "unit" "*,*,i387,i387,i387")
3823    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
3824    (set_attr "mode" "SF")])
3826 (define_insn "*truncdfsf_i387"
3827   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
3828         (float_truncate:SF
3829           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
3830    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
3831   "TARGET_80387"
3833   switch (which_alternative)
3834     {
3835     case 0:
3836       return output_387_reg_move (insn, operands);
3838     default:
3839       return "#";
3840     }
3842   [(set_attr "type" "fmov,multi,multi,multi")
3843    (set_attr "unit" "*,i387,i387,i387")
3844    (set_attr "mode" "SF")])
3846 (define_insn "*truncdfsf2_i387_1"
3847   [(set (match_operand:SF 0 "memory_operand" "=m")
3848         (float_truncate:SF
3849           (match_operand:DF 1 "register_operand" "f")))]
3850   "TARGET_80387
3851    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3852    && !TARGET_MIX_SSE_I387"
3853   "* return output_387_reg_move (insn, operands);"
3854   [(set_attr "type" "fmov")
3855    (set_attr "mode" "SF")])
3857 (define_split
3858   [(set (match_operand:SF 0 "register_operand")
3859         (float_truncate:SF
3860          (match_operand:DF 1 "fp_register_operand")))
3861    (clobber (match_operand 2))]
3862   "reload_completed"
3863   [(set (match_dup 2) (match_dup 1))
3864    (set (match_dup 0) (match_dup 2))]
3865   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
3867 ;; Conversion from XFmode to {SF,DF}mode
3869 (define_expand "truncxf<mode>2"
3870   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
3871                    (float_truncate:MODEF
3872                      (match_operand:XF 1 "register_operand")))
3873               (clobber (match_dup 2))])]
3874   "TARGET_80387"
3876   if (flag_unsafe_math_optimizations)
3877     {
3878       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3879       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3880       if (reg != operands[0])
3881         emit_move_insn (operands[0], reg);
3882       DONE;
3883     }
3884   else
3885     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3888 (define_insn "*truncxfsf2_mixed"
3889   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3890         (float_truncate:SF
3891           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
3892    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
3893   "TARGET_80387"
3895   gcc_assert (!which_alternative);
3896   return output_387_reg_move (insn, operands);
3898   [(set_attr "type" "fmov,multi,multi,multi")
3899    (set_attr "unit" "*,i387,i387,i387")
3900    (set_attr "mode" "SF")])
3902 (define_insn "*truncxfdf2_mixed"
3903   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3904         (float_truncate:DF
3905           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
3906    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
3907   "TARGET_80387"
3909   gcc_assert (!which_alternative);
3910   return output_387_reg_move (insn, operands);
3912   [(set_attr "isa" "*,*,sse2,*")
3913    (set_attr "type" "fmov,multi,multi,multi")
3914    (set_attr "unit" "*,i387,i387,i387")
3915    (set_attr "mode" "DF")])
3917 (define_insn "truncxf<mode>2_i387_noop"
3918   [(set (match_operand:MODEF 0 "register_operand" "=f")
3919         (float_truncate:MODEF
3920           (match_operand:XF 1 "register_operand" "f")))]
3921   "TARGET_80387 && flag_unsafe_math_optimizations"
3922   "* return output_387_reg_move (insn, operands);"
3923   [(set_attr "type" "fmov")
3924    (set_attr "mode" "<MODE>")])
3926 (define_insn "*truncxf<mode>2_i387"
3927   [(set (match_operand:MODEF 0 "memory_operand" "=m")
3928         (float_truncate:MODEF
3929           (match_operand:XF 1 "register_operand" "f")))]
3930   "TARGET_80387"
3931   "* return output_387_reg_move (insn, operands);"
3932   [(set_attr "type" "fmov")
3933    (set_attr "mode" "<MODE>")])
3935 (define_split
3936   [(set (match_operand:MODEF 0 "register_operand")
3937         (float_truncate:MODEF
3938           (match_operand:XF 1 "register_operand")))
3939    (clobber (match_operand:MODEF 2 "memory_operand"))]
3940   "TARGET_80387 && reload_completed"
3941   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
3942    (set (match_dup 0) (match_dup 2))])
3944 (define_split
3945   [(set (match_operand:MODEF 0 "memory_operand")
3946         (float_truncate:MODEF
3947           (match_operand:XF 1 "register_operand")))
3948    (clobber (match_operand:MODEF 2 "memory_operand"))]
3949   "TARGET_80387"
3950   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
3952 ;; Signed conversion to DImode.
3954 (define_expand "fix_truncxfdi2"
3955   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3956                    (fix:DI (match_operand:XF 1 "register_operand")))
3957               (clobber (reg:CC FLAGS_REG))])]
3958   "TARGET_80387"
3960   if (TARGET_FISTTP)
3961    {
3962      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
3963      DONE;
3964    }
3967 (define_expand "fix_trunc<mode>di2"
3968   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3969                    (fix:DI (match_operand:MODEF 1 "register_operand")))
3970               (clobber (reg:CC FLAGS_REG))])]
3971   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
3973   if (TARGET_FISTTP
3974       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
3975    {
3976      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
3977      DONE;
3978    }
3979   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
3980    {
3981      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3982      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
3983      if (out != operands[0])
3984         emit_move_insn (operands[0], out);
3985      DONE;
3986    }
3989 ;; Signed conversion to SImode.
3991 (define_expand "fix_truncxfsi2"
3992   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
3993                    (fix:SI (match_operand:XF 1 "register_operand")))
3994               (clobber (reg:CC FLAGS_REG))])]
3995   "TARGET_80387"
3997   if (TARGET_FISTTP)
3998    {
3999      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4000      DONE;
4001    }
4004 (define_expand "fix_trunc<mode>si2"
4005   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4006                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4007               (clobber (reg:CC FLAGS_REG))])]
4008   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4010   if (TARGET_FISTTP
4011       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4012    {
4013      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4014      DONE;
4015    }
4016   if (SSE_FLOAT_MODE_P (<MODE>mode))
4017    {
4018      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4019      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4020      if (out != operands[0])
4021         emit_move_insn (operands[0], out);
4022      DONE;
4023    }
4026 ;; Signed conversion to HImode.
4028 (define_expand "fix_trunc<mode>hi2"
4029   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4030                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4031               (clobber (reg:CC FLAGS_REG))])]
4032   "TARGET_80387
4033    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4035   if (TARGET_FISTTP)
4036    {
4037      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4038      DONE;
4039    }
4042 ;; Unsigned conversion to SImode.
4044 (define_expand "fixuns_trunc<mode>si2"
4045   [(parallel
4046     [(set (match_operand:SI 0 "register_operand")
4047           (unsigned_fix:SI
4048             (match_operand:MODEF 1 "nonimmediate_operand")))
4049      (use (match_dup 2))
4050      (clobber (match_scratch:<ssevecmode> 3))
4051      (clobber (match_scratch:<ssevecmode> 4))])]
4052   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4054   enum machine_mode mode = <MODE>mode;
4055   enum machine_mode vecmode = <ssevecmode>mode;
4056   REAL_VALUE_TYPE TWO31r;
4057   rtx two31;
4059   if (optimize_insn_for_size_p ())
4060     FAIL;
4062   real_ldexp (&TWO31r, &dconst1, 31);
4063   two31 = const_double_from_real_value (TWO31r, mode);
4064   two31 = ix86_build_const_vector (vecmode, true, two31);
4065   operands[2] = force_reg (vecmode, two31);
4068 (define_insn_and_split "*fixuns_trunc<mode>_1"
4069   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4070         (unsigned_fix:SI
4071           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4072    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4073    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4074    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4075   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4076    && optimize_function_for_speed_p (cfun)"
4077   "#"
4078   "&& reload_completed"
4079   [(const_int 0)]
4081   ix86_split_convert_uns_si_sse (operands);
4082   DONE;
4085 ;; Unsigned conversion to HImode.
4086 ;; Without these patterns, we'll try the unsigned SI conversion which
4087 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4089 (define_expand "fixuns_trunc<mode>hi2"
4090   [(set (match_dup 2)
4091         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4092    (set (match_operand:HI 0 "nonimmediate_operand")
4093         (subreg:HI (match_dup 2) 0))]
4094   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4095   "operands[2] = gen_reg_rtx (SImode);")
4097 ;; When SSE is available, it is always faster to use it!
4098 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4099   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4100         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4101   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4102    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4103   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4104   [(set_attr "type" "sseicvt")
4105    (set_attr "prefix" "maybe_vex")
4106    (set (attr "prefix_rex")
4107         (if_then_else
4108           (match_test "<SWI48:MODE>mode == DImode")
4109           (const_string "1")
4110           (const_string "*")))
4111    (set_attr "mode" "<MODEF:MODE>")
4112    (set_attr "athlon_decode" "double,vector")
4113    (set_attr "amdfam10_decode" "double,double")
4114    (set_attr "bdver1_decode" "double,double")])
4116 ;; Avoid vector decoded forms of the instruction.
4117 (define_peephole2
4118   [(match_scratch:MODEF 2 "x")
4119    (set (match_operand:SWI48 0 "register_operand")
4120         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4121   "TARGET_AVOID_VECTOR_DECODE
4122    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4123    && optimize_insn_for_speed_p ()"
4124   [(set (match_dup 2) (match_dup 1))
4125    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4127 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4128   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4129         (fix:SWI248x (match_operand 1 "register_operand")))]
4130   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4131    && TARGET_FISTTP
4132    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4133          && (TARGET_64BIT || <MODE>mode != DImode))
4134         && TARGET_SSE_MATH)
4135    && can_create_pseudo_p ()"
4136   "#"
4137   "&& 1"
4138   [(const_int 0)]
4140   if (memory_operand (operands[0], VOIDmode))
4141     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4142   else
4143     {
4144       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4145       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4146                                                             operands[1],
4147                                                             operands[2]));
4148     }
4149   DONE;
4151   [(set_attr "type" "fisttp")
4152    (set_attr "mode" "<MODE>")])
4154 (define_insn "fix_trunc<mode>_i387_fisttp"
4155   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4156         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4157    (clobber (match_scratch:XF 2 "=&1f"))]
4158   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4159    && TARGET_FISTTP
4160    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4161          && (TARGET_64BIT || <MODE>mode != DImode))
4162         && TARGET_SSE_MATH)"
4163   "* return output_fix_trunc (insn, operands, true);"
4164   [(set_attr "type" "fisttp")
4165    (set_attr "mode" "<MODE>")])
4167 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4168   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4169         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4170    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4171    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4172   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4173    && TARGET_FISTTP
4174    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4175         && (TARGET_64BIT || <MODE>mode != DImode))
4176         && TARGET_SSE_MATH)"
4177   "#"
4178   [(set_attr "type" "fisttp")
4179    (set_attr "mode" "<MODE>")])
4181 (define_split
4182   [(set (match_operand:SWI248x 0 "register_operand")
4183         (fix:SWI248x (match_operand 1 "register_operand")))
4184    (clobber (match_operand:SWI248x 2 "memory_operand"))
4185    (clobber (match_scratch 3))]
4186   "reload_completed"
4187   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4188               (clobber (match_dup 3))])
4189    (set (match_dup 0) (match_dup 2))])
4191 (define_split
4192   [(set (match_operand:SWI248x 0 "memory_operand")
4193         (fix:SWI248x (match_operand 1 "register_operand")))
4194    (clobber (match_operand:SWI248x 2 "memory_operand"))
4195    (clobber (match_scratch 3))]
4196   "reload_completed"
4197   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4198               (clobber (match_dup 3))])])
4200 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4201 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4202 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4203 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4204 ;; function in i386.c.
4205 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4206   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4207         (fix:SWI248x (match_operand 1 "register_operand")))
4208    (clobber (reg:CC FLAGS_REG))]
4209   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4210    && !TARGET_FISTTP
4211    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4212          && (TARGET_64BIT || <MODE>mode != DImode))
4213    && can_create_pseudo_p ()"
4214   "#"
4215   "&& 1"
4216   [(const_int 0)]
4218   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4220   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4221   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4222   if (memory_operand (operands[0], VOIDmode))
4223     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4224                                          operands[2], operands[3]));
4225   else
4226     {
4227       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4228       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4229                                                      operands[2], operands[3],
4230                                                      operands[4]));
4231     }
4232   DONE;
4234   [(set_attr "type" "fistp")
4235    (set_attr "i387_cw" "trunc")
4236    (set_attr "mode" "<MODE>")])
4238 (define_insn "fix_truncdi_i387"
4239   [(set (match_operand:DI 0 "memory_operand" "=m")
4240         (fix:DI (match_operand 1 "register_operand" "f")))
4241    (use (match_operand:HI 2 "memory_operand" "m"))
4242    (use (match_operand:HI 3 "memory_operand" "m"))
4243    (clobber (match_scratch:XF 4 "=&1f"))]
4244   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4245    && !TARGET_FISTTP
4246    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4247   "* return output_fix_trunc (insn, operands, false);"
4248   [(set_attr "type" "fistp")
4249    (set_attr "i387_cw" "trunc")
4250    (set_attr "mode" "DI")])
4252 (define_insn "fix_truncdi_i387_with_temp"
4253   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4254         (fix:DI (match_operand 1 "register_operand" "f,f")))
4255    (use (match_operand:HI 2 "memory_operand" "m,m"))
4256    (use (match_operand:HI 3 "memory_operand" "m,m"))
4257    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4258    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4259   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4260    && !TARGET_FISTTP
4261    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4262   "#"
4263   [(set_attr "type" "fistp")
4264    (set_attr "i387_cw" "trunc")
4265    (set_attr "mode" "DI")])
4267 (define_split
4268   [(set (match_operand:DI 0 "register_operand")
4269         (fix:DI (match_operand 1 "register_operand")))
4270    (use (match_operand:HI 2 "memory_operand"))
4271    (use (match_operand:HI 3 "memory_operand"))
4272    (clobber (match_operand:DI 4 "memory_operand"))
4273    (clobber (match_scratch 5))]
4274   "reload_completed"
4275   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4276               (use (match_dup 2))
4277               (use (match_dup 3))
4278               (clobber (match_dup 5))])
4279    (set (match_dup 0) (match_dup 4))])
4281 (define_split
4282   [(set (match_operand:DI 0 "memory_operand")
4283         (fix:DI (match_operand 1 "register_operand")))
4284    (use (match_operand:HI 2 "memory_operand"))
4285    (use (match_operand:HI 3 "memory_operand"))
4286    (clobber (match_operand:DI 4 "memory_operand"))
4287    (clobber (match_scratch 5))]
4288   "reload_completed"
4289   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4290               (use (match_dup 2))
4291               (use (match_dup 3))
4292               (clobber (match_dup 5))])])
4294 (define_insn "fix_trunc<mode>_i387"
4295   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4296         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4297    (use (match_operand:HI 2 "memory_operand" "m"))
4298    (use (match_operand:HI 3 "memory_operand" "m"))]
4299   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4300    && !TARGET_FISTTP
4301    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4302   "* return output_fix_trunc (insn, operands, false);"
4303   [(set_attr "type" "fistp")
4304    (set_attr "i387_cw" "trunc")
4305    (set_attr "mode" "<MODE>")])
4307 (define_insn "fix_trunc<mode>_i387_with_temp"
4308   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4309         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4310    (use (match_operand:HI 2 "memory_operand" "m,m"))
4311    (use (match_operand:HI 3 "memory_operand" "m,m"))
4312    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4313   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4314    && !TARGET_FISTTP
4315    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4316   "#"
4317   [(set_attr "type" "fistp")
4318    (set_attr "i387_cw" "trunc")
4319    (set_attr "mode" "<MODE>")])
4321 (define_split
4322   [(set (match_operand:SWI24 0 "register_operand")
4323         (fix:SWI24 (match_operand 1 "register_operand")))
4324    (use (match_operand:HI 2 "memory_operand"))
4325    (use (match_operand:HI 3 "memory_operand"))
4326    (clobber (match_operand:SWI24 4 "memory_operand"))]
4327   "reload_completed"
4328   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4329               (use (match_dup 2))
4330               (use (match_dup 3))])
4331    (set (match_dup 0) (match_dup 4))])
4333 (define_split
4334   [(set (match_operand:SWI24 0 "memory_operand")
4335         (fix:SWI24 (match_operand 1 "register_operand")))
4336    (use (match_operand:HI 2 "memory_operand"))
4337    (use (match_operand:HI 3 "memory_operand"))
4338    (clobber (match_operand:SWI24 4 "memory_operand"))]
4339   "reload_completed"
4340   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4341               (use (match_dup 2))
4342               (use (match_dup 3))])])
4344 (define_insn "x86_fnstcw_1"
4345   [(set (match_operand:HI 0 "memory_operand" "=m")
4346         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4347   "TARGET_80387"
4348   "fnstcw\t%0"
4349   [(set (attr "length")
4350         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4351    (set_attr "mode" "HI")
4352    (set_attr "unit" "i387")
4353    (set_attr "bdver1_decode" "vector")])
4355 (define_insn "x86_fldcw_1"
4356   [(set (reg:HI FPCR_REG)
4357         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4358   "TARGET_80387"
4359   "fldcw\t%0"
4360   [(set (attr "length")
4361         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4362    (set_attr "mode" "HI")
4363    (set_attr "unit" "i387")
4364    (set_attr "athlon_decode" "vector")
4365    (set_attr "amdfam10_decode" "vector")
4366    (set_attr "bdver1_decode" "vector")])
4368 ;; Conversion between fixed point and floating point.
4370 ;; Even though we only accept memory inputs, the backend _really_
4371 ;; wants to be able to do this between registers.
4373 (define_expand "floathi<mode>2"
4374   [(set (match_operand:X87MODEF 0 "register_operand")
4375         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4376   "TARGET_80387
4377    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4378        || TARGET_MIX_SSE_I387)")
4380 ;; Pre-reload splitter to add memory clobber to the pattern.
4381 (define_insn_and_split "*floathi<mode>2_1"
4382   [(set (match_operand:X87MODEF 0 "register_operand")
4383         (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4384   "TARGET_80387
4385    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4386        || TARGET_MIX_SSE_I387)
4387    && can_create_pseudo_p ()"
4388   "#"
4389   "&& 1"
4390   [(parallel [(set (match_dup 0)
4391               (float:X87MODEF (match_dup 1)))
4392    (clobber (match_dup 2))])]
4393   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4395 (define_insn "*floathi<mode>2_i387_with_temp"
4396   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4397         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4398   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4399   "TARGET_80387
4400    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4401        || TARGET_MIX_SSE_I387)"
4402   "#"
4403   [(set_attr "type" "fmov,multi")
4404    (set_attr "mode" "<MODE>")
4405    (set_attr "unit" "*,i387")
4406    (set_attr "fp_int_src" "true")])
4408 (define_insn "*floathi<mode>2_i387"
4409   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4410         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4411   "TARGET_80387
4412    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4413        || TARGET_MIX_SSE_I387)"
4414   "fild%Z1\t%1"
4415   [(set_attr "type" "fmov")
4416    (set_attr "mode" "<MODE>")
4417    (set_attr "fp_int_src" "true")])
4419 (define_split
4420   [(set (match_operand:X87MODEF 0 "register_operand")
4421         (float:X87MODEF (match_operand:HI 1 "register_operand")))
4422    (clobber (match_operand:HI 2 "memory_operand"))]
4423   "TARGET_80387
4424    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4425        || TARGET_MIX_SSE_I387)
4426    && reload_completed"
4427   [(set (match_dup 2) (match_dup 1))
4428    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4430 (define_split
4431   [(set (match_operand:X87MODEF 0 "register_operand")
4432         (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4433    (clobber (match_operand:HI 2 "memory_operand"))]
4434    "TARGET_80387
4435     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4436         || TARGET_MIX_SSE_I387)
4437     && reload_completed"
4438   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4440 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4441   [(set (match_operand:X87MODEF 0 "register_operand")
4442         (float:X87MODEF
4443           (match_operand:SWI48x 1 "nonimmediate_operand")))]
4444   "TARGET_80387
4445    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4446        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4448   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4449         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4450       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4451     {
4452       rtx reg = gen_reg_rtx (XFmode);
4453       rtx (*insn)(rtx, rtx);
4455       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4457       if (<X87MODEF:MODE>mode == SFmode)
4458         insn = gen_truncxfsf2;
4459       else if (<X87MODEF:MODE>mode == DFmode)
4460         insn = gen_truncxfdf2;
4461       else
4462         gcc_unreachable ();
4464       emit_insn (insn (operands[0], reg));
4465       DONE;
4466     }
4469 ;; Pre-reload splitter to add memory clobber to the pattern.
4470 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4471   [(set (match_operand:X87MODEF 0 "register_operand")
4472         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4473   "((TARGET_80387
4474      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4475      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4476            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4477          || TARGET_MIX_SSE_I387))
4478     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4479         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4480         && ((<SWI48x:MODE>mode == SImode
4481              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4482              && optimize_function_for_speed_p (cfun)
4483              && flag_trapping_math)
4484             || !(TARGET_INTER_UNIT_CONVERSIONS
4485                  || optimize_function_for_size_p (cfun)))))
4486    && can_create_pseudo_p ()"
4487   "#"
4488   "&& 1"
4489   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4490               (clobber (match_dup 2))])]
4492   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4494   /* Avoid store forwarding (partial memory) stall penalty
4495      by passing DImode value through XMM registers.  */
4496   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4497       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4498       && optimize_function_for_speed_p (cfun))
4499     {
4500       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4501                                                             operands[1],
4502                                                             operands[2]));
4503       DONE;
4504     }
4507 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4508   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4509         (float:MODEF
4510           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4511    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4512   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4513    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4514   "#"
4515   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4516    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4517    (set_attr "unit" "*,i387,*,*,*")
4518    (set_attr "athlon_decode" "*,*,double,direct,double")
4519    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4520    (set_attr "bdver1_decode" "*,*,double,direct,double")
4521    (set_attr "fp_int_src" "true")])
4523 (define_insn "*floatsi<mode>2_vector_mixed"
4524   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4525         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4526   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4527    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4528   "@
4529    fild%Z1\t%1
4530    #"
4531   [(set_attr "type" "fmov,sseicvt")
4532    (set_attr "mode" "<MODE>,<ssevecmode>")
4533    (set_attr "unit" "i387,*")
4534    (set_attr "athlon_decode" "*,direct")
4535    (set_attr "amdfam10_decode" "*,double")
4536    (set_attr "bdver1_decode" "*,direct")
4537    (set_attr "fp_int_src" "true")])
4539 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4540   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4541         (float:MODEF
4542           (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4543    (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4544   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4545   "#"
4546   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4547    (set_attr "mode" "<MODEF:MODE>")
4548    (set_attr "unit" "*,i387,*,*")
4549    (set_attr "athlon_decode" "*,*,double,direct")
4550    (set_attr "amdfam10_decode" "*,*,vector,double")
4551    (set_attr "bdver1_decode" "*,*,double,direct")
4552    (set_attr "fp_int_src" "true")])
4554 (define_split
4555   [(set (match_operand:MODEF 0 "register_operand")
4556         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4557    (clobber (match_operand:SWI48 2 "memory_operand"))]
4558   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4559    && TARGET_INTER_UNIT_CONVERSIONS
4560    && reload_completed
4561    && (SSE_REG_P (operands[0])
4562        || (GET_CODE (operands[0]) == SUBREG
4563            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4564   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4566 (define_split
4567   [(set (match_operand:MODEF 0 "register_operand")
4568         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4569    (clobber (match_operand:SWI48 2 "memory_operand"))]
4570   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4571    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4572    && reload_completed
4573    && (SSE_REG_P (operands[0])
4574        || (GET_CODE (operands[0]) == SUBREG
4575            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4576   [(set (match_dup 2) (match_dup 1))
4577    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4579 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4580   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4581         (float:MODEF
4582           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4583   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4584    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4585   "@
4586    fild%Z1\t%1
4587    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4588    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4589   [(set_attr "type" "fmov,sseicvt,sseicvt")
4590    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4591    (set_attr "mode" "<MODEF:MODE>")
4592    (set (attr "prefix_rex")
4593      (if_then_else
4594        (and (eq_attr "prefix" "maybe_vex")
4595             (match_test "<SWI48:MODE>mode == DImode"))
4596        (const_string "1")
4597        (const_string "*")))
4598    (set_attr "unit" "i387,*,*")
4599    (set_attr "athlon_decode" "*,double,direct")
4600    (set_attr "amdfam10_decode" "*,vector,double")
4601    (set_attr "bdver1_decode" "*,double,direct")
4602    (set_attr "fp_int_src" "true")])
4604 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4605   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4606         (float:MODEF
4607           (match_operand:SWI48 1 "memory_operand" "m,m")))]
4608   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4609    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4610   "@
4611    fild%Z1\t%1
4612    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4613   [(set_attr "type" "fmov,sseicvt")
4614    (set_attr "prefix" "orig,maybe_vex")
4615    (set_attr "mode" "<MODEF:MODE>")
4616    (set (attr "prefix_rex")
4617      (if_then_else
4618        (and (eq_attr "prefix" "maybe_vex")
4619             (match_test "<SWI48:MODE>mode == DImode"))
4620        (const_string "1")
4621        (const_string "*")))
4622    (set_attr "athlon_decode" "*,direct")
4623    (set_attr "amdfam10_decode" "*,double")
4624    (set_attr "bdver1_decode" "*,direct")
4625    (set_attr "fp_int_src" "true")])
4627 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4628   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4629         (float:MODEF
4630           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4631    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4632   "TARGET_SSE2 && TARGET_SSE_MATH
4633    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4634   "#"
4635   [(set_attr "type" "sseicvt")
4636    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4637    (set_attr "athlon_decode" "double,direct,double")
4638    (set_attr "amdfam10_decode" "vector,double,double")
4639    (set_attr "bdver1_decode" "double,direct,double")
4640    (set_attr "fp_int_src" "true")])
4642 (define_insn "*floatsi<mode>2_vector_sse"
4643   [(set (match_operand:MODEF 0 "register_operand" "=x")
4644         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4645   "TARGET_SSE2 && TARGET_SSE_MATH
4646    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4647   "#"
4648   [(set_attr "type" "sseicvt")
4649    (set_attr "mode" "<MODE>")
4650    (set_attr "athlon_decode" "direct")
4651    (set_attr "amdfam10_decode" "double")
4652    (set_attr "bdver1_decode" "direct")
4653    (set_attr "fp_int_src" "true")])
4655 (define_split
4656   [(set (match_operand:MODEF 0 "register_operand")
4657         (float:MODEF (match_operand:SI 1 "register_operand")))
4658    (clobber (match_operand:SI 2 "memory_operand"))]
4659   "TARGET_SSE2 && TARGET_SSE_MATH
4660    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4661    && reload_completed
4662    && (SSE_REG_P (operands[0])
4663        || (GET_CODE (operands[0]) == SUBREG
4664            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4665   [(const_int 0)]
4667   rtx op1 = operands[1];
4669   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4670                                      <MODE>mode, 0);
4671   if (GET_CODE (op1) == SUBREG)
4672     op1 = SUBREG_REG (op1);
4674   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4675     {
4676       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4677       emit_insn (gen_sse2_loadld (operands[4],
4678                                   CONST0_RTX (V4SImode), operands[1]));
4679     }
4680   /* We can ignore possible trapping value in the
4681      high part of SSE register for non-trapping math. */
4682   else if (SSE_REG_P (op1) && !flag_trapping_math)
4683     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4684   else
4685     {
4686       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4687       emit_move_insn (operands[2], operands[1]);
4688       emit_insn (gen_sse2_loadld (operands[4],
4689                                   CONST0_RTX (V4SImode), operands[2]));
4690     }
4691   if (<ssevecmode>mode == V4SFmode)
4692     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4693   else
4694     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4695   DONE;
4698 (define_split
4699   [(set (match_operand:MODEF 0 "register_operand")
4700         (float:MODEF (match_operand:SI 1 "memory_operand")))
4701    (clobber (match_operand:SI 2 "memory_operand"))]
4702   "TARGET_SSE2 && TARGET_SSE_MATH
4703    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4704    && reload_completed
4705    && (SSE_REG_P (operands[0])
4706        || (GET_CODE (operands[0]) == SUBREG
4707            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4708   [(const_int 0)]
4710   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4711                                      <MODE>mode, 0);
4712   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4714   emit_insn (gen_sse2_loadld (operands[4],
4715                               CONST0_RTX (V4SImode), operands[1]));
4716   if (<ssevecmode>mode == V4SFmode)
4717     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4718   else
4719     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4720   DONE;
4723 (define_split
4724   [(set (match_operand:MODEF 0 "register_operand")
4725         (float:MODEF (match_operand:SI 1 "register_operand")))]
4726   "TARGET_SSE2 && TARGET_SSE_MATH
4727    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4728    && reload_completed
4729    && (SSE_REG_P (operands[0])
4730        || (GET_CODE (operands[0]) == SUBREG
4731            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4732   [(const_int 0)]
4734   rtx op1 = operands[1];
4736   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4737                                      <MODE>mode, 0);
4738   if (GET_CODE (op1) == SUBREG)
4739     op1 = SUBREG_REG (op1);
4741   if (GENERAL_REG_P (op1))
4742     {
4743       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4744       if (TARGET_INTER_UNIT_MOVES)
4745         emit_insn (gen_sse2_loadld (operands[4],
4746                                     CONST0_RTX (V4SImode), operands[1]));
4747       else
4748         {
4749           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4750                                               operands[1]);
4751           emit_insn (gen_sse2_loadld (operands[4],
4752                                       CONST0_RTX (V4SImode), operands[5]));
4753           ix86_free_from_memory (GET_MODE (operands[1]));
4754         }
4755     }
4756   /* We can ignore possible trapping value in the
4757      high part of SSE register for non-trapping math. */
4758   else if (SSE_REG_P (op1) && !flag_trapping_math)
4759     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4760   else
4761     gcc_unreachable ();
4762   if (<ssevecmode>mode == V4SFmode)
4763     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4764   else
4765     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4766   DONE;
4769 (define_split
4770   [(set (match_operand:MODEF 0 "register_operand")
4771         (float:MODEF (match_operand:SI 1 "memory_operand")))]
4772   "TARGET_SSE2 && TARGET_SSE_MATH
4773    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4774    && reload_completed
4775    && (SSE_REG_P (operands[0])
4776        || (GET_CODE (operands[0]) == SUBREG
4777            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4778   [(const_int 0)]
4780   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4781                                      <MODE>mode, 0);
4782   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4784   emit_insn (gen_sse2_loadld (operands[4],
4785                               CONST0_RTX (V4SImode), operands[1]));
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_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
4794   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4795         (float:MODEF
4796           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
4797   (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
4798   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4799   "#"
4800   [(set_attr "type" "sseicvt")
4801    (set_attr "mode" "<MODEF:MODE>")
4802    (set_attr "athlon_decode" "double,direct")
4803    (set_attr "amdfam10_decode" "vector,double")
4804    (set_attr "bdver1_decode" "double,direct")
4805    (set_attr "btver2_decode" "double,double")
4806    (set_attr "fp_int_src" "true")])
4808 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
4809   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4810         (float:MODEF
4811           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
4812   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4813    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4814   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4815   [(set_attr "type" "sseicvt")
4816    (set_attr "prefix" "maybe_vex")
4817    (set_attr "mode" "<MODEF:MODE>")
4818    (set (attr "prefix_rex")
4819      (if_then_else
4820        (and (eq_attr "prefix" "maybe_vex")
4821             (match_test "<SWI48:MODE>mode == DImode"))
4822        (const_string "1")
4823        (const_string "*")))
4824    (set_attr "athlon_decode" "double,direct")
4825    (set_attr "amdfam10_decode" "vector,double")
4826    (set_attr "bdver1_decode" "double,direct")
4827    (set_attr "btver2_decode" "double,double")
4828    (set_attr "fp_int_src" "true")])
4830 (define_split
4831   [(set (match_operand:MODEF 0 "register_operand")
4832         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
4833    (clobber (match_operand:SWI48 2 "memory_operand"))]
4834   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4835    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4836    && reload_completed
4837    && (SSE_REG_P (operands[0])
4838        || (GET_CODE (operands[0]) == SUBREG
4839            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4840   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4842 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
4843   [(set (match_operand:MODEF 0 "register_operand" "=x")
4844         (float:MODEF
4845           (match_operand:SWI48 1 "memory_operand" "m")))]
4846   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4847    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4848   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4849   [(set_attr "type" "sseicvt")
4850    (set_attr "prefix" "maybe_vex")
4851    (set_attr "mode" "<MODEF:MODE>")
4852    (set (attr "prefix_rex")
4853      (if_then_else
4854        (and (eq_attr "prefix" "maybe_vex")
4855             (match_test "<SWI48:MODE>mode == DImode"))
4856        (const_string "1")
4857        (const_string "*")))
4858    (set_attr "athlon_decode" "direct")
4859    (set_attr "amdfam10_decode" "double")
4860    (set_attr "bdver1_decode" "direct")
4861    (set_attr "fp_int_src" "true")])
4863 (define_split
4864   [(set (match_operand:MODEF 0 "register_operand")
4865         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4866    (clobber (match_operand:SWI48 2 "memory_operand"))]
4867   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4868    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4869    && reload_completed
4870    && (SSE_REG_P (operands[0])
4871        || (GET_CODE (operands[0]) == SUBREG
4872            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4873   [(set (match_dup 2) (match_dup 1))
4874    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4876 (define_split
4877   [(set (match_operand:MODEF 0 "register_operand")
4878         (float:MODEF (match_operand:SWI48 1 "memory_operand")))
4879    (clobber (match_operand:SWI48 2 "memory_operand"))]
4880   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4881    && reload_completed
4882    && (SSE_REG_P (operands[0])
4883        || (GET_CODE (operands[0]) == SUBREG
4884            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4885   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4887 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
4888   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4889         (float:X87MODEF
4890           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
4891   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
4892   "TARGET_80387
4893    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4894   "@
4895    fild%Z1\t%1
4896    #"
4897   [(set_attr "type" "fmov,multi")
4898    (set_attr "mode" "<X87MODEF:MODE>")
4899    (set_attr "unit" "*,i387")
4900    (set_attr "fp_int_src" "true")])
4902 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
4903   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4904         (float:X87MODEF
4905           (match_operand:SWI48x 1 "memory_operand" "m")))]
4906   "TARGET_80387
4907    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4908   "fild%Z1\t%1"
4909   [(set_attr "type" "fmov")
4910    (set_attr "mode" "<X87MODEF:MODE>")
4911    (set_attr "fp_int_src" "true")])
4913 (define_split
4914   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4915         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
4916    (clobber (match_operand:SWI48x 2 "memory_operand"))]
4917   "TARGET_80387
4918    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4919    && reload_completed"
4920   [(set (match_dup 2) (match_dup 1))
4921    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4923 (define_split
4924   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4925         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
4926    (clobber (match_operand:SWI48x 2 "memory_operand"))]
4927   "TARGET_80387
4928    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4929    && reload_completed"
4930   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4932 ;; Avoid store forwarding (partial memory) stall penalty
4933 ;; by passing DImode value through XMM registers.  */
4935 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4936   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4937         (float:X87MODEF
4938           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4939    (clobber (match_scratch:V4SI 3 "=X,x"))
4940    (clobber (match_scratch:V4SI 4 "=X,x"))
4941    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4942   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4943    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4944    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4945   "#"
4946   [(set_attr "type" "multi")
4947    (set_attr "mode" "<X87MODEF:MODE>")
4948    (set_attr "unit" "i387")
4949    (set_attr "fp_int_src" "true")])
4951 (define_split
4952   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4953         (float:X87MODEF (match_operand:DI 1 "register_operand")))
4954    (clobber (match_scratch:V4SI 3))
4955    (clobber (match_scratch:V4SI 4))
4956    (clobber (match_operand:DI 2 "memory_operand"))]
4957   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4958    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4959    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4960    && reload_completed"
4961   [(set (match_dup 2) (match_dup 3))
4962    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4964   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4965      Assemble the 64-bit DImode value in an xmm register.  */
4966   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4967                               gen_rtx_SUBREG (SImode, operands[1], 0)));
4968   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4969                               gen_rtx_SUBREG (SImode, operands[1], 4)));
4970   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4971                                          operands[4]));
4973   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4976 (define_split
4977   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4978         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4979    (clobber (match_scratch:V4SI 3))
4980    (clobber (match_scratch:V4SI 4))
4981    (clobber (match_operand:DI 2 "memory_operand"))]
4982   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4983    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4984    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4985    && reload_completed"
4986   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4988 ;; Avoid store forwarding (partial memory) stall penalty by extending
4989 ;; SImode value to DImode through XMM register instead of pushing two
4990 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
4991 ;; targets benefit from this optimization. Also note that fild
4992 ;; loads from memory only.
4994 (define_insn "*floatunssi<mode>2_1"
4995   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4996         (unsigned_float:X87MODEF
4997           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
4998    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
4999    (clobber (match_scratch:SI 3 "=X,x"))]
5000   "!TARGET_64BIT
5001    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5002    && TARGET_SSE"
5003   "#"
5004   [(set_attr "type" "multi")
5005    (set_attr "mode" "<MODE>")])
5007 (define_split
5008   [(set (match_operand:X87MODEF 0 "register_operand")
5009         (unsigned_float:X87MODEF
5010           (match_operand:SI 1 "register_operand")))
5011    (clobber (match_operand:DI 2 "memory_operand"))
5012    (clobber (match_scratch:SI 3))]
5013   "!TARGET_64BIT
5014    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5015    && TARGET_SSE
5016    && reload_completed"
5017   [(set (match_dup 2) (match_dup 1))
5018    (set (match_dup 0)
5019         (float:X87MODEF (match_dup 2)))]
5020   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5022 (define_split
5023   [(set (match_operand:X87MODEF 0 "register_operand")
5024         (unsigned_float:X87MODEF
5025           (match_operand:SI 1 "memory_operand")))
5026    (clobber (match_operand:DI 2 "memory_operand"))
5027    (clobber (match_scratch:SI 3))]
5028   "!TARGET_64BIT
5029    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5030    && TARGET_SSE
5031    && reload_completed"
5032   [(set (match_dup 2) (match_dup 3))
5033    (set (match_dup 0)
5034         (float:X87MODEF (match_dup 2)))]
5036   emit_move_insn (operands[3], operands[1]);
5037   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5040 (define_expand "floatunssi<mode>2"
5041   [(parallel
5042      [(set (match_operand:X87MODEF 0 "register_operand")
5043            (unsigned_float:X87MODEF
5044              (match_operand:SI 1 "nonimmediate_operand")))
5045       (clobber (match_dup 2))
5046       (clobber (match_scratch:SI 3))])]
5047   "!TARGET_64BIT
5048    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5049         && TARGET_SSE)
5050        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5052   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5053     {
5054       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5055       DONE;
5056     }
5057   else
5058     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5061 (define_expand "floatunsdisf2"
5062   [(use (match_operand:SF 0 "register_operand"))
5063    (use (match_operand:DI 1 "nonimmediate_operand"))]
5064   "TARGET_64BIT && TARGET_SSE_MATH"
5065   "x86_emit_floatuns (operands); DONE;")
5067 (define_expand "floatunsdidf2"
5068   [(use (match_operand:DF 0 "register_operand"))
5069    (use (match_operand:DI 1 "nonimmediate_operand"))]
5070   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5071    && TARGET_SSE2 && TARGET_SSE_MATH"
5073   if (TARGET_64BIT)
5074     x86_emit_floatuns (operands);
5075   else
5076     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5077   DONE;
5080 ;; Load effective address instructions
5082 (define_insn_and_split "*lea<mode>"
5083   [(set (match_operand:SWI48 0 "register_operand" "=r")
5084         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5085   ""
5087   if (SImode_address_operand (operands[1], VOIDmode))
5088     {
5089       gcc_assert (TARGET_64BIT);
5090       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5091     }
5092   else 
5093     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5095   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5096   [(const_int 0)]
5098   enum machine_mode mode = <MODE>mode;
5099   rtx pat;
5101   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5102      change operands[] array behind our back.  */
5103   pat = PATTERN (curr_insn);
5105   operands[0] = SET_DEST (pat);
5106   operands[1] = SET_SRC (pat);
5108   /* Emit all operations in SImode for zero-extended addresses.  Recall
5109      that x86_64 inheretly zero-extends SImode operations to DImode.  */
5110   if (SImode_address_operand (operands[1], VOIDmode))
5111     mode = SImode;
5113   ix86_split_lea_for_addr (curr_insn, operands, mode);
5114   DONE;
5116   [(set_attr "type" "lea")
5117    (set (attr "mode")
5118      (if_then_else
5119        (match_operand 1 "SImode_address_operand")
5120        (const_string "SI")
5121        (const_string "<MODE>")))])
5123 ;; Add instructions
5125 (define_expand "add<mode>3"
5126   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5127         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5128                     (match_operand:SDWIM 2 "<general_operand>")))]
5129   ""
5130   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5132 (define_insn_and_split "*add<dwi>3_doubleword"
5133   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5134         (plus:<DWI>
5135           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5136           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5137    (clobber (reg:CC FLAGS_REG))]
5138   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5139   "#"
5140   "reload_completed"
5141   [(parallel [(set (reg:CC FLAGS_REG)
5142                    (unspec:CC [(match_dup 1) (match_dup 2)]
5143                               UNSPEC_ADD_CARRY))
5144               (set (match_dup 0)
5145                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5146    (parallel [(set (match_dup 3)
5147                    (plus:DWIH
5148                      (match_dup 4)
5149                      (plus:DWIH
5150                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5151                        (match_dup 5))))
5152               (clobber (reg:CC FLAGS_REG))])]
5153   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5155 (define_insn "*add<mode>3_cc"
5156   [(set (reg:CC FLAGS_REG)
5157         (unspec:CC
5158           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5159            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5160           UNSPEC_ADD_CARRY))
5161    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5162         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5163   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5164   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5165   [(set_attr "type" "alu")
5166    (set_attr "mode" "<MODE>")])
5168 (define_insn "addqi3_cc"
5169   [(set (reg:CC FLAGS_REG)
5170         (unspec:CC
5171           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5172            (match_operand:QI 2 "general_operand" "qn,qm")]
5173           UNSPEC_ADD_CARRY))
5174    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5175         (plus:QI (match_dup 1) (match_dup 2)))]
5176   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5177   "add{b}\t{%2, %0|%0, %2}"
5178   [(set_attr "type" "alu")
5179    (set_attr "mode" "QI")])
5181 (define_insn "*add<mode>_1"
5182   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5183         (plus:SWI48
5184           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5185           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5186    (clobber (reg:CC FLAGS_REG))]
5187   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5189   switch (get_attr_type (insn))
5190     {
5191     case TYPE_LEA:
5192       return "#";
5194     case TYPE_INCDEC:
5195       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5196       if (operands[2] == const1_rtx)
5197         return "inc{<imodesuffix>}\t%0";
5198       else
5199         {
5200           gcc_assert (operands[2] == constm1_rtx);
5201           return "dec{<imodesuffix>}\t%0";
5202         }
5204     default:
5205       /* For most processors, ADD is faster than LEA.  This alternative
5206          was added to use ADD as much as possible.  */
5207       if (which_alternative == 2)
5208         {
5209           rtx tmp;
5210           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5211         }
5212         
5213       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5215         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5217       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5218     }
5220   [(set (attr "type")
5221      (cond [(eq_attr "alternative" "3")
5222               (const_string "lea")
5223             (match_operand:SWI48 2 "incdec_operand")
5224               (const_string "incdec")
5225            ]
5226            (const_string "alu")))
5227    (set (attr "length_immediate")
5228       (if_then_else
5229         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5230         (const_string "1")
5231         (const_string "*")))
5232    (set_attr "mode" "<MODE>")])
5234 ;; It may seem that nonimmediate operand is proper one for operand 1.
5235 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5236 ;; we take care in ix86_binary_operator_ok to not allow two memory
5237 ;; operands so proper swapping will be done in reload.  This allow
5238 ;; patterns constructed from addsi_1 to match.
5240 (define_insn "addsi_1_zext"
5241   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5242         (zero_extend:DI
5243           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5244                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5245    (clobber (reg:CC FLAGS_REG))]
5246   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5248   switch (get_attr_type (insn))
5249     {
5250     case TYPE_LEA:
5251       return "#";
5253     case TYPE_INCDEC:
5254       if (operands[2] == const1_rtx)
5255         return "inc{l}\t%k0";
5256       else
5257         {
5258           gcc_assert (operands[2] == constm1_rtx);
5259           return "dec{l}\t%k0";
5260         }
5262     default:
5263       /* For most processors, ADD is faster than LEA.  This alternative
5264          was added to use ADD as much as possible.  */
5265       if (which_alternative == 1)
5266         {
5267           rtx tmp;
5268           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5269         }
5271       if (x86_maybe_negate_const_int (&operands[2], SImode))
5272         return "sub{l}\t{%2, %k0|%k0, %2}";
5274       return "add{l}\t{%2, %k0|%k0, %2}";
5275     }
5277   [(set (attr "type")
5278      (cond [(eq_attr "alternative" "2")
5279               (const_string "lea")
5280             (match_operand:SI 2 "incdec_operand")
5281               (const_string "incdec")
5282            ]
5283            (const_string "alu")))
5284    (set (attr "length_immediate")
5285       (if_then_else
5286         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5287         (const_string "1")
5288         (const_string "*")))
5289    (set_attr "mode" "SI")])
5291 (define_insn "*addhi_1"
5292   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5293         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5294                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5295    (clobber (reg:CC FLAGS_REG))]
5296   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5298   switch (get_attr_type (insn))
5299     {
5300     case TYPE_LEA:
5301       return "#";
5303     case TYPE_INCDEC:
5304       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5305       if (operands[2] == const1_rtx)
5306         return "inc{w}\t%0";
5307       else
5308         {
5309           gcc_assert (operands[2] == constm1_rtx);
5310           return "dec{w}\t%0";
5311         }
5313     default:
5314       /* For most processors, ADD is faster than LEA.  This alternative
5315          was added to use ADD as much as possible.  */
5316       if (which_alternative == 2)
5317         {
5318           rtx tmp;
5319           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5320         }
5322       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5323       if (x86_maybe_negate_const_int (&operands[2], HImode))
5324         return "sub{w}\t{%2, %0|%0, %2}";
5326       return "add{w}\t{%2, %0|%0, %2}";
5327     }
5329   [(set (attr "type")
5330      (cond [(eq_attr "alternative" "3")
5331               (const_string "lea")
5332             (match_operand:HI 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" "HI,HI,HI,SI")])
5343 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5344 (define_insn "*addqi_1"
5345   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5346         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5347                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5348    (clobber (reg:CC FLAGS_REG))]
5349   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5351   bool widen = (which_alternative == 3 || which_alternative == 4);
5353   switch (get_attr_type (insn))
5354     {
5355     case TYPE_LEA:
5356       return "#";
5358     case TYPE_INCDEC:
5359       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360       if (operands[2] == const1_rtx)
5361         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5362       else
5363         {
5364           gcc_assert (operands[2] == constm1_rtx);
5365           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5366         }
5368     default:
5369       /* For most processors, ADD is faster than LEA.  These alternatives
5370          were added to use ADD as much as possible.  */
5371       if (which_alternative == 2 || which_alternative == 4)
5372         {
5373           rtx tmp;
5374           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5375         }
5377       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5378       if (x86_maybe_negate_const_int (&operands[2], QImode))
5379         {
5380           if (widen)
5381             return "sub{l}\t{%2, %k0|%k0, %2}";
5382           else
5383             return "sub{b}\t{%2, %0|%0, %2}";
5384         }
5385       if (widen)
5386         return "add{l}\t{%k2, %k0|%k0, %k2}";
5387       else
5388         return "add{b}\t{%2, %0|%0, %2}";
5389     }
5391   [(set (attr "type")
5392      (cond [(eq_attr "alternative" "5")
5393               (const_string "lea")
5394             (match_operand:QI 2 "incdec_operand")
5395               (const_string "incdec")
5396            ]
5397            (const_string "alu")))
5398    (set (attr "length_immediate")
5399       (if_then_else
5400         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5401         (const_string "1")
5402         (const_string "*")))
5403    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5405 (define_insn "*addqi_1_slp"
5406   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5407         (plus:QI (match_dup 0)
5408                  (match_operand:QI 1 "general_operand" "qn,qm")))
5409    (clobber (reg:CC FLAGS_REG))]
5410   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5411    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5413   switch (get_attr_type (insn))
5414     {
5415     case TYPE_INCDEC:
5416       if (operands[1] == const1_rtx)
5417         return "inc{b}\t%0";
5418       else
5419         {
5420           gcc_assert (operands[1] == constm1_rtx);
5421           return "dec{b}\t%0";
5422         }
5424     default:
5425       if (x86_maybe_negate_const_int (&operands[1], QImode))
5426         return "sub{b}\t{%1, %0|%0, %1}";
5428       return "add{b}\t{%1, %0|%0, %1}";
5429     }
5431   [(set (attr "type")
5432      (if_then_else (match_operand:QI 1 "incdec_operand")
5433         (const_string "incdec")
5434         (const_string "alu1")))
5435    (set (attr "memory")
5436      (if_then_else (match_operand 1 "memory_operand")
5437         (const_string "load")
5438         (const_string "none")))
5439    (set_attr "mode" "QI")])
5441 ;; Split non destructive adds if we cannot use lea.
5442 (define_split
5443   [(set (match_operand:SWI48 0 "register_operand")
5444         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5445                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5446    (clobber (reg:CC FLAGS_REG))]
5447   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5448   [(set (match_dup 0) (match_dup 1))
5449    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5450               (clobber (reg:CC FLAGS_REG))])])
5452 ;; Convert add to the lea pattern to avoid flags dependency.
5453 (define_split
5454   [(set (match_operand:SWI 0 "register_operand")
5455         (plus:SWI (match_operand:SWI 1 "register_operand")
5456                   (match_operand:SWI 2 "<nonmemory_operand>")))
5457    (clobber (reg:CC FLAGS_REG))]
5458   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5459   [(const_int 0)]
5461   enum machine_mode mode = <MODE>mode;
5462   rtx pat;
5464   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5465     { 
5466       mode = SImode; 
5467       operands[0] = gen_lowpart (mode, operands[0]);
5468       operands[1] = gen_lowpart (mode, operands[1]);
5469       operands[2] = gen_lowpart (mode, operands[2]);
5470     }
5472   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5474   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5475   DONE;
5478 ;; Split non destructive adds if we cannot use lea.
5479 (define_split
5480   [(set (match_operand:DI 0 "register_operand")
5481         (zero_extend:DI
5482           (plus:SI (match_operand:SI 1 "register_operand")
5483                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5484    (clobber (reg:CC FLAGS_REG))]
5485   "TARGET_64BIT
5486    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5487   [(set (match_dup 3) (match_dup 1))
5488    (parallel [(set (match_dup 0)
5489                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5490               (clobber (reg:CC FLAGS_REG))])]
5491   "operands[3] = gen_lowpart (SImode, operands[0]);")
5493 ;; Convert add to the lea pattern to avoid flags dependency.
5494 (define_split
5495   [(set (match_operand:DI 0 "register_operand")
5496         (zero_extend:DI
5497           (plus:SI (match_operand:SI 1 "register_operand")
5498                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5499    (clobber (reg:CC FLAGS_REG))]
5500   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5501   [(set (match_dup 0)
5502         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5504 (define_insn "*add<mode>_2"
5505   [(set (reg FLAGS_REG)
5506         (compare
5507           (plus:SWI
5508             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5509             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5510           (const_int 0)))
5511    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5512         (plus:SWI (match_dup 1) (match_dup 2)))]
5513   "ix86_match_ccmode (insn, CCGOCmode)
5514    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5516   switch (get_attr_type (insn))
5517     {
5518     case TYPE_INCDEC:
5519       if (operands[2] == const1_rtx)
5520         return "inc{<imodesuffix>}\t%0";
5521       else
5522         {
5523           gcc_assert (operands[2] == constm1_rtx);
5524           return "dec{<imodesuffix>}\t%0";
5525         }
5527     default:
5528       if (which_alternative == 2)
5529         {
5530           rtx tmp;
5531           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5532         }
5533         
5534       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5535       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5536         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5538       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5539     }
5541   [(set (attr "type")
5542      (if_then_else (match_operand:SWI 2 "incdec_operand")
5543         (const_string "incdec")
5544         (const_string "alu")))
5545    (set (attr "length_immediate")
5546       (if_then_else
5547         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5548         (const_string "1")
5549         (const_string "*")))
5550    (set_attr "mode" "<MODE>")])
5552 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5553 (define_insn "*addsi_2_zext"
5554   [(set (reg FLAGS_REG)
5555         (compare
5556           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5557                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5558           (const_int 0)))
5559    (set (match_operand:DI 0 "register_operand" "=r,r")
5560         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5561   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5562    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5564   switch (get_attr_type (insn))
5565     {
5566     case TYPE_INCDEC:
5567       if (operands[2] == const1_rtx)
5568         return "inc{l}\t%k0";
5569       else
5570         {
5571           gcc_assert (operands[2] == constm1_rtx);
5572           return "dec{l}\t%k0";
5573         }
5575     default:
5576       if (which_alternative == 1)
5577         {
5578           rtx tmp;
5579           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5580         }
5582       if (x86_maybe_negate_const_int (&operands[2], SImode))
5583         return "sub{l}\t{%2, %k0|%k0, %2}";
5585       return "add{l}\t{%2, %k0|%k0, %2}";
5586     }
5588   [(set (attr "type")
5589      (if_then_else (match_operand:SI 2 "incdec_operand")
5590         (const_string "incdec")
5591         (const_string "alu")))
5592    (set (attr "length_immediate")
5593       (if_then_else
5594         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5595         (const_string "1")
5596         (const_string "*")))
5597    (set_attr "mode" "SI")])
5599 (define_insn "*add<mode>_3"
5600   [(set (reg FLAGS_REG)
5601         (compare
5602           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5603           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5604    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5605   "ix86_match_ccmode (insn, CCZmode)
5606    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5608   switch (get_attr_type (insn))
5609     {
5610     case TYPE_INCDEC:
5611       if (operands[2] == const1_rtx)
5612         return "inc{<imodesuffix>}\t%0";
5613       else
5614         {
5615           gcc_assert (operands[2] == constm1_rtx);
5616           return "dec{<imodesuffix>}\t%0";
5617         }
5619     default:
5620       if (which_alternative == 1)
5621         {
5622           rtx tmp;
5623           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5624         }
5626       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5627       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5628         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5630       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5631     }
5633   [(set (attr "type")
5634      (if_then_else (match_operand:SWI 2 "incdec_operand")
5635         (const_string "incdec")
5636         (const_string "alu")))
5637    (set (attr "length_immediate")
5638       (if_then_else
5639         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5640         (const_string "1")
5641         (const_string "*")))
5642    (set_attr "mode" "<MODE>")])
5644 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5645 (define_insn "*addsi_3_zext"
5646   [(set (reg FLAGS_REG)
5647         (compare
5648           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5649           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5650    (set (match_operand:DI 0 "register_operand" "=r,r")
5651         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5652   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5653    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5655   switch (get_attr_type (insn))
5656     {
5657     case TYPE_INCDEC:
5658       if (operands[2] == const1_rtx)
5659         return "inc{l}\t%k0";
5660       else
5661         {
5662           gcc_assert (operands[2] == constm1_rtx);
5663           return "dec{l}\t%k0";
5664         }
5666     default:
5667       if (which_alternative == 1)
5668         {
5669           rtx tmp;
5670           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5671         }
5673       if (x86_maybe_negate_const_int (&operands[2], SImode))
5674         return "sub{l}\t{%2, %k0|%k0, %2}";
5676       return "add{l}\t{%2, %k0|%k0, %2}";
5677     }
5679   [(set (attr "type")
5680      (if_then_else (match_operand:SI 2 "incdec_operand")
5681         (const_string "incdec")
5682         (const_string "alu")))
5683    (set (attr "length_immediate")
5684       (if_then_else
5685         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5686         (const_string "1")
5687         (const_string "*")))
5688    (set_attr "mode" "SI")])
5690 ; For comparisons against 1, -1 and 128, we may generate better code
5691 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5692 ; is matched then.  We can't accept general immediate, because for
5693 ; case of overflows,  the result is messed up.
5694 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5695 ; only for comparisons not depending on it.
5697 (define_insn "*adddi_4"
5698   [(set (reg FLAGS_REG)
5699         (compare
5700           (match_operand:DI 1 "nonimmediate_operand" "0")
5701           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5702    (clobber (match_scratch:DI 0 "=rm"))]
5703   "TARGET_64BIT
5704    && ix86_match_ccmode (insn, CCGCmode)"
5706   switch (get_attr_type (insn))
5707     {
5708     case TYPE_INCDEC:
5709       if (operands[2] == constm1_rtx)
5710         return "inc{q}\t%0";
5711       else
5712         {
5713           gcc_assert (operands[2] == const1_rtx);
5714           return "dec{q}\t%0";
5715         }
5717     default:
5718       if (x86_maybe_negate_const_int (&operands[2], DImode))
5719         return "add{q}\t{%2, %0|%0, %2}";
5721       return "sub{q}\t{%2, %0|%0, %2}";
5722     }
5724   [(set (attr "type")
5725      (if_then_else (match_operand:DI 2 "incdec_operand")
5726         (const_string "incdec")
5727         (const_string "alu")))
5728    (set (attr "length_immediate")
5729       (if_then_else
5730         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5731         (const_string "1")
5732         (const_string "*")))
5733    (set_attr "mode" "DI")])
5735 ; For comparisons against 1, -1 and 128, we may generate better code
5736 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5737 ; is matched then.  We can't accept general immediate, because for
5738 ; case of overflows,  the result is messed up.
5739 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5740 ; only for comparisons not depending on it.
5742 (define_insn "*add<mode>_4"
5743   [(set (reg FLAGS_REG)
5744         (compare
5745           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5746           (match_operand:SWI124 2 "const_int_operand" "n")))
5747    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5748   "ix86_match_ccmode (insn, CCGCmode)"
5750   switch (get_attr_type (insn))
5751     {
5752     case TYPE_INCDEC:
5753       if (operands[2] == constm1_rtx)
5754         return "inc{<imodesuffix>}\t%0";
5755       else
5756         {
5757           gcc_assert (operands[2] == const1_rtx);
5758           return "dec{<imodesuffix>}\t%0";
5759         }
5761     default:
5762       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5763         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5765       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5766     }
5768   [(set (attr "type")
5769      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5770         (const_string "incdec")
5771         (const_string "alu")))
5772    (set (attr "length_immediate")
5773       (if_then_else
5774         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5775         (const_string "1")
5776         (const_string "*")))
5777    (set_attr "mode" "<MODE>")])
5779 (define_insn "*add<mode>_5"
5780   [(set (reg FLAGS_REG)
5781         (compare
5782           (plus:SWI
5783             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5784             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5785           (const_int 0)))
5786    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5787   "ix86_match_ccmode (insn, CCGOCmode)
5788    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5790   switch (get_attr_type (insn))
5791     {
5792     case TYPE_INCDEC:
5793       if (operands[2] == const1_rtx)
5794         return "inc{<imodesuffix>}\t%0";
5795       else
5796         {
5797           gcc_assert (operands[2] == constm1_rtx);
5798           return "dec{<imodesuffix>}\t%0";
5799         }
5801     default:
5802       if (which_alternative == 1)
5803         {
5804           rtx tmp;
5805           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5806         }
5808       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5810         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5812       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5813     }
5815   [(set (attr "type")
5816      (if_then_else (match_operand:SWI 2 "incdec_operand")
5817         (const_string "incdec")
5818         (const_string "alu")))
5819    (set (attr "length_immediate")
5820       (if_then_else
5821         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5822         (const_string "1")
5823         (const_string "*")))
5824    (set_attr "mode" "<MODE>")])
5826 (define_insn "*addqi_ext_1_rex64"
5827   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5828                          (const_int 8)
5829                          (const_int 8))
5830         (plus:SI
5831           (zero_extract:SI
5832             (match_operand 1 "ext_register_operand" "0")
5833             (const_int 8)
5834             (const_int 8))
5835           (match_operand:QI 2 "nonmemory_operand" "Qn")))
5836    (clobber (reg:CC FLAGS_REG))]
5837   "TARGET_64BIT"
5839   switch (get_attr_type (insn))
5840     {
5841     case TYPE_INCDEC:
5842       if (operands[2] == const1_rtx)
5843         return "inc{b}\t%h0";
5844       else
5845         {
5846           gcc_assert (operands[2] == constm1_rtx);
5847           return "dec{b}\t%h0";
5848         }
5850     default:
5851       return "add{b}\t{%2, %h0|%h0, %2}";
5852     }
5854   [(set (attr "type")
5855      (if_then_else (match_operand:QI 2 "incdec_operand")
5856         (const_string "incdec")
5857         (const_string "alu")))
5858    (set_attr "modrm" "1")
5859    (set_attr "mode" "QI")])
5861 (define_insn "addqi_ext_1"
5862   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5863                          (const_int 8)
5864                          (const_int 8))
5865         (plus:SI
5866           (zero_extract:SI
5867             (match_operand 1 "ext_register_operand" "0")
5868             (const_int 8)
5869             (const_int 8))
5870           (match_operand:QI 2 "general_operand" "Qmn")))
5871    (clobber (reg:CC FLAGS_REG))]
5872   "!TARGET_64BIT"
5874   switch (get_attr_type (insn))
5875     {
5876     case TYPE_INCDEC:
5877       if (operands[2] == const1_rtx)
5878         return "inc{b}\t%h0";
5879       else
5880         {
5881           gcc_assert (operands[2] == constm1_rtx);
5882           return "dec{b}\t%h0";
5883         }
5885     default:
5886       return "add{b}\t{%2, %h0|%h0, %2}";
5887     }
5889   [(set (attr "type")
5890      (if_then_else (match_operand:QI 2 "incdec_operand")
5891         (const_string "incdec")
5892         (const_string "alu")))
5893    (set_attr "modrm" "1")
5894    (set_attr "mode" "QI")])
5896 (define_insn "*addqi_ext_2"
5897   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5898                          (const_int 8)
5899                          (const_int 8))
5900         (plus:SI
5901           (zero_extract:SI
5902             (match_operand 1 "ext_register_operand" "%0")
5903             (const_int 8)
5904             (const_int 8))
5905           (zero_extract:SI
5906             (match_operand 2 "ext_register_operand" "Q")
5907             (const_int 8)
5908             (const_int 8))))
5909    (clobber (reg:CC FLAGS_REG))]
5910   ""
5911   "add{b}\t{%h2, %h0|%h0, %h2}"
5912   [(set_attr "type" "alu")
5913    (set_attr "mode" "QI")])
5915 ;; The lea patterns for modes less than 32 bits need to be matched by
5916 ;; several insns converted to real lea by splitters.
5918 (define_insn_and_split "*lea_general_1"
5919   [(set (match_operand 0 "register_operand" "=r")
5920         (plus (plus (match_operand 1 "index_register_operand" "l")
5921                     (match_operand 2 "register_operand" "r"))
5922               (match_operand 3 "immediate_operand" "i")))]
5923   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5924    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5925    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5926    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5927    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5928        || GET_MODE (operands[3]) == VOIDmode)"
5929   "#"
5930   "&& reload_completed"
5931   [(const_int 0)]
5933   enum machine_mode mode = SImode;
5934   rtx pat;
5936   operands[0] = gen_lowpart (mode, operands[0]);
5937   operands[1] = gen_lowpart (mode, operands[1]);
5938   operands[2] = gen_lowpart (mode, operands[2]);
5939   operands[3] = gen_lowpart (mode, operands[3]);
5941   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5942                       operands[3]);
5944   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5945   DONE;
5947   [(set_attr "type" "lea")
5948    (set_attr "mode" "SI")])
5950 (define_insn_and_split "*lea_general_2"
5951   [(set (match_operand 0 "register_operand" "=r")
5952         (plus (mult (match_operand 1 "index_register_operand" "l")
5953                     (match_operand 2 "const248_operand" "n"))
5954               (match_operand 3 "nonmemory_operand" "ri")))]
5955   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5956    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5957    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5958    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5959        || GET_MODE (operands[3]) == VOIDmode)"
5960   "#"
5961   "&& reload_completed"
5962   [(const_int 0)]
5964   enum machine_mode mode = SImode;
5965   rtx pat;
5967   operands[0] = gen_lowpart (mode, operands[0]);
5968   operands[1] = gen_lowpart (mode, operands[1]);
5969   operands[3] = gen_lowpart (mode, operands[3]);
5971   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5972                       operands[3]);
5974   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5975   DONE;
5977   [(set_attr "type" "lea")
5978    (set_attr "mode" "SI")])
5980 (define_insn_and_split "*lea_general_3"
5981   [(set (match_operand 0 "register_operand" "=r")
5982         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5983                           (match_operand 2 "const248_operand" "n"))
5984                     (match_operand 3 "register_operand" "r"))
5985               (match_operand 4 "immediate_operand" "i")))]
5986   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5987    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5988    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5989    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5990   "#"
5991   "&& reload_completed"
5992   [(const_int 0)]
5994   enum machine_mode mode = SImode;
5995   rtx pat;
5997   operands[0] = gen_lowpart (mode, operands[0]);
5998   operands[1] = gen_lowpart (mode, operands[1]);
5999   operands[3] = gen_lowpart (mode, operands[3]);
6000   operands[4] = gen_lowpart (mode, operands[4]);
6002   pat = gen_rtx_PLUS (mode,
6003                       gen_rtx_PLUS (mode,
6004                                     gen_rtx_MULT (mode, operands[1],
6005                                                         operands[2]),
6006                                     operands[3]),
6007                       operands[4]);
6009   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6010   DONE;
6012   [(set_attr "type" "lea")
6013    (set_attr "mode" "SI")])
6015 (define_insn_and_split "*lea_general_4"
6016   [(set (match_operand 0 "register_operand" "=r")
6017         (any_or (ashift
6018                   (match_operand 1 "index_register_operand" "l")
6019                   (match_operand 2 "const_int_operand" "n"))
6020                 (match_operand 3 "const_int_operand" "n")))]
6021   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6022       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6023     || GET_MODE (operands[0]) == SImode
6024     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6025    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6026    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6027    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6028        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6029   "#"
6030   "&& reload_completed"
6031   [(const_int 0)]
6033   enum machine_mode mode = GET_MODE (operands[0]);
6034   rtx pat;
6036   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6037     { 
6038       mode = SImode; 
6039       operands[0] = gen_lowpart (mode, operands[0]);
6040       operands[1] = gen_lowpart (mode, operands[1]);
6041     }
6043   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6045   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6046                        INTVAL (operands[3]));
6048   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6049   DONE;
6051   [(set_attr "type" "lea")
6052    (set (attr "mode")
6053       (if_then_else (match_operand:DI 0)
6054         (const_string "DI")
6055         (const_string "SI")))])
6057 ;; Subtract instructions
6059 (define_expand "sub<mode>3"
6060   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6061         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6062                      (match_operand:SDWIM 2 "<general_operand>")))]
6063   ""
6064   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6066 (define_insn_and_split "*sub<dwi>3_doubleword"
6067   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6068         (minus:<DWI>
6069           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6070           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6071    (clobber (reg:CC FLAGS_REG))]
6072   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6073   "#"
6074   "reload_completed"
6075   [(parallel [(set (reg:CC FLAGS_REG)
6076                    (compare:CC (match_dup 1) (match_dup 2)))
6077               (set (match_dup 0)
6078                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6079    (parallel [(set (match_dup 3)
6080                    (minus:DWIH
6081                      (match_dup 4)
6082                      (plus:DWIH
6083                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6084                        (match_dup 5))))
6085               (clobber (reg:CC FLAGS_REG))])]
6086   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6088 (define_insn "*sub<mode>_1"
6089   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6090         (minus:SWI
6091           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6092           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6093    (clobber (reg:CC FLAGS_REG))]
6094   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6095   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6096   [(set_attr "type" "alu")
6097    (set_attr "mode" "<MODE>")])
6099 (define_insn "*subsi_1_zext"
6100   [(set (match_operand:DI 0 "register_operand" "=r")
6101         (zero_extend:DI
6102           (minus:SI (match_operand:SI 1 "register_operand" "0")
6103                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6104    (clobber (reg:CC FLAGS_REG))]
6105   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6106   "sub{l}\t{%2, %k0|%k0, %2}"
6107   [(set_attr "type" "alu")
6108    (set_attr "mode" "SI")])
6110 (define_insn "*subqi_1_slp"
6111   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6112         (minus:QI (match_dup 0)
6113                   (match_operand:QI 1 "general_operand" "qn,qm")))
6114    (clobber (reg:CC FLAGS_REG))]
6115   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6116    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6117   "sub{b}\t{%1, %0|%0, %1}"
6118   [(set_attr "type" "alu1")
6119    (set_attr "mode" "QI")])
6121 (define_insn "*sub<mode>_2"
6122   [(set (reg FLAGS_REG)
6123         (compare
6124           (minus:SWI
6125             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6126             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6127           (const_int 0)))
6128    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6129         (minus:SWI (match_dup 1) (match_dup 2)))]
6130   "ix86_match_ccmode (insn, CCGOCmode)
6131    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6132   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6133   [(set_attr "type" "alu")
6134    (set_attr "mode" "<MODE>")])
6136 (define_insn "*subsi_2_zext"
6137   [(set (reg FLAGS_REG)
6138         (compare
6139           (minus:SI (match_operand:SI 1 "register_operand" "0")
6140                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6141           (const_int 0)))
6142    (set (match_operand:DI 0 "register_operand" "=r")
6143         (zero_extend:DI
6144           (minus:SI (match_dup 1)
6145                     (match_dup 2))))]
6146   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6147    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6148   "sub{l}\t{%2, %k0|%k0, %2}"
6149   [(set_attr "type" "alu")
6150    (set_attr "mode" "SI")])
6152 (define_insn "*sub<mode>_3"
6153   [(set (reg FLAGS_REG)
6154         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6155                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6156    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6157         (minus:SWI (match_dup 1) (match_dup 2)))]
6158   "ix86_match_ccmode (insn, CCmode)
6159    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6160   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6161   [(set_attr "type" "alu")
6162    (set_attr "mode" "<MODE>")])
6164 (define_insn "*subsi_3_zext"
6165   [(set (reg FLAGS_REG)
6166         (compare (match_operand:SI 1 "register_operand" "0")
6167                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6168    (set (match_operand:DI 0 "register_operand" "=r")
6169         (zero_extend:DI
6170           (minus:SI (match_dup 1)
6171                     (match_dup 2))))]
6172   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6173    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6174   "sub{l}\t{%2, %1|%1, %2}"
6175   [(set_attr "type" "alu")
6176    (set_attr "mode" "SI")])
6178 ;; Add with carry and subtract with borrow
6180 (define_expand "<plusminus_insn><mode>3_carry"
6181   [(parallel
6182     [(set (match_operand:SWI 0 "nonimmediate_operand")
6183           (plusminus:SWI
6184             (match_operand:SWI 1 "nonimmediate_operand")
6185             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6186                        [(match_operand 3 "flags_reg_operand")
6187                         (const_int 0)])
6188                       (match_operand:SWI 2 "<general_operand>"))))
6189      (clobber (reg:CC FLAGS_REG))])]
6190   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6192 (define_insn "*<plusminus_insn><mode>3_carry"
6193   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6194         (plusminus:SWI
6195           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6196           (plus:SWI
6197             (match_operator 3 "ix86_carry_flag_operator"
6198              [(reg FLAGS_REG) (const_int 0)])
6199             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6200    (clobber (reg:CC FLAGS_REG))]
6201   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6202   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6203   [(set_attr "type" "alu")
6204    (set_attr "use_carry" "1")
6205    (set_attr "pent_pair" "pu")
6206    (set_attr "mode" "<MODE>")])
6208 (define_insn "*addsi3_carry_zext"
6209   [(set (match_operand:DI 0 "register_operand" "=r")
6210         (zero_extend:DI
6211           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6212                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6213                              [(reg FLAGS_REG) (const_int 0)])
6214                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6215    (clobber (reg:CC FLAGS_REG))]
6216   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6217   "adc{l}\t{%2, %k0|%k0, %2}"
6218   [(set_attr "type" "alu")
6219    (set_attr "use_carry" "1")
6220    (set_attr "pent_pair" "pu")
6221    (set_attr "mode" "SI")])
6223 (define_insn "*subsi3_carry_zext"
6224   [(set (match_operand:DI 0 "register_operand" "=r")
6225         (zero_extend:DI
6226           (minus:SI (match_operand:SI 1 "register_operand" "0")
6227                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6228                               [(reg FLAGS_REG) (const_int 0)])
6229                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6230    (clobber (reg:CC FLAGS_REG))]
6231   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6232   "sbb{l}\t{%2, %k0|%k0, %2}"
6233   [(set_attr "type" "alu")
6234    (set_attr "pent_pair" "pu")
6235    (set_attr "mode" "SI")])
6237 ;; ADCX instruction
6239 (define_insn "adcx<mode>3"
6240   [(set (reg:CCC FLAGS_REG)
6241         (compare:CCC
6242           (plus:SWI48
6243             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6244             (plus:SWI48
6245               (match_operator 4 "ix86_carry_flag_operator"
6246                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6247               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6248           (const_int 0)))
6249    (set (match_operand:SWI48 0 "register_operand" "=r")
6250         (plus:SWI48 (match_dup 1)
6251                     (plus:SWI48 (match_op_dup 4
6252                                  [(match_dup 3) (const_int 0)])
6253                                 (match_dup 2))))]
6254   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6255   "adcx\t{%2, %0|%0, %2}"
6256   [(set_attr "type" "alu")
6257    (set_attr "use_carry" "1")
6258    (set_attr "mode" "<MODE>")])
6260 ;; Overflow setting add and subtract instructions
6262 (define_insn "*add<mode>3_cconly_overflow"
6263   [(set (reg:CCC FLAGS_REG)
6264         (compare:CCC
6265           (plus:SWI
6266             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6267             (match_operand:SWI 2 "<general_operand>" "<g>"))
6268           (match_dup 1)))
6269    (clobber (match_scratch:SWI 0 "=<r>"))]
6270   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6271   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6272   [(set_attr "type" "alu")
6273    (set_attr "mode" "<MODE>")])
6275 (define_insn "*sub<mode>3_cconly_overflow"
6276   [(set (reg:CCC FLAGS_REG)
6277         (compare:CCC
6278           (minus:SWI
6279             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6280             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6281           (match_dup 0)))]
6282   ""
6283   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6284   [(set_attr "type" "icmp")
6285    (set_attr "mode" "<MODE>")])
6287 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6288   [(set (reg:CCC FLAGS_REG)
6289         (compare:CCC
6290             (plusminus:SWI
6291                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6292                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6293             (match_dup 1)))
6294    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6295         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6296   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6297   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6298   [(set_attr "type" "alu")
6299    (set_attr "mode" "<MODE>")])
6301 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6302   [(set (reg:CCC FLAGS_REG)
6303         (compare:CCC
6304           (plusminus:SI
6305             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6306             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6307           (match_dup 1)))
6308    (set (match_operand:DI 0 "register_operand" "=r")
6309         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6310   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6311   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6312   [(set_attr "type" "alu")
6313    (set_attr "mode" "SI")])
6315 ;; The patterns that match these are at the end of this file.
6317 (define_expand "<plusminus_insn>xf3"
6318   [(set (match_operand:XF 0 "register_operand")
6319         (plusminus:XF
6320           (match_operand:XF 1 "register_operand")
6321           (match_operand:XF 2 "register_operand")))]
6322   "TARGET_80387")
6324 (define_expand "<plusminus_insn><mode>3"
6325   [(set (match_operand:MODEF 0 "register_operand")
6326         (plusminus:MODEF
6327           (match_operand:MODEF 1 "register_operand")
6328           (match_operand:MODEF 2 "nonimmediate_operand")))]
6329   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6330     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6332 ;; Multiply instructions
6334 (define_expand "mul<mode>3"
6335   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6336                    (mult:SWIM248
6337                      (match_operand:SWIM248 1 "register_operand")
6338                      (match_operand:SWIM248 2 "<general_operand>")))
6339               (clobber (reg:CC FLAGS_REG))])])
6341 (define_expand "mulqi3"
6342   [(parallel [(set (match_operand:QI 0 "register_operand")
6343                    (mult:QI
6344                      (match_operand:QI 1 "register_operand")
6345                      (match_operand:QI 2 "nonimmediate_operand")))
6346               (clobber (reg:CC FLAGS_REG))])]
6347   "TARGET_QIMODE_MATH")
6349 ;; On AMDFAM10
6350 ;; IMUL reg32/64, reg32/64, imm8        Direct
6351 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6352 ;; IMUL reg32/64, reg32/64, imm32       Direct
6353 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6354 ;; IMUL reg32/64, reg32/64              Direct
6355 ;; IMUL reg32/64, mem32/64              Direct
6357 ;; On BDVER1, all above IMULs use DirectPath
6359 (define_insn "*mul<mode>3_1"
6360   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6361         (mult:SWI48
6362           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6363           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6364    (clobber (reg:CC FLAGS_REG))]
6365   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6366   "@
6367    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6368    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6369    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6370   [(set_attr "type" "imul")
6371    (set_attr "prefix_0f" "0,0,1")
6372    (set (attr "athlon_decode")
6373         (cond [(eq_attr "cpu" "athlon")
6374                   (const_string "vector")
6375                (eq_attr "alternative" "1")
6376                   (const_string "vector")
6377                (and (eq_attr "alternative" "2")
6378                     (match_operand 1 "memory_operand"))
6379                   (const_string "vector")]
6380               (const_string "direct")))
6381    (set (attr "amdfam10_decode")
6382         (cond [(and (eq_attr "alternative" "0,1")
6383                     (match_operand 1 "memory_operand"))
6384                   (const_string "vector")]
6385               (const_string "direct")))
6386    (set_attr "bdver1_decode" "direct")
6387    (set_attr "mode" "<MODE>")])
6389 (define_insn "*mulsi3_1_zext"
6390   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6391         (zero_extend:DI
6392           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6393                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6394    (clobber (reg:CC FLAGS_REG))]
6395   "TARGET_64BIT
6396    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6397   "@
6398    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6399    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6400    imul{l}\t{%2, %k0|%k0, %2}"
6401   [(set_attr "type" "imul")
6402    (set_attr "prefix_0f" "0,0,1")
6403    (set (attr "athlon_decode")
6404         (cond [(eq_attr "cpu" "athlon")
6405                   (const_string "vector")
6406                (eq_attr "alternative" "1")
6407                   (const_string "vector")
6408                (and (eq_attr "alternative" "2")
6409                     (match_operand 1 "memory_operand"))
6410                   (const_string "vector")]
6411               (const_string "direct")))
6412    (set (attr "amdfam10_decode")
6413         (cond [(and (eq_attr "alternative" "0,1")
6414                     (match_operand 1 "memory_operand"))
6415                   (const_string "vector")]
6416               (const_string "direct")))
6417    (set_attr "bdver1_decode" "direct")
6418    (set_attr "mode" "SI")])
6420 ;; On AMDFAM10
6421 ;; IMUL reg16, reg16, imm8      VectorPath
6422 ;; IMUL reg16, mem16, imm8      VectorPath
6423 ;; IMUL reg16, reg16, imm16     VectorPath
6424 ;; IMUL reg16, mem16, imm16     VectorPath
6425 ;; IMUL reg16, reg16            Direct
6426 ;; IMUL reg16, mem16            Direct
6428 ;; On BDVER1, all HI MULs use DoublePath
6430 (define_insn "*mulhi3_1"
6431   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6432         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6433                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6434    (clobber (reg:CC FLAGS_REG))]
6435   "TARGET_HIMODE_MATH
6436    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6437   "@
6438    imul{w}\t{%2, %1, %0|%0, %1, %2}
6439    imul{w}\t{%2, %1, %0|%0, %1, %2}
6440    imul{w}\t{%2, %0|%0, %2}"
6441   [(set_attr "type" "imul")
6442    (set_attr "prefix_0f" "0,0,1")
6443    (set (attr "athlon_decode")
6444         (cond [(eq_attr "cpu" "athlon")
6445                   (const_string "vector")
6446                (eq_attr "alternative" "1,2")
6447                   (const_string "vector")]
6448               (const_string "direct")))
6449    (set (attr "amdfam10_decode")
6450         (cond [(eq_attr "alternative" "0,1")
6451                   (const_string "vector")]
6452               (const_string "direct")))
6453    (set_attr "bdver1_decode" "double")
6454    (set_attr "mode" "HI")])
6456 ;;On AMDFAM10 and BDVER1
6457 ;; MUL reg8     Direct
6458 ;; MUL mem8     Direct
6460 (define_insn "*mulqi3_1"
6461   [(set (match_operand:QI 0 "register_operand" "=a")
6462         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6463                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6464    (clobber (reg:CC FLAGS_REG))]
6465   "TARGET_QIMODE_MATH
6466    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6467   "mul{b}\t%2"
6468   [(set_attr "type" "imul")
6469    (set_attr "length_immediate" "0")
6470    (set (attr "athlon_decode")
6471      (if_then_else (eq_attr "cpu" "athlon")
6472         (const_string "vector")
6473         (const_string "direct")))
6474    (set_attr "amdfam10_decode" "direct")
6475    (set_attr "bdver1_decode" "direct")
6476    (set_attr "mode" "QI")])
6478 (define_expand "<u>mul<mode><dwi>3"
6479   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6480                    (mult:<DWI>
6481                      (any_extend:<DWI>
6482                        (match_operand:DWIH 1 "nonimmediate_operand"))
6483                      (any_extend:<DWI>
6484                        (match_operand:DWIH 2 "register_operand"))))
6485               (clobber (reg:CC FLAGS_REG))])])
6487 (define_expand "<u>mulqihi3"
6488   [(parallel [(set (match_operand:HI 0 "register_operand")
6489                    (mult:HI
6490                      (any_extend:HI
6491                        (match_operand:QI 1 "nonimmediate_operand"))
6492                      (any_extend:HI
6493                        (match_operand:QI 2 "register_operand"))))
6494               (clobber (reg:CC FLAGS_REG))])]
6495   "TARGET_QIMODE_MATH")
6497 (define_insn "*bmi2_umulditi3_1"
6498   [(set (match_operand:DI 0 "register_operand" "=r")
6499         (mult:DI
6500           (match_operand:DI 2 "nonimmediate_operand" "%d")
6501           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6502    (set (match_operand:DI 1 "register_operand" "=r")
6503         (truncate:DI
6504           (lshiftrt:TI
6505             (mult:TI (zero_extend:TI (match_dup 2))
6506                      (zero_extend:TI (match_dup 3)))
6507             (const_int 64))))]
6508   "TARGET_64BIT && TARGET_BMI2
6509    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6510   "mulx\t{%3, %0, %1|%1, %0, %3}"
6511   [(set_attr "type" "imulx")
6512    (set_attr "prefix" "vex")
6513    (set_attr "mode" "DI")])
6515 (define_insn "*bmi2_umulsidi3_1"
6516   [(set (match_operand:SI 0 "register_operand" "=r")
6517         (mult:SI
6518           (match_operand:SI 2 "nonimmediate_operand" "%d")
6519           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6520    (set (match_operand:SI 1 "register_operand" "=r")
6521         (truncate:SI
6522           (lshiftrt:DI
6523             (mult:DI (zero_extend:DI (match_dup 2))
6524                      (zero_extend:DI (match_dup 3)))
6525             (const_int 32))))]
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" "SI")])
6533 (define_insn "*umul<mode><dwi>3_1"
6534   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6535         (mult:<DWI>
6536           (zero_extend:<DWI>
6537             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6538           (zero_extend:<DWI>
6539             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6540    (clobber (reg:CC FLAGS_REG))]
6541   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6542   "@
6543    #
6544    mul{<imodesuffix>}\t%2"
6545   [(set_attr "isa" "bmi2,*")
6546    (set_attr "type" "imulx,imul")
6547    (set_attr "length_immediate" "*,0")
6548    (set (attr "athlon_decode")
6549         (cond [(eq_attr "alternative" "1")
6550                  (if_then_else (eq_attr "cpu" "athlon")
6551                    (const_string "vector")
6552                    (const_string "double"))]
6553               (const_string "*")))
6554    (set_attr "amdfam10_decode" "*,double")
6555    (set_attr "bdver1_decode" "*,direct")
6556    (set_attr "prefix" "vex,orig")
6557    (set_attr "mode" "<MODE>")])
6559 ;; Convert mul to the mulx pattern to avoid flags dependency.
6560 (define_split
6561  [(set (match_operand:<DWI> 0 "register_operand")
6562        (mult:<DWI>
6563          (zero_extend:<DWI>
6564            (match_operand:DWIH 1 "register_operand"))
6565          (zero_extend:<DWI>
6566            (match_operand:DWIH 2 "nonimmediate_operand"))))
6567   (clobber (reg:CC FLAGS_REG))]
6568  "TARGET_BMI2 && reload_completed
6569   && true_regnum (operands[1]) == DX_REG"
6570   [(parallel [(set (match_dup 3)
6571                    (mult:DWIH (match_dup 1) (match_dup 2)))
6572               (set (match_dup 4)
6573                    (truncate:DWIH
6574                      (lshiftrt:<DWI>
6575                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6576                                    (zero_extend:<DWI> (match_dup 2)))
6577                        (match_dup 5))))])]
6579   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6581   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6584 (define_insn "*mul<mode><dwi>3_1"
6585   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6586         (mult:<DWI>
6587           (sign_extend:<DWI>
6588             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6589           (sign_extend:<DWI>
6590             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6591    (clobber (reg:CC FLAGS_REG))]
6592   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6593   "imul{<imodesuffix>}\t%2"
6594   [(set_attr "type" "imul")
6595    (set_attr "length_immediate" "0")
6596    (set (attr "athlon_decode")
6597      (if_then_else (eq_attr "cpu" "athlon")
6598         (const_string "vector")
6599         (const_string "double")))
6600    (set_attr "amdfam10_decode" "double")
6601    (set_attr "bdver1_decode" "direct")
6602    (set_attr "mode" "<MODE>")])
6604 (define_insn "*<u>mulqihi3_1"
6605   [(set (match_operand:HI 0 "register_operand" "=a")
6606         (mult:HI
6607           (any_extend:HI
6608             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6609           (any_extend:HI
6610             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "TARGET_QIMODE_MATH
6613    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6614   "<sgnprefix>mul{b}\t%2"
6615   [(set_attr "type" "imul")
6616    (set_attr "length_immediate" "0")
6617    (set (attr "athlon_decode")
6618      (if_then_else (eq_attr "cpu" "athlon")
6619         (const_string "vector")
6620         (const_string "direct")))
6621    (set_attr "amdfam10_decode" "direct")
6622    (set_attr "bdver1_decode" "direct")
6623    (set_attr "mode" "QI")])
6625 (define_expand "<s>mul<mode>3_highpart"
6626   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6627                    (truncate:SWI48
6628                      (lshiftrt:<DWI>
6629                        (mult:<DWI>
6630                          (any_extend:<DWI>
6631                            (match_operand:SWI48 1 "nonimmediate_operand"))
6632                          (any_extend:<DWI>
6633                            (match_operand:SWI48 2 "register_operand")))
6634                        (match_dup 4))))
6635               (clobber (match_scratch:SWI48 3))
6636               (clobber (reg:CC FLAGS_REG))])]
6637   ""
6638   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6640 (define_insn "*<s>muldi3_highpart_1"
6641   [(set (match_operand:DI 0 "register_operand" "=d")
6642         (truncate:DI
6643           (lshiftrt:TI
6644             (mult:TI
6645               (any_extend:TI
6646                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6647               (any_extend:TI
6648                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6649             (const_int 64))))
6650    (clobber (match_scratch:DI 3 "=1"))
6651    (clobber (reg:CC FLAGS_REG))]
6652   "TARGET_64BIT
6653    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6654   "<sgnprefix>mul{q}\t%2"
6655   [(set_attr "type" "imul")
6656    (set_attr "length_immediate" "0")
6657    (set (attr "athlon_decode")
6658      (if_then_else (eq_attr "cpu" "athlon")
6659         (const_string "vector")
6660         (const_string "double")))
6661    (set_attr "amdfam10_decode" "double")
6662    (set_attr "bdver1_decode" "direct")
6663    (set_attr "mode" "DI")])
6665 (define_insn "*<s>mulsi3_highpart_1"
6666   [(set (match_operand:SI 0 "register_operand" "=d")
6667         (truncate:SI
6668           (lshiftrt:DI
6669             (mult:DI
6670               (any_extend:DI
6671                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6672               (any_extend:DI
6673                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6674             (const_int 32))))
6675    (clobber (match_scratch:SI 3 "=1"))
6676    (clobber (reg:CC FLAGS_REG))]
6677   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6678   "<sgnprefix>mul{l}\t%2"
6679   [(set_attr "type" "imul")
6680    (set_attr "length_immediate" "0")
6681    (set (attr "athlon_decode")
6682      (if_then_else (eq_attr "cpu" "athlon")
6683         (const_string "vector")
6684         (const_string "double")))
6685    (set_attr "amdfam10_decode" "double")
6686    (set_attr "bdver1_decode" "direct")
6687    (set_attr "mode" "SI")])
6689 (define_insn "*<s>mulsi3_highpart_zext"
6690   [(set (match_operand:DI 0 "register_operand" "=d")
6691         (zero_extend:DI (truncate:SI
6692           (lshiftrt:DI
6693             (mult:DI (any_extend:DI
6694                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6695                      (any_extend:DI
6696                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6697             (const_int 32)))))
6698    (clobber (match_scratch:SI 3 "=1"))
6699    (clobber (reg:CC FLAGS_REG))]
6700   "TARGET_64BIT
6701    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6702   "<sgnprefix>mul{l}\t%2"
6703   [(set_attr "type" "imul")
6704    (set_attr "length_immediate" "0")
6705    (set (attr "athlon_decode")
6706      (if_then_else (eq_attr "cpu" "athlon")
6707         (const_string "vector")
6708         (const_string "double")))
6709    (set_attr "amdfam10_decode" "double")
6710    (set_attr "bdver1_decode" "direct")
6711    (set_attr "mode" "SI")])
6713 ;; The patterns that match these are at the end of this file.
6715 (define_expand "mulxf3"
6716   [(set (match_operand:XF 0 "register_operand")
6717         (mult:XF (match_operand:XF 1 "register_operand")
6718                  (match_operand:XF 2 "register_operand")))]
6719   "TARGET_80387")
6721 (define_expand "mul<mode>3"
6722   [(set (match_operand:MODEF 0 "register_operand")
6723         (mult:MODEF (match_operand:MODEF 1 "register_operand")
6724                     (match_operand:MODEF 2 "nonimmediate_operand")))]
6725   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6726     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6728 ;; Divide instructions
6730 ;; The patterns that match these are at the end of this file.
6732 (define_expand "divxf3"
6733   [(set (match_operand:XF 0 "register_operand")
6734         (div:XF (match_operand:XF 1 "register_operand")
6735                 (match_operand:XF 2 "register_operand")))]
6736   "TARGET_80387")
6738 (define_expand "divdf3"
6739   [(set (match_operand:DF 0 "register_operand")
6740         (div:DF (match_operand:DF 1 "register_operand")
6741                 (match_operand:DF 2 "nonimmediate_operand")))]
6742    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6743     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6745 (define_expand "divsf3"
6746   [(set (match_operand:SF 0 "register_operand")
6747         (div:SF (match_operand:SF 1 "register_operand")
6748                 (match_operand:SF 2 "nonimmediate_operand")))]
6749   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6750     || TARGET_SSE_MATH"
6752   if (TARGET_SSE_MATH
6753       && TARGET_RECIP_DIV
6754       && optimize_insn_for_speed_p ()
6755       && flag_finite_math_only && !flag_trapping_math
6756       && flag_unsafe_math_optimizations)
6757     {
6758       ix86_emit_swdivsf (operands[0], operands[1],
6759                          operands[2], SFmode);
6760       DONE;
6761     }
6764 ;; Divmod instructions.
6766 (define_expand "divmod<mode>4"
6767   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6768                    (div:SWIM248
6769                      (match_operand:SWIM248 1 "register_operand")
6770                      (match_operand:SWIM248 2 "nonimmediate_operand")))
6771               (set (match_operand:SWIM248 3 "register_operand")
6772                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
6773               (clobber (reg:CC FLAGS_REG))])])
6775 ;; Split with 8bit unsigned divide:
6776 ;;      if (dividend an divisor are in [0-255])
6777 ;;         use 8bit unsigned integer divide
6778 ;;       else
6779 ;;         use original integer divide
6780 (define_split
6781   [(set (match_operand:SWI48 0 "register_operand")
6782         (div:SWI48 (match_operand:SWI48 2 "register_operand")
6783                     (match_operand:SWI48 3 "nonimmediate_operand")))
6784    (set (match_operand:SWI48 1 "register_operand")
6785         (mod:SWI48 (match_dup 2) (match_dup 3)))
6786    (clobber (reg:CC FLAGS_REG))]
6787   "TARGET_USE_8BIT_IDIV
6788    && TARGET_QIMODE_MATH
6789    && can_create_pseudo_p ()
6790    && !optimize_insn_for_size_p ()"
6791   [(const_int 0)]
6792   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6794 (define_insn_and_split "divmod<mode>4_1"
6795   [(set (match_operand:SWI48 0 "register_operand" "=a")
6796         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6797                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6798    (set (match_operand:SWI48 1 "register_operand" "=&d")
6799         (mod:SWI48 (match_dup 2) (match_dup 3)))
6800    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6801    (clobber (reg:CC FLAGS_REG))]
6802   ""
6803   "#"
6804   "reload_completed"
6805   [(parallel [(set (match_dup 1)
6806                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6807               (clobber (reg:CC FLAGS_REG))])
6808    (parallel [(set (match_dup 0)
6809                    (div:SWI48 (match_dup 2) (match_dup 3)))
6810               (set (match_dup 1)
6811                    (mod:SWI48 (match_dup 2) (match_dup 3)))
6812               (use (match_dup 1))
6813               (clobber (reg:CC FLAGS_REG))])]
6815   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6817   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6818     operands[4] = operands[2];
6819   else
6820     {
6821       /* Avoid use of cltd in favor of a mov+shift.  */
6822       emit_move_insn (operands[1], operands[2]);
6823       operands[4] = operands[1];
6824     }
6826   [(set_attr "type" "multi")
6827    (set_attr "mode" "<MODE>")])
6829 (define_insn_and_split "*divmod<mode>4"
6830   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6831         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6832                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6833    (set (match_operand:SWIM248 1 "register_operand" "=&d")
6834         (mod:SWIM248 (match_dup 2) (match_dup 3)))
6835    (clobber (reg:CC FLAGS_REG))]
6836   ""
6837   "#"
6838   "reload_completed"
6839   [(parallel [(set (match_dup 1)
6840                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6841               (clobber (reg:CC FLAGS_REG))])
6842    (parallel [(set (match_dup 0)
6843                    (div:SWIM248 (match_dup 2) (match_dup 3)))
6844               (set (match_dup 1)
6845                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
6846               (use (match_dup 1))
6847               (clobber (reg:CC FLAGS_REG))])]
6849   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6851   if (<MODE>mode != HImode
6852       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6853     operands[4] = operands[2];
6854   else
6855     {
6856       /* Avoid use of cltd in favor of a mov+shift.  */
6857       emit_move_insn (operands[1], operands[2]);
6858       operands[4] = operands[1];
6859     }
6861   [(set_attr "type" "multi")
6862    (set_attr "mode" "<MODE>")])
6864 (define_insn "*divmod<mode>4_noext"
6865   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6866         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6867                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6868    (set (match_operand:SWIM248 1 "register_operand" "=d")
6869         (mod:SWIM248 (match_dup 2) (match_dup 3)))
6870    (use (match_operand:SWIM248 4 "register_operand" "1"))
6871    (clobber (reg:CC FLAGS_REG))]
6872   ""
6873   "idiv{<imodesuffix>}\t%3"
6874   [(set_attr "type" "idiv")
6875    (set_attr "mode" "<MODE>")])
6877 (define_expand "divmodqi4"
6878   [(parallel [(set (match_operand:QI 0 "register_operand")
6879                    (div:QI
6880                      (match_operand:QI 1 "register_operand")
6881                      (match_operand:QI 2 "nonimmediate_operand")))
6882               (set (match_operand:QI 3 "register_operand")
6883                    (mod:QI (match_dup 1) (match_dup 2)))
6884               (clobber (reg:CC FLAGS_REG))])]
6885   "TARGET_QIMODE_MATH"
6887   rtx div, mod, insn;
6888   rtx tmp0, tmp1;
6889   
6890   tmp0 = gen_reg_rtx (HImode);
6891   tmp1 = gen_reg_rtx (HImode);
6893   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
6894      in AX.  */
6895   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
6896   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
6898   /* Extract remainder from AH.  */
6899   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
6900   insn = emit_move_insn (operands[3], tmp1);
6902   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
6903   set_unique_reg_note (insn, REG_EQUAL, mod);
6905   /* Extract quotient from AL.  */
6906   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
6908   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
6909   set_unique_reg_note (insn, REG_EQUAL, div);
6911   DONE;
6914 ;; Divide AX by r/m8, with result stored in
6915 ;; AL <- Quotient
6916 ;; AH <- Remainder
6917 ;; Change div/mod to HImode and extend the second argument to HImode
6918 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
6919 ;; combine may fail.
6920 (define_insn "divmodhiqi3"
6921   [(set (match_operand:HI 0 "register_operand" "=a")
6922         (ior:HI
6923           (ashift:HI
6924             (zero_extend:HI
6925               (truncate:QI
6926                 (mod:HI (match_operand:HI 1 "register_operand" "0")
6927                         (sign_extend:HI
6928                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
6929             (const_int 8))
6930           (zero_extend:HI
6931             (truncate:QI
6932               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
6933    (clobber (reg:CC FLAGS_REG))]
6934   "TARGET_QIMODE_MATH"
6935   "idiv{b}\t%2"
6936   [(set_attr "type" "idiv")
6937    (set_attr "mode" "QI")])
6939 (define_expand "udivmod<mode>4"
6940   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6941                    (udiv:SWIM248
6942                      (match_operand:SWIM248 1 "register_operand")
6943                      (match_operand:SWIM248 2 "nonimmediate_operand")))
6944               (set (match_operand:SWIM248 3 "register_operand")
6945                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
6946               (clobber (reg:CC FLAGS_REG))])])
6948 ;; Split with 8bit unsigned divide:
6949 ;;      if (dividend an divisor are in [0-255])
6950 ;;         use 8bit unsigned integer divide
6951 ;;       else
6952 ;;         use original integer divide
6953 (define_split
6954   [(set (match_operand:SWI48 0 "register_operand")
6955         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
6956                     (match_operand:SWI48 3 "nonimmediate_operand")))
6957    (set (match_operand:SWI48 1 "register_operand")
6958         (umod:SWI48 (match_dup 2) (match_dup 3)))
6959    (clobber (reg:CC FLAGS_REG))]
6960   "TARGET_USE_8BIT_IDIV
6961    && TARGET_QIMODE_MATH
6962    && can_create_pseudo_p ()
6963    && !optimize_insn_for_size_p ()"
6964   [(const_int 0)]
6965   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
6967 (define_insn_and_split "udivmod<mode>4_1"
6968   [(set (match_operand:SWI48 0 "register_operand" "=a")
6969         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6970                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6971    (set (match_operand:SWI48 1 "register_operand" "=&d")
6972         (umod:SWI48 (match_dup 2) (match_dup 3)))
6973    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6974    (clobber (reg:CC FLAGS_REG))]
6975   ""
6976   "#"
6977   "reload_completed"
6978   [(set (match_dup 1) (const_int 0))
6979    (parallel [(set (match_dup 0)
6980                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
6981               (set (match_dup 1)
6982                    (umod:SWI48 (match_dup 2) (match_dup 3)))
6983               (use (match_dup 1))
6984               (clobber (reg:CC FLAGS_REG))])]
6985   ""
6986   [(set_attr "type" "multi")
6987    (set_attr "mode" "<MODE>")])
6989 (define_insn_and_split "*udivmod<mode>4"
6990   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6991         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6992                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6993    (set (match_operand:SWIM248 1 "register_operand" "=&d")
6994         (umod:SWIM248 (match_dup 2) (match_dup 3)))
6995    (clobber (reg:CC FLAGS_REG))]
6996   ""
6997   "#"
6998   "reload_completed"
6999   [(set (match_dup 1) (const_int 0))
7000    (parallel [(set (match_dup 0)
7001                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7002               (set (match_dup 1)
7003                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7004               (use (match_dup 1))
7005               (clobber (reg:CC FLAGS_REG))])]
7006   ""
7007   [(set_attr "type" "multi")
7008    (set_attr "mode" "<MODE>")])
7010 (define_insn "*udivmod<mode>4_noext"
7011   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7012         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7013                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7014    (set (match_operand:SWIM248 1 "register_operand" "=d")
7015         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7016    (use (match_operand:SWIM248 4 "register_operand" "1"))
7017    (clobber (reg:CC FLAGS_REG))]
7018   ""
7019   "div{<imodesuffix>}\t%3"
7020   [(set_attr "type" "idiv")
7021    (set_attr "mode" "<MODE>")])
7023 (define_expand "udivmodqi4"
7024   [(parallel [(set (match_operand:QI 0 "register_operand")
7025                    (udiv:QI
7026                      (match_operand:QI 1 "register_operand")
7027                      (match_operand:QI 2 "nonimmediate_operand")))
7028               (set (match_operand:QI 3 "register_operand")
7029                    (umod:QI (match_dup 1) (match_dup 2)))
7030               (clobber (reg:CC FLAGS_REG))])]
7031   "TARGET_QIMODE_MATH"
7033   rtx div, mod, insn;
7034   rtx tmp0, tmp1;
7035   
7036   tmp0 = gen_reg_rtx (HImode);
7037   tmp1 = gen_reg_rtx (HImode);
7039   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7040      in AX.  */
7041   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7042   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7044   /* Extract remainder from AH.  */
7045   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7046   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7047   insn = emit_move_insn (operands[3], tmp1);
7049   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7050   set_unique_reg_note (insn, REG_EQUAL, mod);
7052   /* Extract quotient from AL.  */
7053   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7055   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7056   set_unique_reg_note (insn, REG_EQUAL, div);
7058   DONE;
7061 (define_insn "udivmodhiqi3"
7062   [(set (match_operand:HI 0 "register_operand" "=a")
7063         (ior:HI
7064           (ashift:HI
7065             (zero_extend:HI
7066               (truncate:QI
7067                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7068                         (zero_extend:HI
7069                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7070             (const_int 8))
7071           (zero_extend:HI
7072             (truncate:QI
7073               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7074    (clobber (reg:CC FLAGS_REG))]
7075   "TARGET_QIMODE_MATH"
7076   "div{b}\t%2"
7077   [(set_attr "type" "idiv")
7078    (set_attr "mode" "QI")])
7080 ;; We cannot use div/idiv for double division, because it causes
7081 ;; "division by zero" on the overflow and that's not what we expect
7082 ;; from truncate.  Because true (non truncating) double division is
7083 ;; never generated, we can't create this insn anyway.
7085 ;(define_insn ""
7086 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7087 ;       (truncate:SI
7088 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7089 ;                  (zero_extend:DI
7090 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7091 ;   (set (match_operand:SI 3 "register_operand" "=d")
7092 ;       (truncate:SI
7093 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7094 ;   (clobber (reg:CC FLAGS_REG))]
7095 ;  ""
7096 ;  "div{l}\t{%2, %0|%0, %2}"
7097 ;  [(set_attr "type" "idiv")])
7099 ;;- Logical AND instructions
7101 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7102 ;; Note that this excludes ah.
7104 (define_expand "testsi_ccno_1"
7105   [(set (reg:CCNO FLAGS_REG)
7106         (compare:CCNO
7107           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7108                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7109           (const_int 0)))])
7111 (define_expand "testqi_ccz_1"
7112   [(set (reg:CCZ FLAGS_REG)
7113         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7114                              (match_operand:QI 1 "nonmemory_operand"))
7115                  (const_int 0)))])
7117 (define_expand "testdi_ccno_1"
7118   [(set (reg:CCNO FLAGS_REG)
7119         (compare:CCNO
7120           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7121                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7122           (const_int 0)))]
7123   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7125 (define_insn "*testdi_1"
7126   [(set (reg FLAGS_REG)
7127         (compare
7128          (and:DI
7129           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7130           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7131          (const_int 0)))]
7132   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7133    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7134   "@
7135    test{l}\t{%k1, %k0|%k0, %k1}
7136    test{l}\t{%k1, %k0|%k0, %k1}
7137    test{q}\t{%1, %0|%0, %1}
7138    test{q}\t{%1, %0|%0, %1}
7139    test{q}\t{%1, %0|%0, %1}"
7140   [(set_attr "type" "test")
7141    (set_attr "modrm" "0,1,0,1,1")
7142    (set_attr "mode" "SI,SI,DI,DI,DI")])
7144 (define_insn "*testqi_1_maybe_si"
7145   [(set (reg FLAGS_REG)
7146         (compare
7147           (and:QI
7148             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7149             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7150           (const_int 0)))]
7151    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7152     && ix86_match_ccmode (insn,
7153                          CONST_INT_P (operands[1])
7154                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7156   if (which_alternative == 3)
7157     {
7158       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7159         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7160       return "test{l}\t{%1, %k0|%k0, %1}";
7161     }
7162   return "test{b}\t{%1, %0|%0, %1}";
7164   [(set_attr "type" "test")
7165    (set_attr "modrm" "0,1,1,1")
7166    (set_attr "mode" "QI,QI,QI,SI")
7167    (set_attr "pent_pair" "uv,np,uv,np")])
7169 (define_insn "*test<mode>_1"
7170   [(set (reg FLAGS_REG)
7171         (compare
7172          (and:SWI124
7173           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7174           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7175          (const_int 0)))]
7176   "ix86_match_ccmode (insn, CCNOmode)
7177    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7178   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7179   [(set_attr "type" "test")
7180    (set_attr "modrm" "0,1,1")
7181    (set_attr "mode" "<MODE>")
7182    (set_attr "pent_pair" "uv,np,uv")])
7184 (define_expand "testqi_ext_ccno_0"
7185   [(set (reg:CCNO FLAGS_REG)
7186         (compare:CCNO
7187           (and:SI
7188             (zero_extract:SI
7189               (match_operand 0 "ext_register_operand")
7190               (const_int 8)
7191               (const_int 8))
7192             (match_operand 1 "const_int_operand"))
7193           (const_int 0)))])
7195 (define_insn "*testqi_ext_0"
7196   [(set (reg FLAGS_REG)
7197         (compare
7198           (and:SI
7199             (zero_extract:SI
7200               (match_operand 0 "ext_register_operand" "Q")
7201               (const_int 8)
7202               (const_int 8))
7203             (match_operand 1 "const_int_operand" "n"))
7204           (const_int 0)))]
7205   "ix86_match_ccmode (insn, CCNOmode)"
7206   "test{b}\t{%1, %h0|%h0, %1}"
7207   [(set_attr "type" "test")
7208    (set_attr "mode" "QI")
7209    (set_attr "length_immediate" "1")
7210    (set_attr "modrm" "1")
7211    (set_attr "pent_pair" "np")])
7213 (define_insn "*testqi_ext_1_rex64"
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             (zero_extend:SI
7222               (match_operand:QI 1 "register_operand" "Q")))
7223           (const_int 0)))]
7224   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7225   "test{b}\t{%1, %h0|%h0, %1}"
7226   [(set_attr "type" "test")
7227    (set_attr "mode" "QI")])
7229 (define_insn "*testqi_ext_1"
7230   [(set (reg FLAGS_REG)
7231         (compare
7232           (and:SI
7233             (zero_extract:SI
7234               (match_operand 0 "ext_register_operand" "Q")
7235               (const_int 8)
7236               (const_int 8))
7237             (zero_extend:SI
7238               (match_operand:QI 1 "general_operand" "Qm")))
7239           (const_int 0)))]
7240   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7241   "test{b}\t{%1, %h0|%h0, %1}"
7242   [(set_attr "type" "test")
7243    (set_attr "mode" "QI")])
7245 (define_insn "*testqi_ext_2"
7246   [(set (reg FLAGS_REG)
7247         (compare
7248           (and:SI
7249             (zero_extract:SI
7250               (match_operand 0 "ext_register_operand" "Q")
7251               (const_int 8)
7252               (const_int 8))
7253             (zero_extract:SI
7254               (match_operand 1 "ext_register_operand" "Q")
7255               (const_int 8)
7256               (const_int 8)))
7257           (const_int 0)))]
7258   "ix86_match_ccmode (insn, CCNOmode)"
7259   "test{b}\t{%h1, %h0|%h0, %h1}"
7260   [(set_attr "type" "test")
7261    (set_attr "mode" "QI")])
7263 (define_insn "*testqi_ext_3_rex64"
7264   [(set (reg FLAGS_REG)
7265         (compare (zero_extract:DI
7266                    (match_operand 0 "nonimmediate_operand" "rm")
7267                    (match_operand:DI 1 "const_int_operand")
7268                    (match_operand:DI 2 "const_int_operand"))
7269                  (const_int 0)))]
7270   "TARGET_64BIT
7271    && ix86_match_ccmode (insn, CCNOmode)
7272    && INTVAL (operands[1]) > 0
7273    && INTVAL (operands[2]) >= 0
7274    /* Ensure that resulting mask is zero or sign extended operand.  */
7275    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7276        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7277            && INTVAL (operands[1]) > 32))
7278    && (GET_MODE (operands[0]) == SImode
7279        || GET_MODE (operands[0]) == DImode
7280        || GET_MODE (operands[0]) == HImode
7281        || GET_MODE (operands[0]) == QImode)"
7282   "#")
7284 ;; Combine likes to form bit extractions for some tests.  Humor it.
7285 (define_insn "*testqi_ext_3"
7286   [(set (reg FLAGS_REG)
7287         (compare (zero_extract:SI
7288                    (match_operand 0 "nonimmediate_operand" "rm")
7289                    (match_operand:SI 1 "const_int_operand")
7290                    (match_operand:SI 2 "const_int_operand"))
7291                  (const_int 0)))]
7292   "ix86_match_ccmode (insn, CCNOmode)
7293    && INTVAL (operands[1]) > 0
7294    && INTVAL (operands[2]) >= 0
7295    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7296    && (GET_MODE (operands[0]) == SImode
7297        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7298        || GET_MODE (operands[0]) == HImode
7299        || GET_MODE (operands[0]) == QImode)"
7300   "#")
7302 (define_split
7303   [(set (match_operand 0 "flags_reg_operand")
7304         (match_operator 1 "compare_operator"
7305           [(zero_extract
7306              (match_operand 2 "nonimmediate_operand")
7307              (match_operand 3 "const_int_operand")
7308              (match_operand 4 "const_int_operand"))
7309            (const_int 0)]))]
7310   "ix86_match_ccmode (insn, CCNOmode)"
7311   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7313   rtx val = operands[2];
7314   HOST_WIDE_INT len = INTVAL (operands[3]);
7315   HOST_WIDE_INT pos = INTVAL (operands[4]);
7316   HOST_WIDE_INT mask;
7317   enum machine_mode mode, submode;
7319   mode = GET_MODE (val);
7320   if (MEM_P (val))
7321     {
7322       /* ??? Combine likes to put non-volatile mem extractions in QImode
7323          no matter the size of the test.  So find a mode that works.  */
7324       if (! MEM_VOLATILE_P (val))
7325         {
7326           mode = smallest_mode_for_size (pos + len, MODE_INT);
7327           val = adjust_address (val, mode, 0);
7328         }
7329     }
7330   else if (GET_CODE (val) == SUBREG
7331            && (submode = GET_MODE (SUBREG_REG (val)),
7332                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7333            && pos + len <= GET_MODE_BITSIZE (submode)
7334            && GET_MODE_CLASS (submode) == MODE_INT)
7335     {
7336       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7337       mode = submode;
7338       val = SUBREG_REG (val);
7339     }
7340   else if (mode == HImode && pos + len <= 8)
7341     {
7342       /* Small HImode tests can be converted to QImode.  */
7343       mode = QImode;
7344       val = gen_lowpart (QImode, val);
7345     }
7347   if (len == HOST_BITS_PER_WIDE_INT)
7348     mask = -1;
7349   else
7350     mask = ((HOST_WIDE_INT)1 << len) - 1;
7351   mask <<= pos;
7353   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7356 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7357 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7358 ;; this is relatively important trick.
7359 ;; Do the conversion only post-reload to avoid limiting of the register class
7360 ;; to QI regs.
7361 (define_split
7362   [(set (match_operand 0 "flags_reg_operand")
7363         (match_operator 1 "compare_operator"
7364           [(and (match_operand 2 "register_operand")
7365                 (match_operand 3 "const_int_operand"))
7366            (const_int 0)]))]
7367    "reload_completed
7368     && QI_REG_P (operands[2])
7369     && GET_MODE (operands[2]) != QImode
7370     && ((ix86_match_ccmode (insn, CCZmode)
7371          && !(INTVAL (operands[3]) & ~(255 << 8)))
7372         || (ix86_match_ccmode (insn, CCNOmode)
7373             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7374   [(set (match_dup 0)
7375         (match_op_dup 1
7376           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7377                    (match_dup 3))
7378            (const_int 0)]))]
7380   operands[2] = gen_lowpart (SImode, operands[2]);
7381   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7384 (define_split
7385   [(set (match_operand 0 "flags_reg_operand")
7386         (match_operator 1 "compare_operator"
7387           [(and (match_operand 2 "nonimmediate_operand")
7388                 (match_operand 3 "const_int_operand"))
7389            (const_int 0)]))]
7390    "reload_completed
7391     && GET_MODE (operands[2]) != QImode
7392     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7393     && ((ix86_match_ccmode (insn, CCZmode)
7394          && !(INTVAL (operands[3]) & ~255))
7395         || (ix86_match_ccmode (insn, CCNOmode)
7396             && !(INTVAL (operands[3]) & ~127)))"
7397   [(set (match_dup 0)
7398         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7399                          (const_int 0)]))]
7401   operands[2] = gen_lowpart (QImode, operands[2]);
7402   operands[3] = gen_lowpart (QImode, operands[3]);
7405 ;; %%% This used to optimize known byte-wide and operations to memory,
7406 ;; and sometimes to QImode registers.  If this is considered useful,
7407 ;; it should be done with splitters.
7409 (define_expand "and<mode>3"
7410   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7411         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7412                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7413   ""
7415   enum machine_mode mode = <MODE>mode;
7416   rtx (*insn) (rtx, rtx);
7418   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7419     {
7420       HOST_WIDE_INT ival = INTVAL (operands[2]);
7422       if (ival == (HOST_WIDE_INT) 0xffffffff)
7423         mode = SImode;
7424       else if (ival == 0xffff)
7425         mode = HImode;
7426       else if (ival == 0xff)
7427         mode = QImode;
7428       }
7430   if (mode == <MODE>mode)
7431     {
7432       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7433       DONE;
7434     }
7436   if (<MODE>mode == DImode)
7437     insn = (mode == SImode)
7438            ? gen_zero_extendsidi2
7439            : (mode == HImode)
7440            ? gen_zero_extendhidi2
7441            : gen_zero_extendqidi2;
7442   else if (<MODE>mode == SImode)
7443     insn = (mode == HImode)
7444            ? gen_zero_extendhisi2
7445            : gen_zero_extendqisi2;
7446   else if (<MODE>mode == HImode)
7447     insn = gen_zero_extendqihi2;
7448   else
7449     gcc_unreachable ();
7451   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7452   DONE;
7455 (define_insn "*anddi_1"
7456   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7457         (and:DI
7458          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7459          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7460    (clobber (reg:CC FLAGS_REG))]
7461   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7463   switch (get_attr_type (insn))
7464     {
7465     case TYPE_IMOVX:
7466       return "#";
7468     default:
7469       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7470       if (get_attr_mode (insn) == MODE_SI)
7471         return "and{l}\t{%k2, %k0|%k0, %k2}";
7472       else
7473         return "and{q}\t{%2, %0|%0, %2}";
7474     }
7476   [(set_attr "type" "alu,alu,alu,imovx")
7477    (set_attr "length_immediate" "*,*,*,0")
7478    (set (attr "prefix_rex")
7479      (if_then_else
7480        (and (eq_attr "type" "imovx")
7481             (and (match_test "INTVAL (operands[2]) == 0xff")
7482                  (match_operand 1 "ext_QIreg_operand")))
7483        (const_string "1")
7484        (const_string "*")))
7485    (set_attr "mode" "SI,DI,DI,SI")])
7487 (define_insn "*andsi_1"
7488   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7489         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7490                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7491    (clobber (reg:CC FLAGS_REG))]
7492   "ix86_binary_operator_ok (AND, SImode, operands)"
7494   switch (get_attr_type (insn))
7495     {
7496     case TYPE_IMOVX:
7497       return "#";
7499     default:
7500       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7501       return "and{l}\t{%2, %0|%0, %2}";
7502     }
7504   [(set_attr "type" "alu,alu,imovx")
7505    (set (attr "prefix_rex")
7506      (if_then_else
7507        (and (eq_attr "type" "imovx")
7508             (and (match_test "INTVAL (operands[2]) == 0xff")
7509                  (match_operand 1 "ext_QIreg_operand")))
7510        (const_string "1")
7511        (const_string "*")))
7512    (set_attr "length_immediate" "*,*,0")
7513    (set_attr "mode" "SI")])
7515 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7516 (define_insn "*andsi_1_zext"
7517   [(set (match_operand:DI 0 "register_operand" "=r")
7518         (zero_extend:DI
7519           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7520                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7521    (clobber (reg:CC FLAGS_REG))]
7522   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7523   "and{l}\t{%2, %k0|%k0, %2}"
7524   [(set_attr "type" "alu")
7525    (set_attr "mode" "SI")])
7527 (define_insn "*andhi_1"
7528   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7529         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7530                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7531    (clobber (reg:CC FLAGS_REG))]
7532   "ix86_binary_operator_ok (AND, HImode, operands)"
7534   switch (get_attr_type (insn))
7535     {
7536     case TYPE_IMOVX:
7537       return "#";
7539     default:
7540       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7541       return "and{w}\t{%2, %0|%0, %2}";
7542     }
7544   [(set_attr "type" "alu,alu,imovx")
7545    (set_attr "length_immediate" "*,*,0")
7546    (set (attr "prefix_rex")
7547      (if_then_else
7548        (and (eq_attr "type" "imovx")
7549             (match_operand 1 "ext_QIreg_operand"))
7550        (const_string "1")
7551        (const_string "*")))
7552    (set_attr "mode" "HI,HI,SI")])
7554 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7555 (define_insn "*andqi_1"
7556   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7557         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7558                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7559    (clobber (reg:CC FLAGS_REG))]
7560   "ix86_binary_operator_ok (AND, QImode, operands)"
7561   "@
7562    and{b}\t{%2, %0|%0, %2}
7563    and{b}\t{%2, %0|%0, %2}
7564    and{l}\t{%k2, %k0|%k0, %k2}"
7565   [(set_attr "type" "alu")
7566    (set_attr "mode" "QI,QI,SI")])
7568 (define_insn "*andqi_1_slp"
7569   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7570         (and:QI (match_dup 0)
7571                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7572    (clobber (reg:CC FLAGS_REG))]
7573   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7574    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7575   "and{b}\t{%1, %0|%0, %1}"
7576   [(set_attr "type" "alu1")
7577    (set_attr "mode" "QI")])
7579 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7580 (define_split
7581   [(set (match_operand:DI 0 "register_operand")
7582         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7583                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7584    (clobber (reg:CC FLAGS_REG))]
7585   "TARGET_64BIT"
7586   [(parallel [(set (match_dup 0)
7587                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7588               (clobber (reg:CC FLAGS_REG))])]
7589   "operands[2] = gen_lowpart (SImode, operands[2]);")
7591 (define_split
7592   [(set (match_operand:SWI248 0 "register_operand")
7593         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7594                     (match_operand:SWI248 2 "const_int_operand")))
7595    (clobber (reg:CC FLAGS_REG))]
7596   "reload_completed
7597    && true_regnum (operands[0]) != true_regnum (operands[1])"
7598   [(const_int 0)]
7600   HOST_WIDE_INT ival = INTVAL (operands[2]);
7601   enum machine_mode mode;
7602   rtx (*insn) (rtx, rtx);
7604   if (ival == (HOST_WIDE_INT) 0xffffffff)
7605     mode = SImode;
7606   else if (ival == 0xffff)
7607     mode = HImode;
7608   else
7609     {
7610       gcc_assert (ival == 0xff);
7611       mode = QImode;
7612     }
7614   if (<MODE>mode == DImode)
7615     insn = (mode == SImode)
7616            ? gen_zero_extendsidi2
7617            : (mode == HImode)
7618            ? gen_zero_extendhidi2
7619            : gen_zero_extendqidi2;
7620   else
7621     {
7622       if (<MODE>mode != SImode)
7623         /* Zero extend to SImode to avoid partial register stalls.  */
7624         operands[0] = gen_lowpart (SImode, operands[0]);
7626       insn = (mode == HImode)
7627              ? gen_zero_extendhisi2
7628              : gen_zero_extendqisi2;
7629     }
7630   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7631   DONE;
7634 (define_split
7635   [(set (match_operand 0 "register_operand")
7636         (and (match_dup 0)
7637              (const_int -65536)))
7638    (clobber (reg:CC FLAGS_REG))]
7639   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7640     || optimize_function_for_size_p (cfun)"
7641   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7642   "operands[1] = gen_lowpart (HImode, operands[0]);")
7644 (define_split
7645   [(set (match_operand 0 "ext_register_operand")
7646         (and (match_dup 0)
7647              (const_int -256)))
7648    (clobber (reg:CC FLAGS_REG))]
7649   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7650    && reload_completed"
7651   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7652   "operands[1] = gen_lowpart (QImode, operands[0]);")
7654 (define_split
7655   [(set (match_operand 0 "ext_register_operand")
7656         (and (match_dup 0)
7657              (const_int -65281)))
7658    (clobber (reg:CC FLAGS_REG))]
7659   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7660    && reload_completed"
7661   [(parallel [(set (zero_extract:SI (match_dup 0)
7662                                     (const_int 8)
7663                                     (const_int 8))
7664                    (xor:SI
7665                      (zero_extract:SI (match_dup 0)
7666                                       (const_int 8)
7667                                       (const_int 8))
7668                      (zero_extract:SI (match_dup 0)
7669                                       (const_int 8)
7670                                       (const_int 8))))
7671               (clobber (reg:CC FLAGS_REG))])]
7672   "operands[0] = gen_lowpart (SImode, operands[0]);")
7674 (define_insn "*anddi_2"
7675   [(set (reg FLAGS_REG)
7676         (compare
7677          (and:DI
7678           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7679           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7680          (const_int 0)))
7681    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7682         (and:DI (match_dup 1) (match_dup 2)))]
7683   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7684    && ix86_binary_operator_ok (AND, DImode, operands)"
7685   "@
7686    and{l}\t{%k2, %k0|%k0, %k2}
7687    and{q}\t{%2, %0|%0, %2}
7688    and{q}\t{%2, %0|%0, %2}"
7689   [(set_attr "type" "alu")
7690    (set_attr "mode" "SI,DI,DI")])
7692 (define_insn "*andqi_2_maybe_si"
7693   [(set (reg FLAGS_REG)
7694         (compare (and:QI
7695                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7696                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7697                  (const_int 0)))
7698    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7699         (and:QI (match_dup 1) (match_dup 2)))]
7700   "ix86_binary_operator_ok (AND, QImode, operands)
7701    && ix86_match_ccmode (insn,
7702                          CONST_INT_P (operands[2])
7703                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7705   if (which_alternative == 2)
7706     {
7707       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7708         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7709       return "and{l}\t{%2, %k0|%k0, %2}";
7710     }
7711   return "and{b}\t{%2, %0|%0, %2}";
7713   [(set_attr "type" "alu")
7714    (set_attr "mode" "QI,QI,SI")])
7716 (define_insn "*and<mode>_2"
7717   [(set (reg FLAGS_REG)
7718         (compare (and:SWI124
7719                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7720                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7721                  (const_int 0)))
7722    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7723         (and:SWI124 (match_dup 1) (match_dup 2)))]
7724   "ix86_match_ccmode (insn, CCNOmode)
7725    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7726   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7727   [(set_attr "type" "alu")
7728    (set_attr "mode" "<MODE>")])
7730 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7731 (define_insn "*andsi_2_zext"
7732   [(set (reg FLAGS_REG)
7733         (compare (and:SI
7734                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7735                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7736                  (const_int 0)))
7737    (set (match_operand:DI 0 "register_operand" "=r")
7738         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7739   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7740    && ix86_binary_operator_ok (AND, SImode, operands)"
7741   "and{l}\t{%2, %k0|%k0, %2}"
7742   [(set_attr "type" "alu")
7743    (set_attr "mode" "SI")])
7745 (define_insn "*andqi_2_slp"
7746   [(set (reg FLAGS_REG)
7747         (compare (and:QI
7748                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7749                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7750                  (const_int 0)))
7751    (set (strict_low_part (match_dup 0))
7752         (and:QI (match_dup 0) (match_dup 1)))]
7753   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7754    && ix86_match_ccmode (insn, CCNOmode)
7755    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7756   "and{b}\t{%1, %0|%0, %1}"
7757   [(set_attr "type" "alu1")
7758    (set_attr "mode" "QI")])
7760 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7761 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7762 ;; for a QImode operand, which of course failed.
7763 (define_insn "andqi_ext_0"
7764   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7765                          (const_int 8)
7766                          (const_int 8))
7767         (and:SI
7768           (zero_extract:SI
7769             (match_operand 1 "ext_register_operand" "0")
7770             (const_int 8)
7771             (const_int 8))
7772           (match_operand 2 "const_int_operand" "n")))
7773    (clobber (reg:CC FLAGS_REG))]
7774   ""
7775   "and{b}\t{%2, %h0|%h0, %2}"
7776   [(set_attr "type" "alu")
7777    (set_attr "length_immediate" "1")
7778    (set_attr "modrm" "1")
7779    (set_attr "mode" "QI")])
7781 ;; Generated by peephole translating test to and.  This shows up
7782 ;; often in fp comparisons.
7783 (define_insn "*andqi_ext_0_cc"
7784   [(set (reg FLAGS_REG)
7785         (compare
7786           (and:SI
7787             (zero_extract:SI
7788               (match_operand 1 "ext_register_operand" "0")
7789               (const_int 8)
7790               (const_int 8))
7791             (match_operand 2 "const_int_operand" "n"))
7792           (const_int 0)))
7793    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7794                          (const_int 8)
7795                          (const_int 8))
7796         (and:SI
7797           (zero_extract:SI
7798             (match_dup 1)
7799             (const_int 8)
7800             (const_int 8))
7801           (match_dup 2)))]
7802   "ix86_match_ccmode (insn, CCNOmode)"
7803   "and{b}\t{%2, %h0|%h0, %2}"
7804   [(set_attr "type" "alu")
7805    (set_attr "length_immediate" "1")
7806    (set_attr "modrm" "1")
7807    (set_attr "mode" "QI")])
7809 (define_insn "*andqi_ext_1_rex64"
7810   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7811                          (const_int 8)
7812                          (const_int 8))
7813         (and:SI
7814           (zero_extract:SI
7815             (match_operand 1 "ext_register_operand" "0")
7816             (const_int 8)
7817             (const_int 8))
7818           (zero_extend:SI
7819             (match_operand 2 "ext_register_operand" "Q"))))
7820    (clobber (reg:CC FLAGS_REG))]
7821   "TARGET_64BIT"
7822   "and{b}\t{%2, %h0|%h0, %2}"
7823   [(set_attr "type" "alu")
7824    (set_attr "length_immediate" "0")
7825    (set_attr "mode" "QI")])
7827 (define_insn "*andqi_ext_1"
7828   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7829                          (const_int 8)
7830                          (const_int 8))
7831         (and:SI
7832           (zero_extract:SI
7833             (match_operand 1 "ext_register_operand" "0")
7834             (const_int 8)
7835             (const_int 8))
7836           (zero_extend:SI
7837             (match_operand:QI 2 "general_operand" "Qm"))))
7838    (clobber (reg:CC FLAGS_REG))]
7839   "!TARGET_64BIT"
7840   "and{b}\t{%2, %h0|%h0, %2}"
7841   [(set_attr "type" "alu")
7842    (set_attr "length_immediate" "0")
7843    (set_attr "mode" "QI")])
7845 (define_insn "*andqi_ext_2"
7846   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7847                          (const_int 8)
7848                          (const_int 8))
7849         (and:SI
7850           (zero_extract:SI
7851             (match_operand 1 "ext_register_operand" "%0")
7852             (const_int 8)
7853             (const_int 8))
7854           (zero_extract:SI
7855             (match_operand 2 "ext_register_operand" "Q")
7856             (const_int 8)
7857             (const_int 8))))
7858    (clobber (reg:CC FLAGS_REG))]
7859   ""
7860   "and{b}\t{%h2, %h0|%h0, %h2}"
7861   [(set_attr "type" "alu")
7862    (set_attr "length_immediate" "0")
7863    (set_attr "mode" "QI")])
7865 ;; Convert wide AND instructions with immediate operand to shorter QImode
7866 ;; equivalents when possible.
7867 ;; Don't do the splitting with memory operands, since it introduces risk
7868 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
7869 ;; for size, but that can (should?) be handled by generic code instead.
7870 (define_split
7871   [(set (match_operand 0 "register_operand")
7872         (and (match_operand 1 "register_operand")
7873              (match_operand 2 "const_int_operand")))
7874    (clobber (reg:CC FLAGS_REG))]
7875    "reload_completed
7876     && QI_REG_P (operands[0])
7877     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7878     && !(~INTVAL (operands[2]) & ~(255 << 8))
7879     && GET_MODE (operands[0]) != QImode"
7880   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7881                    (and:SI (zero_extract:SI (match_dup 1)
7882                                             (const_int 8) (const_int 8))
7883                            (match_dup 2)))
7884               (clobber (reg:CC FLAGS_REG))])]
7886   operands[0] = gen_lowpart (SImode, operands[0]);
7887   operands[1] = gen_lowpart (SImode, operands[1]);
7888   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
7891 ;; Since AND can be encoded with sign extended immediate, this is only
7892 ;; profitable when 7th bit is not set.
7893 (define_split
7894   [(set (match_operand 0 "register_operand")
7895         (and (match_operand 1 "general_operand")
7896              (match_operand 2 "const_int_operand")))
7897    (clobber (reg:CC FLAGS_REG))]
7898    "reload_completed
7899     && ANY_QI_REG_P (operands[0])
7900     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7901     && !(~INTVAL (operands[2]) & ~255)
7902     && !(INTVAL (operands[2]) & 128)
7903     && GET_MODE (operands[0]) != QImode"
7904   [(parallel [(set (strict_low_part (match_dup 0))
7905                    (and:QI (match_dup 1)
7906                            (match_dup 2)))
7907               (clobber (reg:CC FLAGS_REG))])]
7909   operands[0] = gen_lowpart (QImode, operands[0]);
7910   operands[1] = gen_lowpart (QImode, operands[1]);
7911   operands[2] = gen_lowpart (QImode, operands[2]);
7914 ;; Logical inclusive and exclusive OR instructions
7916 ;; %%% This used to optimize known byte-wide and operations to memory.
7917 ;; If this is considered useful, it should be done with splitters.
7919 (define_expand "<code><mode>3"
7920   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7921         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7922                      (match_operand:SWIM 2 "<general_operand>")))]
7923   ""
7924   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
7926 (define_insn "*<code><mode>_1"
7927   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
7928         (any_or:SWI248
7929          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
7930          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
7931    (clobber (reg:CC FLAGS_REG))]
7932   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7933   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7934   [(set_attr "type" "alu")
7935    (set_attr "mode" "<MODE>")])
7937 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7938 (define_insn "*<code>qi_1"
7939   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
7940         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7941                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
7942    (clobber (reg:CC FLAGS_REG))]
7943   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
7944   "@
7945    <logic>{b}\t{%2, %0|%0, %2}
7946    <logic>{b}\t{%2, %0|%0, %2}
7947    <logic>{l}\t{%k2, %k0|%k0, %k2}"
7948   [(set_attr "type" "alu")
7949    (set_attr "mode" "QI,QI,SI")])
7951 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7952 (define_insn "*<code>si_1_zext"
7953   [(set (match_operand:DI 0 "register_operand" "=r")
7954         (zero_extend:DI
7955          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7956                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7957    (clobber (reg:CC FLAGS_REG))]
7958   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7959   "<logic>{l}\t{%2, %k0|%k0, %2}"
7960   [(set_attr "type" "alu")
7961    (set_attr "mode" "SI")])
7963 (define_insn "*<code>si_1_zext_imm"
7964   [(set (match_operand:DI 0 "register_operand" "=r")
7965         (any_or:DI
7966          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7967          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
7968    (clobber (reg:CC FLAGS_REG))]
7969   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7970   "<logic>{l}\t{%2, %k0|%k0, %2}"
7971   [(set_attr "type" "alu")
7972    (set_attr "mode" "SI")])
7974 (define_insn "*<code>qi_1_slp"
7975   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
7976         (any_or:QI (match_dup 0)
7977                    (match_operand:QI 1 "general_operand" "qmn,qn")))
7978    (clobber (reg:CC FLAGS_REG))]
7979   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7980    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7981   "<logic>{b}\t{%1, %0|%0, %1}"
7982   [(set_attr "type" "alu1")
7983    (set_attr "mode" "QI")])
7985 (define_insn "*<code><mode>_2"
7986   [(set (reg FLAGS_REG)
7987         (compare (any_or:SWI
7988                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7989                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
7990                  (const_int 0)))
7991    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
7992         (any_or:SWI (match_dup 1) (match_dup 2)))]
7993   "ix86_match_ccmode (insn, CCNOmode)
7994    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7995   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7996   [(set_attr "type" "alu")
7997    (set_attr "mode" "<MODE>")])
7999 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8000 ;; ??? Special case for immediate operand is missing - it is tricky.
8001 (define_insn "*<code>si_2_zext"
8002   [(set (reg FLAGS_REG)
8003         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8004                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8005                  (const_int 0)))
8006    (set (match_operand:DI 0 "register_operand" "=r")
8007         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8008   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8009    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8010   "<logic>{l}\t{%2, %k0|%k0, %2}"
8011   [(set_attr "type" "alu")
8012    (set_attr "mode" "SI")])
8014 (define_insn "*<code>si_2_zext_imm"
8015   [(set (reg FLAGS_REG)
8016         (compare (any_or:SI
8017                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8018                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8019                  (const_int 0)))
8020    (set (match_operand:DI 0 "register_operand" "=r")
8021         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8022   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8023    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8024   "<logic>{l}\t{%2, %k0|%k0, %2}"
8025   [(set_attr "type" "alu")
8026    (set_attr "mode" "SI")])
8028 (define_insn "*<code>qi_2_slp"
8029   [(set (reg FLAGS_REG)
8030         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8031                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8032                  (const_int 0)))
8033    (set (strict_low_part (match_dup 0))
8034         (any_or:QI (match_dup 0) (match_dup 1)))]
8035   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8036    && ix86_match_ccmode (insn, CCNOmode)
8037    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8038   "<logic>{b}\t{%1, %0|%0, %1}"
8039   [(set_attr "type" "alu1")
8040    (set_attr "mode" "QI")])
8042 (define_insn "*<code><mode>_3"
8043   [(set (reg FLAGS_REG)
8044         (compare (any_or:SWI
8045                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8046                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8047                  (const_int 0)))
8048    (clobber (match_scratch:SWI 0 "=<r>"))]
8049   "ix86_match_ccmode (insn, CCNOmode)
8050    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8051   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8052   [(set_attr "type" "alu")
8053    (set_attr "mode" "<MODE>")])
8055 (define_insn "*<code>qi_ext_0"
8056   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8057                          (const_int 8)
8058                          (const_int 8))
8059         (any_or:SI
8060           (zero_extract:SI
8061             (match_operand 1 "ext_register_operand" "0")
8062             (const_int 8)
8063             (const_int 8))
8064           (match_operand 2 "const_int_operand" "n")))
8065    (clobber (reg:CC FLAGS_REG))]
8066   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8067   "<logic>{b}\t{%2, %h0|%h0, %2}"
8068   [(set_attr "type" "alu")
8069    (set_attr "length_immediate" "1")
8070    (set_attr "modrm" "1")
8071    (set_attr "mode" "QI")])
8073 (define_insn "*<code>qi_ext_1_rex64"
8074   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8075                          (const_int 8)
8076                          (const_int 8))
8077         (any_or:SI
8078           (zero_extract:SI
8079             (match_operand 1 "ext_register_operand" "0")
8080             (const_int 8)
8081             (const_int 8))
8082           (zero_extend:SI
8083             (match_operand 2 "ext_register_operand" "Q"))))
8084    (clobber (reg:CC FLAGS_REG))]
8085   "TARGET_64BIT
8086    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8087   "<logic>{b}\t{%2, %h0|%h0, %2}"
8088   [(set_attr "type" "alu")
8089    (set_attr "length_immediate" "0")
8090    (set_attr "mode" "QI")])
8092 (define_insn "*<code>qi_ext_1"
8093   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8094                          (const_int 8)
8095                          (const_int 8))
8096         (any_or:SI
8097           (zero_extract:SI
8098             (match_operand 1 "ext_register_operand" "0")
8099             (const_int 8)
8100             (const_int 8))
8101           (zero_extend:SI
8102             (match_operand:QI 2 "general_operand" "Qm"))))
8103    (clobber (reg:CC FLAGS_REG))]
8104   "!TARGET_64BIT
8105    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8106   "<logic>{b}\t{%2, %h0|%h0, %2}"
8107   [(set_attr "type" "alu")
8108    (set_attr "length_immediate" "0")
8109    (set_attr "mode" "QI")])
8111 (define_insn "*<code>qi_ext_2"
8112   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8113                          (const_int 8)
8114                          (const_int 8))
8115         (any_or:SI
8116           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8117                            (const_int 8)
8118                            (const_int 8))
8119           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8120                            (const_int 8)
8121                            (const_int 8))))
8122    (clobber (reg:CC FLAGS_REG))]
8123   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8124   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8125   [(set_attr "type" "alu")
8126    (set_attr "length_immediate" "0")
8127    (set_attr "mode" "QI")])
8129 (define_split
8130   [(set (match_operand 0 "register_operand")
8131         (any_or (match_operand 1 "register_operand")
8132                 (match_operand 2 "const_int_operand")))
8133    (clobber (reg:CC FLAGS_REG))]
8134    "reload_completed
8135     && QI_REG_P (operands[0])
8136     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8137     && !(INTVAL (operands[2]) & ~(255 << 8))
8138     && GET_MODE (operands[0]) != QImode"
8139   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8140                    (any_or:SI (zero_extract:SI (match_dup 1)
8141                                                (const_int 8) (const_int 8))
8142                               (match_dup 2)))
8143               (clobber (reg:CC FLAGS_REG))])]
8145   operands[0] = gen_lowpart (SImode, operands[0]);
8146   operands[1] = gen_lowpart (SImode, operands[1]);
8147   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8150 ;; Since OR can be encoded with sign extended immediate, this is only
8151 ;; profitable when 7th bit is set.
8152 (define_split
8153   [(set (match_operand 0 "register_operand")
8154         (any_or (match_operand 1 "general_operand")
8155                 (match_operand 2 "const_int_operand")))
8156    (clobber (reg:CC FLAGS_REG))]
8157    "reload_completed
8158     && ANY_QI_REG_P (operands[0])
8159     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8160     && !(INTVAL (operands[2]) & ~255)
8161     && (INTVAL (operands[2]) & 128)
8162     && GET_MODE (operands[0]) != QImode"
8163   [(parallel [(set (strict_low_part (match_dup 0))
8164                    (any_or:QI (match_dup 1)
8165                               (match_dup 2)))
8166               (clobber (reg:CC FLAGS_REG))])]
8168   operands[0] = gen_lowpart (QImode, operands[0]);
8169   operands[1] = gen_lowpart (QImode, operands[1]);
8170   operands[2] = gen_lowpart (QImode, operands[2]);
8173 (define_expand "xorqi_cc_ext_1"
8174   [(parallel [
8175      (set (reg:CCNO FLAGS_REG)
8176           (compare:CCNO
8177             (xor:SI
8178               (zero_extract:SI
8179                 (match_operand 1 "ext_register_operand")
8180                 (const_int 8)
8181                 (const_int 8))
8182               (match_operand:QI 2 "general_operand"))
8183             (const_int 0)))
8184      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8185                            (const_int 8)
8186                            (const_int 8))
8187           (xor:SI
8188             (zero_extract:SI
8189              (match_dup 1)
8190              (const_int 8)
8191              (const_int 8))
8192             (match_dup 2)))])])
8194 (define_insn "*xorqi_cc_ext_1_rex64"
8195   [(set (reg FLAGS_REG)
8196         (compare
8197           (xor:SI
8198             (zero_extract:SI
8199               (match_operand 1 "ext_register_operand" "0")
8200               (const_int 8)
8201               (const_int 8))
8202             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8203           (const_int 0)))
8204    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8205                          (const_int 8)
8206                          (const_int 8))
8207         (xor:SI
8208           (zero_extract:SI
8209            (match_dup 1)
8210            (const_int 8)
8211            (const_int 8))
8212           (match_dup 2)))]
8213   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8214   "xor{b}\t{%2, %h0|%h0, %2}"
8215   [(set_attr "type" "alu")
8216    (set_attr "modrm" "1")
8217    (set_attr "mode" "QI")])
8219 (define_insn "*xorqi_cc_ext_1"
8220   [(set (reg FLAGS_REG)
8221         (compare
8222           (xor:SI
8223             (zero_extract:SI
8224               (match_operand 1 "ext_register_operand" "0")
8225               (const_int 8)
8226               (const_int 8))
8227             (match_operand:QI 2 "general_operand" "qmn"))
8228           (const_int 0)))
8229    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8230                          (const_int 8)
8231                          (const_int 8))
8232         (xor:SI
8233           (zero_extract:SI
8234            (match_dup 1)
8235            (const_int 8)
8236            (const_int 8))
8237           (match_dup 2)))]
8238   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8239   "xor{b}\t{%2, %h0|%h0, %2}"
8240   [(set_attr "type" "alu")
8241    (set_attr "modrm" "1")
8242    (set_attr "mode" "QI")])
8244 ;; Negation instructions
8246 (define_expand "neg<mode>2"
8247   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8248         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8249   ""
8250   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8252 (define_insn_and_split "*neg<dwi>2_doubleword"
8253   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8254         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8255    (clobber (reg:CC FLAGS_REG))]
8256   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8257   "#"
8258   "reload_completed"
8259   [(parallel
8260     [(set (reg:CCZ FLAGS_REG)
8261           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8262      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8263    (parallel
8264     [(set (match_dup 2)
8265           (plus:DWIH (match_dup 3)
8266                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8267                                 (const_int 0))))
8268      (clobber (reg:CC FLAGS_REG))])
8269    (parallel
8270     [(set (match_dup 2)
8271           (neg:DWIH (match_dup 2)))
8272      (clobber (reg:CC FLAGS_REG))])]
8273   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8275 (define_insn "*neg<mode>2_1"
8276   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8277         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8278    (clobber (reg:CC FLAGS_REG))]
8279   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8280   "neg{<imodesuffix>}\t%0"
8281   [(set_attr "type" "negnot")
8282    (set_attr "mode" "<MODE>")])
8284 ;; Combine is quite creative about this pattern.
8285 (define_insn "*negsi2_1_zext"
8286   [(set (match_operand:DI 0 "register_operand" "=r")
8287         (lshiftrt:DI
8288           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8289                              (const_int 32)))
8290         (const_int 32)))
8291    (clobber (reg:CC FLAGS_REG))]
8292   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8293   "neg{l}\t%k0"
8294   [(set_attr "type" "negnot")
8295    (set_attr "mode" "SI")])
8297 ;; The problem with neg is that it does not perform (compare x 0),
8298 ;; it really performs (compare 0 x), which leaves us with the zero
8299 ;; flag being the only useful item.
8301 (define_insn "*neg<mode>2_cmpz"
8302   [(set (reg:CCZ FLAGS_REG)
8303         (compare:CCZ
8304           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8305                    (const_int 0)))
8306    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8307         (neg:SWI (match_dup 1)))]
8308   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8309   "neg{<imodesuffix>}\t%0"
8310   [(set_attr "type" "negnot")
8311    (set_attr "mode" "<MODE>")])
8313 (define_insn "*negsi2_cmpz_zext"
8314   [(set (reg:CCZ FLAGS_REG)
8315         (compare:CCZ
8316           (lshiftrt:DI
8317             (neg:DI (ashift:DI
8318                       (match_operand:DI 1 "register_operand" "0")
8319                       (const_int 32)))
8320             (const_int 32))
8321           (const_int 0)))
8322    (set (match_operand:DI 0 "register_operand" "=r")
8323         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8324                                         (const_int 32)))
8325                      (const_int 32)))]
8326   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8327   "neg{l}\t%k0"
8328   [(set_attr "type" "negnot")
8329    (set_attr "mode" "SI")])
8331 ;; Changing of sign for FP values is doable using integer unit too.
8333 (define_expand "<code><mode>2"
8334   [(set (match_operand:X87MODEF 0 "register_operand")
8335         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8336   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8337   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8339 (define_insn "*absneg<mode>2_mixed"
8340   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8341         (match_operator:MODEF 3 "absneg_operator"
8342           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8343    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8344    (clobber (reg:CC FLAGS_REG))]
8345   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8346   "#")
8348 (define_insn "*absneg<mode>2_sse"
8349   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8350         (match_operator:MODEF 3 "absneg_operator"
8351           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8352    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8353    (clobber (reg:CC FLAGS_REG))]
8354   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8355   "#")
8357 (define_insn "*absneg<mode>2_i387"
8358   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8359         (match_operator:X87MODEF 3 "absneg_operator"
8360           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8361    (use (match_operand 2))
8362    (clobber (reg:CC FLAGS_REG))]
8363   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8364   "#")
8366 (define_expand "<code>tf2"
8367   [(set (match_operand:TF 0 "register_operand")
8368         (absneg:TF (match_operand:TF 1 "register_operand")))]
8369   "TARGET_SSE"
8370   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8372 (define_insn "*absnegtf2_sse"
8373   [(set (match_operand:TF 0 "register_operand" "=x,x")
8374         (match_operator:TF 3 "absneg_operator"
8375           [(match_operand:TF 1 "register_operand" "0,x")]))
8376    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8377    (clobber (reg:CC FLAGS_REG))]
8378   "TARGET_SSE"
8379   "#")
8381 ;; Splitters for fp abs and neg.
8383 (define_split
8384   [(set (match_operand 0 "fp_register_operand")
8385         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8386    (use (match_operand 2))
8387    (clobber (reg:CC FLAGS_REG))]
8388   "reload_completed"
8389   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8391 (define_split
8392   [(set (match_operand 0 "register_operand")
8393         (match_operator 3 "absneg_operator"
8394           [(match_operand 1 "register_operand")]))
8395    (use (match_operand 2 "nonimmediate_operand"))
8396    (clobber (reg:CC FLAGS_REG))]
8397   "reload_completed && SSE_REG_P (operands[0])"
8398   [(set (match_dup 0) (match_dup 3))]
8400   enum machine_mode mode = GET_MODE (operands[0]);
8401   enum machine_mode vmode = GET_MODE (operands[2]);
8402   rtx tmp;
8404   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8405   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8406   if (operands_match_p (operands[0], operands[2]))
8407     {
8408       tmp = operands[1];
8409       operands[1] = operands[2];
8410       operands[2] = tmp;
8411     }
8412   if (GET_CODE (operands[3]) == ABS)
8413     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8414   else
8415     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8416   operands[3] = tmp;
8419 (define_split
8420   [(set (match_operand:SF 0 "register_operand")
8421         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8422    (use (match_operand:V4SF 2))
8423    (clobber (reg:CC FLAGS_REG))]
8424   "reload_completed"
8425   [(parallel [(set (match_dup 0) (match_dup 1))
8426               (clobber (reg:CC FLAGS_REG))])]
8428   rtx tmp;
8429   operands[0] = gen_lowpart (SImode, operands[0]);
8430   if (GET_CODE (operands[1]) == ABS)
8431     {
8432       tmp = gen_int_mode (0x7fffffff, SImode);
8433       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8434     }
8435   else
8436     {
8437       tmp = gen_int_mode (0x80000000, SImode);
8438       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8439     }
8440   operands[1] = tmp;
8443 (define_split
8444   [(set (match_operand:DF 0 "register_operand")
8445         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8446    (use (match_operand 2))
8447    (clobber (reg:CC FLAGS_REG))]
8448   "reload_completed"
8449   [(parallel [(set (match_dup 0) (match_dup 1))
8450               (clobber (reg:CC FLAGS_REG))])]
8452   rtx tmp;
8453   if (TARGET_64BIT)
8454     {
8455       tmp = gen_lowpart (DImode, operands[0]);
8456       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8457       operands[0] = tmp;
8459       if (GET_CODE (operands[1]) == ABS)
8460         tmp = const0_rtx;
8461       else
8462         tmp = gen_rtx_NOT (DImode, tmp);
8463     }
8464   else
8465     {
8466       operands[0] = gen_highpart (SImode, operands[0]);
8467       if (GET_CODE (operands[1]) == ABS)
8468         {
8469           tmp = gen_int_mode (0x7fffffff, SImode);
8470           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8471         }
8472       else
8473         {
8474           tmp = gen_int_mode (0x80000000, SImode);
8475           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8476         }
8477     }
8478   operands[1] = tmp;
8481 (define_split
8482   [(set (match_operand:XF 0 "register_operand")
8483         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8484    (use (match_operand 2))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "reload_completed"
8487   [(parallel [(set (match_dup 0) (match_dup 1))
8488               (clobber (reg:CC FLAGS_REG))])]
8490   rtx tmp;
8491   operands[0] = gen_rtx_REG (SImode,
8492                              true_regnum (operands[0])
8493                              + (TARGET_64BIT ? 1 : 2));
8494   if (GET_CODE (operands[1]) == ABS)
8495     {
8496       tmp = GEN_INT (0x7fff);
8497       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8498     }
8499   else
8500     {
8501       tmp = GEN_INT (0x8000);
8502       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8503     }
8504   operands[1] = tmp;
8507 ;; Conditionalize these after reload. If they match before reload, we
8508 ;; lose the clobber and ability to use integer instructions.
8510 (define_insn "*<code><mode>2_1"
8511   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8512         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8513   "TARGET_80387
8514    && (reload_completed
8515        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8516   "f<absneg_mnemonic>"
8517   [(set_attr "type" "fsgn")
8518    (set_attr "mode" "<MODE>")])
8520 (define_insn "*<code>extendsfdf2"
8521   [(set (match_operand:DF 0 "register_operand" "=f")
8522         (absneg:DF (float_extend:DF
8523                      (match_operand:SF 1 "register_operand" "0"))))]
8524   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8525   "f<absneg_mnemonic>"
8526   [(set_attr "type" "fsgn")
8527    (set_attr "mode" "DF")])
8529 (define_insn "*<code>extendsfxf2"
8530   [(set (match_operand:XF 0 "register_operand" "=f")
8531         (absneg:XF (float_extend:XF
8532                      (match_operand:SF 1 "register_operand" "0"))))]
8533   "TARGET_80387"
8534   "f<absneg_mnemonic>"
8535   [(set_attr "type" "fsgn")
8536    (set_attr "mode" "XF")])
8538 (define_insn "*<code>extenddfxf2"
8539   [(set (match_operand:XF 0 "register_operand" "=f")
8540         (absneg:XF (float_extend:XF
8541                      (match_operand:DF 1 "register_operand" "0"))))]
8542   "TARGET_80387"
8543   "f<absneg_mnemonic>"
8544   [(set_attr "type" "fsgn")
8545    (set_attr "mode" "XF")])
8547 ;; Copysign instructions
8549 (define_mode_iterator CSGNMODE [SF DF TF])
8550 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8552 (define_expand "copysign<mode>3"
8553   [(match_operand:CSGNMODE 0 "register_operand")
8554    (match_operand:CSGNMODE 1 "nonmemory_operand")
8555    (match_operand:CSGNMODE 2 "register_operand")]
8556   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8557    || (TARGET_SSE && (<MODE>mode == TFmode))"
8558   "ix86_expand_copysign (operands); DONE;")
8560 (define_insn_and_split "copysign<mode>3_const"
8561   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8562         (unspec:CSGNMODE
8563           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8564            (match_operand:CSGNMODE 2 "register_operand" "0")
8565            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8566           UNSPEC_COPYSIGN))]
8567   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8568    || (TARGET_SSE && (<MODE>mode == TFmode))"
8569   "#"
8570   "&& reload_completed"
8571   [(const_int 0)]
8572   "ix86_split_copysign_const (operands); DONE;")
8574 (define_insn "copysign<mode>3_var"
8575   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8576         (unspec:CSGNMODE
8577           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8578            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8579            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8580            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8581           UNSPEC_COPYSIGN))
8582    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8583   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8584    || (TARGET_SSE && (<MODE>mode == TFmode))"
8585   "#")
8587 (define_split
8588   [(set (match_operand:CSGNMODE 0 "register_operand")
8589         (unspec:CSGNMODE
8590           [(match_operand:CSGNMODE 2 "register_operand")
8591            (match_operand:CSGNMODE 3 "register_operand")
8592            (match_operand:<CSGNVMODE> 4)
8593            (match_operand:<CSGNVMODE> 5)]
8594           UNSPEC_COPYSIGN))
8595    (clobber (match_scratch:<CSGNVMODE> 1))]
8596   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8597     || (TARGET_SSE && (<MODE>mode == TFmode)))
8598    && reload_completed"
8599   [(const_int 0)]
8600   "ix86_split_copysign_var (operands); DONE;")
8602 ;; One complement instructions
8604 (define_expand "one_cmpl<mode>2"
8605   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8606         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8607   ""
8608   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8610 (define_insn "*one_cmpl<mode>2_1"
8611   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8612         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8613   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8614   "not{<imodesuffix>}\t%0"
8615   [(set_attr "type" "negnot")
8616    (set_attr "mode" "<MODE>")])
8618 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8619 (define_insn "*one_cmplqi2_1"
8620   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8621         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8622   "ix86_unary_operator_ok (NOT, QImode, operands)"
8623   "@
8624    not{b}\t%0
8625    not{l}\t%k0"
8626   [(set_attr "type" "negnot")
8627    (set_attr "mode" "QI,SI")])
8629 ;; ??? Currently never generated - xor is used instead.
8630 (define_insn "*one_cmplsi2_1_zext"
8631   [(set (match_operand:DI 0 "register_operand" "=r")
8632         (zero_extend:DI
8633           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8634   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8635   "not{l}\t%k0"
8636   [(set_attr "type" "negnot")
8637    (set_attr "mode" "SI")])
8639 (define_insn "*one_cmpl<mode>2_2"
8640   [(set (reg FLAGS_REG)
8641         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8642                  (const_int 0)))
8643    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8644         (not:SWI (match_dup 1)))]
8645   "ix86_match_ccmode (insn, CCNOmode)
8646    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8647   "#"
8648   [(set_attr "type" "alu1")
8649    (set_attr "mode" "<MODE>")])
8651 (define_split
8652   [(set (match_operand 0 "flags_reg_operand")
8653         (match_operator 2 "compare_operator"
8654           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8655            (const_int 0)]))
8656    (set (match_operand:SWI 1 "nonimmediate_operand")
8657         (not:SWI (match_dup 3)))]
8658   "ix86_match_ccmode (insn, CCNOmode)"
8659   [(parallel [(set (match_dup 0)
8660                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8661                                     (const_int 0)]))
8662               (set (match_dup 1)
8663                    (xor:SWI (match_dup 3) (const_int -1)))])])
8665 ;; ??? Currently never generated - xor is used instead.
8666 (define_insn "*one_cmplsi2_2_zext"
8667   [(set (reg FLAGS_REG)
8668         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8669                  (const_int 0)))
8670    (set (match_operand:DI 0 "register_operand" "=r")
8671         (zero_extend:DI (not:SI (match_dup 1))))]
8672   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8673    && ix86_unary_operator_ok (NOT, SImode, operands)"
8674   "#"
8675   [(set_attr "type" "alu1")
8676    (set_attr "mode" "SI")])
8678 (define_split
8679   [(set (match_operand 0 "flags_reg_operand")
8680         (match_operator 2 "compare_operator"
8681           [(not:SI (match_operand:SI 3 "register_operand"))
8682            (const_int 0)]))
8683    (set (match_operand:DI 1 "register_operand")
8684         (zero_extend:DI (not:SI (match_dup 3))))]
8685   "ix86_match_ccmode (insn, CCNOmode)"
8686   [(parallel [(set (match_dup 0)
8687                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8688                                     (const_int 0)]))
8689               (set (match_dup 1)
8690                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8692 ;; Shift instructions
8694 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8695 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8696 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8697 ;; from the assembler input.
8699 ;; This instruction shifts the target reg/mem as usual, but instead of
8700 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8701 ;; is a left shift double, bits are taken from the high order bits of
8702 ;; reg, else if the insn is a shift right double, bits are taken from the
8703 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8704 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8706 ;; Since sh[lr]d does not change the `reg' operand, that is done
8707 ;; separately, making all shifts emit pairs of shift double and normal
8708 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8709 ;; support a 63 bit shift, each shift where the count is in a reg expands
8710 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8712 ;; If the shift count is a constant, we need never emit more than one
8713 ;; shift pair, instead using moves and sign extension for counts greater
8714 ;; than 31.
8716 (define_expand "ashl<mode>3"
8717   [(set (match_operand:SDWIM 0 "<shift_operand>")
8718         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8719                       (match_operand:QI 2 "nonmemory_operand")))]
8720   ""
8721   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8723 (define_insn "*ashl<mode>3_doubleword"
8724   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8725         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8726                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8727    (clobber (reg:CC FLAGS_REG))]
8728   ""
8729   "#"
8730   [(set_attr "type" "multi")])
8732 (define_split
8733   [(set (match_operand:DWI 0 "register_operand")
8734         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8735                     (match_operand:QI 2 "nonmemory_operand")))
8736    (clobber (reg:CC FLAGS_REG))]
8737   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8738   [(const_int 0)]
8739   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8741 ;; By default we don't ask for a scratch register, because when DWImode
8742 ;; values are manipulated, registers are already at a premium.  But if
8743 ;; we have one handy, we won't turn it away.
8745 (define_peephole2
8746   [(match_scratch:DWIH 3 "r")
8747    (parallel [(set (match_operand:<DWI> 0 "register_operand")
8748                    (ashift:<DWI>
8749                      (match_operand:<DWI> 1 "nonmemory_operand")
8750                      (match_operand:QI 2 "nonmemory_operand")))
8751               (clobber (reg:CC FLAGS_REG))])
8752    (match_dup 3)]
8753   "TARGET_CMOVE"
8754   [(const_int 0)]
8755   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8757 (define_insn "x86_64_shld"
8758   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8759         (ior:DI (ashift:DI (match_dup 0)
8760                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8761                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8762                   (minus:QI (const_int 64) (match_dup 2)))))
8763    (clobber (reg:CC FLAGS_REG))]
8764   "TARGET_64BIT"
8765   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8766   [(set_attr "type" "ishift")
8767    (set_attr "prefix_0f" "1")
8768    (set_attr "mode" "DI")
8769    (set_attr "athlon_decode" "vector")
8770    (set_attr "amdfam10_decode" "vector")
8771    (set_attr "bdver1_decode" "vector")])
8773 (define_insn "x86_shld"
8774   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8775         (ior:SI (ashift:SI (match_dup 0)
8776                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8777                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8778                   (minus:QI (const_int 32) (match_dup 2)))))
8779    (clobber (reg:CC FLAGS_REG))]
8780   ""
8781   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8782   [(set_attr "type" "ishift")
8783    (set_attr "prefix_0f" "1")
8784    (set_attr "mode" "SI")
8785    (set_attr "pent_pair" "np")
8786    (set_attr "athlon_decode" "vector")
8787    (set_attr "amdfam10_decode" "vector")
8788    (set_attr "bdver1_decode" "vector")])
8790 (define_expand "x86_shift<mode>_adj_1"
8791   [(set (reg:CCZ FLAGS_REG)
8792         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
8793                              (match_dup 4))
8794                      (const_int 0)))
8795    (set (match_operand:SWI48 0 "register_operand")
8796         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8797                             (match_operand:SWI48 1 "register_operand")
8798                             (match_dup 0)))
8799    (set (match_dup 1)
8800         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8801                             (match_operand:SWI48 3 "register_operand")
8802                             (match_dup 1)))]
8803   "TARGET_CMOVE"
8804   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8806 (define_expand "x86_shift<mode>_adj_2"
8807   [(use (match_operand:SWI48 0 "register_operand"))
8808    (use (match_operand:SWI48 1 "register_operand"))
8809    (use (match_operand:QI 2 "register_operand"))]
8810   ""
8812   rtx label = gen_label_rtx ();
8813   rtx tmp;
8815   emit_insn (gen_testqi_ccz_1 (operands[2],
8816                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8818   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8819   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8820   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8821                               gen_rtx_LABEL_REF (VOIDmode, label),
8822                               pc_rtx);
8823   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8824   JUMP_LABEL (tmp) = label;
8826   emit_move_insn (operands[0], operands[1]);
8827   ix86_expand_clear (operands[1]);
8829   emit_label (label);
8830   LABEL_NUSES (label) = 1;
8832   DONE;
8835 ;; Avoid useless masking of count operand.
8836 (define_insn_and_split "*ashl<mode>3_mask"
8837   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8838         (ashift:SWI48
8839           (match_operand:SWI48 1 "nonimmediate_operand" "0")
8840           (subreg:QI
8841             (and:SI
8842               (match_operand:SI 2 "nonimmediate_operand" "c")
8843               (match_operand:SI 3 "const_int_operand" "n")) 0)))
8844    (clobber (reg:CC FLAGS_REG))]
8845   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8846    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8847       == GET_MODE_BITSIZE (<MODE>mode)-1"
8848   "#"
8849   "&& 1"
8850   [(parallel [(set (match_dup 0)
8851                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
8852               (clobber (reg:CC FLAGS_REG))])]
8854   if (can_create_pseudo_p ())
8855     operands [2] = force_reg (SImode, operands[2]);
8857   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
8859   [(set_attr "type" "ishift")
8860    (set_attr "mode" "<MODE>")])
8862 (define_insn "*bmi2_ashl<mode>3_1"
8863   [(set (match_operand:SWI48 0 "register_operand" "=r")
8864         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
8865                       (match_operand:SWI48 2 "register_operand" "r")))]
8866   "TARGET_BMI2"
8867   "shlx\t{%2, %1, %0|%0, %1, %2}"
8868   [(set_attr "type" "ishiftx")
8869    (set_attr "mode" "<MODE>")])
8871 (define_insn "*ashl<mode>3_1"
8872   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
8873         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
8874                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
8875    (clobber (reg:CC FLAGS_REG))]
8876   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8878   switch (get_attr_type (insn))
8879     {
8880     case TYPE_LEA:
8881     case TYPE_ISHIFTX:
8882       return "#";
8884     case TYPE_ALU:
8885       gcc_assert (operands[2] == const1_rtx);
8886       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8887       return "add{<imodesuffix>}\t%0, %0";
8889     default:
8890       if (operands[2] == const1_rtx
8891           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8892         return "sal{<imodesuffix>}\t%0";
8893       else
8894         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
8895     }
8897   [(set_attr "isa" "*,*,bmi2")
8898    (set (attr "type")
8899      (cond [(eq_attr "alternative" "1")
8900               (const_string "lea")
8901             (eq_attr "alternative" "2")
8902               (const_string "ishiftx")
8903             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8904                       (match_operand 0 "register_operand"))
8905                  (match_operand 2 "const1_operand"))
8906               (const_string "alu")
8907            ]
8908            (const_string "ishift")))
8909    (set (attr "length_immediate")
8910      (if_then_else
8911        (ior (eq_attr "type" "alu")
8912             (and (eq_attr "type" "ishift")
8913                  (and (match_operand 2 "const1_operand")
8914                       (ior (match_test "TARGET_SHIFT1")
8915                            (match_test "optimize_function_for_size_p (cfun)")))))
8916        (const_string "0")
8917        (const_string "*")))
8918    (set_attr "mode" "<MODE>")])
8920 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8921 (define_split
8922   [(set (match_operand:SWI48 0 "register_operand")
8923         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
8924                       (match_operand:QI 2 "register_operand")))
8925    (clobber (reg:CC FLAGS_REG))]
8926   "TARGET_BMI2 && reload_completed"
8927   [(set (match_dup 0)
8928         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
8929   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
8931 (define_insn "*bmi2_ashlsi3_1_zext"
8932   [(set (match_operand:DI 0 "register_operand" "=r")
8933         (zero_extend:DI
8934           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
8935                      (match_operand:SI 2 "register_operand" "r"))))]
8936   "TARGET_64BIT && TARGET_BMI2"
8937   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
8938   [(set_attr "type" "ishiftx")
8939    (set_attr "mode" "SI")])
8941 (define_insn "*ashlsi3_1_zext"
8942   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8943         (zero_extend:DI
8944           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
8945                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
8946    (clobber (reg:CC FLAGS_REG))]
8947   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
8949   switch (get_attr_type (insn))
8950     {
8951     case TYPE_LEA:
8952     case TYPE_ISHIFTX:
8953       return "#";
8955     case TYPE_ALU:
8956       gcc_assert (operands[2] == const1_rtx);
8957       return "add{l}\t%k0, %k0";
8959     default:
8960       if (operands[2] == const1_rtx
8961           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8962         return "sal{l}\t%k0";
8963       else
8964         return "sal{l}\t{%2, %k0|%k0, %2}";
8965     }
8967   [(set_attr "isa" "*,*,bmi2")
8968    (set (attr "type")
8969      (cond [(eq_attr "alternative" "1")
8970               (const_string "lea")
8971             (eq_attr "alternative" "2")
8972               (const_string "ishiftx")
8973             (and (match_test "TARGET_DOUBLE_WITH_ADD")
8974                  (match_operand 2 "const1_operand"))
8975               (const_string "alu")
8976            ]
8977            (const_string "ishift")))
8978    (set (attr "length_immediate")
8979      (if_then_else
8980        (ior (eq_attr "type" "alu")
8981             (and (eq_attr "type" "ishift")
8982                  (and (match_operand 2 "const1_operand")
8983                       (ior (match_test "TARGET_SHIFT1")
8984                            (match_test "optimize_function_for_size_p (cfun)")))))
8985        (const_string "0")
8986        (const_string "*")))
8987    (set_attr "mode" "SI")])
8989 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8990 (define_split
8991   [(set (match_operand:DI 0 "register_operand")
8992         (zero_extend:DI
8993           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
8994                      (match_operand:QI 2 "register_operand"))))
8995    (clobber (reg:CC FLAGS_REG))]
8996   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
8997   [(set (match_dup 0)
8998         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
8999   "operands[2] = gen_lowpart (SImode, operands[2]);")
9001 (define_insn "*ashlhi3_1"
9002   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9003         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9004                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9005    (clobber (reg:CC FLAGS_REG))]
9006   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9008   switch (get_attr_type (insn))
9009     {
9010     case TYPE_LEA:
9011       return "#";
9013     case TYPE_ALU:
9014       gcc_assert (operands[2] == const1_rtx);
9015       return "add{w}\t%0, %0";
9017     default:
9018       if (operands[2] == const1_rtx
9019           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9020         return "sal{w}\t%0";
9021       else
9022         return "sal{w}\t{%2, %0|%0, %2}";
9023     }
9025   [(set (attr "type")
9026      (cond [(eq_attr "alternative" "1")
9027               (const_string "lea")
9028             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9029                       (match_operand 0 "register_operand"))
9030                  (match_operand 2 "const1_operand"))
9031               (const_string "alu")
9032            ]
9033            (const_string "ishift")))
9034    (set (attr "length_immediate")
9035      (if_then_else
9036        (ior (eq_attr "type" "alu")
9037             (and (eq_attr "type" "ishift")
9038                  (and (match_operand 2 "const1_operand")
9039                       (ior (match_test "TARGET_SHIFT1")
9040                            (match_test "optimize_function_for_size_p (cfun)")))))
9041        (const_string "0")
9042        (const_string "*")))
9043    (set_attr "mode" "HI,SI")])
9045 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9046 (define_insn "*ashlqi3_1"
9047   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9048         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9049                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9050    (clobber (reg:CC FLAGS_REG))]
9051   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9053   switch (get_attr_type (insn))
9054     {
9055     case TYPE_LEA:
9056       return "#";
9058     case TYPE_ALU:
9059       gcc_assert (operands[2] == const1_rtx);
9060       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9061         return "add{l}\t%k0, %k0";
9062       else
9063         return "add{b}\t%0, %0";
9065     default:
9066       if (operands[2] == const1_rtx
9067           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9068         {
9069           if (get_attr_mode (insn) == MODE_SI)
9070             return "sal{l}\t%k0";
9071           else
9072             return "sal{b}\t%0";
9073         }
9074       else
9075         {
9076           if (get_attr_mode (insn) == MODE_SI)
9077             return "sal{l}\t{%2, %k0|%k0, %2}";
9078           else
9079             return "sal{b}\t{%2, %0|%0, %2}";
9080         }
9081     }
9083   [(set (attr "type")
9084      (cond [(eq_attr "alternative" "2")
9085               (const_string "lea")
9086             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9087                       (match_operand 0 "register_operand"))
9088                  (match_operand 2 "const1_operand"))
9089               (const_string "alu")
9090            ]
9091            (const_string "ishift")))
9092    (set (attr "length_immediate")
9093      (if_then_else
9094        (ior (eq_attr "type" "alu")
9095             (and (eq_attr "type" "ishift")
9096                  (and (match_operand 2 "const1_operand")
9097                       (ior (match_test "TARGET_SHIFT1")
9098                            (match_test "optimize_function_for_size_p (cfun)")))))
9099        (const_string "0")
9100        (const_string "*")))
9101    (set_attr "mode" "QI,SI,SI")])
9103 (define_insn "*ashlqi3_1_slp"
9104   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9105         (ashift:QI (match_dup 0)
9106                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9107    (clobber (reg:CC FLAGS_REG))]
9108   "(optimize_function_for_size_p (cfun)
9109     || !TARGET_PARTIAL_FLAG_REG_STALL
9110     || (operands[1] == const1_rtx
9111         && (TARGET_SHIFT1
9112             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9114   switch (get_attr_type (insn))
9115     {
9116     case TYPE_ALU:
9117       gcc_assert (operands[1] == const1_rtx);
9118       return "add{b}\t%0, %0";
9120     default:
9121       if (operands[1] == const1_rtx
9122           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9123         return "sal{b}\t%0";
9124       else
9125         return "sal{b}\t{%1, %0|%0, %1}";
9126     }
9128   [(set (attr "type")
9129      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9130                       (match_operand 0 "register_operand"))
9131                  (match_operand 1 "const1_operand"))
9132               (const_string "alu")
9133            ]
9134            (const_string "ishift1")))
9135    (set (attr "length_immediate")
9136      (if_then_else
9137        (ior (eq_attr "type" "alu")
9138             (and (eq_attr "type" "ishift1")
9139                  (and (match_operand 1 "const1_operand")
9140                       (ior (match_test "TARGET_SHIFT1")
9141                            (match_test "optimize_function_for_size_p (cfun)")))))
9142        (const_string "0")
9143        (const_string "*")))
9144    (set_attr "mode" "QI")])
9146 ;; Convert ashift to the lea pattern to avoid flags dependency.
9147 (define_split
9148   [(set (match_operand 0 "register_operand")
9149         (ashift (match_operand 1 "index_register_operand")
9150                 (match_operand:QI 2 "const_int_operand")))
9151    (clobber (reg:CC FLAGS_REG))]
9152   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9153    && reload_completed
9154    && true_regnum (operands[0]) != true_regnum (operands[1])"
9155   [(const_int 0)]
9157   enum machine_mode mode = GET_MODE (operands[0]);
9158   rtx pat;
9160   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9161     { 
9162       mode = SImode; 
9163       operands[0] = gen_lowpart (mode, operands[0]);
9164       operands[1] = gen_lowpart (mode, operands[1]);
9165     }
9167   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9169   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9171   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9172   DONE;
9175 ;; Convert ashift to the lea pattern to avoid flags dependency.
9176 (define_split
9177   [(set (match_operand:DI 0 "register_operand")
9178         (zero_extend:DI
9179           (ashift:SI (match_operand:SI 1 "index_register_operand")
9180                      (match_operand:QI 2 "const_int_operand"))))
9181    (clobber (reg:CC FLAGS_REG))]
9182   "TARGET_64BIT && reload_completed
9183    && true_regnum (operands[0]) != true_regnum (operands[1])"
9184   [(set (match_dup 0)
9185         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9187   operands[1] = gen_lowpart (SImode, operands[1]);
9188   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9191 ;; This pattern can't accept a variable shift count, since shifts by
9192 ;; zero don't affect the flags.  We assume that shifts by constant
9193 ;; zero are optimized away.
9194 (define_insn "*ashl<mode>3_cmp"
9195   [(set (reg FLAGS_REG)
9196         (compare
9197           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9198                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9199           (const_int 0)))
9200    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9201         (ashift:SWI (match_dup 1) (match_dup 2)))]
9202   "(optimize_function_for_size_p (cfun)
9203     || !TARGET_PARTIAL_FLAG_REG_STALL
9204     || (operands[2] == const1_rtx
9205         && (TARGET_SHIFT1
9206             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9207    && ix86_match_ccmode (insn, CCGOCmode)
9208    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9210   switch (get_attr_type (insn))
9211     {
9212     case TYPE_ALU:
9213       gcc_assert (operands[2] == const1_rtx);
9214       return "add{<imodesuffix>}\t%0, %0";
9216     default:
9217       if (operands[2] == const1_rtx
9218           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9219         return "sal{<imodesuffix>}\t%0";
9220       else
9221         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9222     }
9224   [(set (attr "type")
9225      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9226                       (match_operand 0 "register_operand"))
9227                  (match_operand 2 "const1_operand"))
9228               (const_string "alu")
9229            ]
9230            (const_string "ishift")))
9231    (set (attr "length_immediate")
9232      (if_then_else
9233        (ior (eq_attr "type" "alu")
9234             (and (eq_attr "type" "ishift")
9235                  (and (match_operand 2 "const1_operand")
9236                       (ior (match_test "TARGET_SHIFT1")
9237                            (match_test "optimize_function_for_size_p (cfun)")))))
9238        (const_string "0")
9239        (const_string "*")))
9240    (set_attr "mode" "<MODE>")])
9242 (define_insn "*ashlsi3_cmp_zext"
9243   [(set (reg FLAGS_REG)
9244         (compare
9245           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9246                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9247           (const_int 0)))
9248    (set (match_operand:DI 0 "register_operand" "=r")
9249         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9250   "TARGET_64BIT
9251    && (optimize_function_for_size_p (cfun)
9252        || !TARGET_PARTIAL_FLAG_REG_STALL
9253        || (operands[2] == const1_rtx
9254            && (TARGET_SHIFT1
9255                || TARGET_DOUBLE_WITH_ADD)))
9256    && ix86_match_ccmode (insn, CCGOCmode)
9257    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9259   switch (get_attr_type (insn))
9260     {
9261     case TYPE_ALU:
9262       gcc_assert (operands[2] == const1_rtx);
9263       return "add{l}\t%k0, %k0";
9265     default:
9266       if (operands[2] == const1_rtx
9267           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9268         return "sal{l}\t%k0";
9269       else
9270         return "sal{l}\t{%2, %k0|%k0, %2}";
9271     }
9273   [(set (attr "type")
9274      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9275                  (match_operand 2 "const1_operand"))
9276               (const_string "alu")
9277            ]
9278            (const_string "ishift")))
9279    (set (attr "length_immediate")
9280      (if_then_else
9281        (ior (eq_attr "type" "alu")
9282             (and (eq_attr "type" "ishift")
9283                  (and (match_operand 2 "const1_operand")
9284                       (ior (match_test "TARGET_SHIFT1")
9285                            (match_test "optimize_function_for_size_p (cfun)")))))
9286        (const_string "0")
9287        (const_string "*")))
9288    (set_attr "mode" "SI")])
9290 (define_insn "*ashl<mode>3_cconly"
9291   [(set (reg FLAGS_REG)
9292         (compare
9293           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9294                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9295           (const_int 0)))
9296    (clobber (match_scratch:SWI 0 "=<r>"))]
9297   "(optimize_function_for_size_p (cfun)
9298     || !TARGET_PARTIAL_FLAG_REG_STALL
9299     || (operands[2] == const1_rtx
9300         && (TARGET_SHIFT1
9301             || TARGET_DOUBLE_WITH_ADD)))
9302    && ix86_match_ccmode (insn, CCGOCmode)"
9304   switch (get_attr_type (insn))
9305     {
9306     case TYPE_ALU:
9307       gcc_assert (operands[2] == const1_rtx);
9308       return "add{<imodesuffix>}\t%0, %0";
9310     default:
9311       if (operands[2] == const1_rtx
9312           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9313         return "sal{<imodesuffix>}\t%0";
9314       else
9315         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9316     }
9318   [(set (attr "type")
9319      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9320                       (match_operand 0 "register_operand"))
9321                  (match_operand 2 "const1_operand"))
9322               (const_string "alu")
9323            ]
9324            (const_string "ishift")))
9325    (set (attr "length_immediate")
9326      (if_then_else
9327        (ior (eq_attr "type" "alu")
9328             (and (eq_attr "type" "ishift")
9329                  (and (match_operand 2 "const1_operand")
9330                       (ior (match_test "TARGET_SHIFT1")
9331                            (match_test "optimize_function_for_size_p (cfun)")))))
9332        (const_string "0")
9333        (const_string "*")))
9334    (set_attr "mode" "<MODE>")])
9336 ;; See comment above `ashl<mode>3' about how this works.
9338 (define_expand "<shift_insn><mode>3"
9339   [(set (match_operand:SDWIM 0 "<shift_operand>")
9340         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9341                            (match_operand:QI 2 "nonmemory_operand")))]
9342   ""
9343   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9345 ;; Avoid useless masking of count operand.
9346 (define_insn_and_split "*<shift_insn><mode>3_mask"
9347   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9348         (any_shiftrt:SWI48
9349           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9350           (subreg:QI
9351             (and:SI
9352               (match_operand:SI 2 "nonimmediate_operand" "c")
9353               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9354    (clobber (reg:CC FLAGS_REG))]
9355   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9356    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9357       == GET_MODE_BITSIZE (<MODE>mode)-1"
9358   "#"
9359   "&& 1"
9360   [(parallel [(set (match_dup 0)
9361                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9362               (clobber (reg:CC FLAGS_REG))])]
9364   if (can_create_pseudo_p ())
9365     operands [2] = force_reg (SImode, operands[2]);
9367   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9369   [(set_attr "type" "ishift")
9370    (set_attr "mode" "<MODE>")])
9372 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9373   [(set (match_operand:DWI 0 "register_operand" "=r")
9374         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9375                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9376    (clobber (reg:CC FLAGS_REG))]
9377   ""
9378   "#"
9379   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9380   [(const_int 0)]
9381   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9382   [(set_attr "type" "multi")])
9384 ;; By default we don't ask for a scratch register, because when DWImode
9385 ;; values are manipulated, registers are already at a premium.  But if
9386 ;; we have one handy, we won't turn it away.
9388 (define_peephole2
9389   [(match_scratch:DWIH 3 "r")
9390    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9391                    (any_shiftrt:<DWI>
9392                      (match_operand:<DWI> 1 "register_operand")
9393                      (match_operand:QI 2 "nonmemory_operand")))
9394               (clobber (reg:CC FLAGS_REG))])
9395    (match_dup 3)]
9396   "TARGET_CMOVE"
9397   [(const_int 0)]
9398   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9400 (define_insn "x86_64_shrd"
9401   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9402         (ior:DI (ashiftrt:DI (match_dup 0)
9403                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9404                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9405                   (minus:QI (const_int 64) (match_dup 2)))))
9406    (clobber (reg:CC FLAGS_REG))]
9407   "TARGET_64BIT"
9408   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9409   [(set_attr "type" "ishift")
9410    (set_attr "prefix_0f" "1")
9411    (set_attr "mode" "DI")
9412    (set_attr "athlon_decode" "vector")
9413    (set_attr "amdfam10_decode" "vector")
9414    (set_attr "bdver1_decode" "vector")])
9416 (define_insn "x86_shrd"
9417   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9418         (ior:SI (ashiftrt:SI (match_dup 0)
9419                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9420                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9421                   (minus:QI (const_int 32) (match_dup 2)))))
9422    (clobber (reg:CC FLAGS_REG))]
9423   ""
9424   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9425   [(set_attr "type" "ishift")
9426    (set_attr "prefix_0f" "1")
9427    (set_attr "mode" "SI")
9428    (set_attr "pent_pair" "np")
9429    (set_attr "athlon_decode" "vector")
9430    (set_attr "amdfam10_decode" "vector")
9431    (set_attr "bdver1_decode" "vector")])
9433 (define_insn "ashrdi3_cvt"
9434   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9435         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9436                      (match_operand:QI 2 "const_int_operand")))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_64BIT && INTVAL (operands[2]) == 63
9439    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9440    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9441   "@
9442    {cqto|cqo}
9443    sar{q}\t{%2, %0|%0, %2}"
9444   [(set_attr "type" "imovx,ishift")
9445    (set_attr "prefix_0f" "0,*")
9446    (set_attr "length_immediate" "0,*")
9447    (set_attr "modrm" "0,1")
9448    (set_attr "mode" "DI")])
9450 (define_insn "ashrsi3_cvt"
9451   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9452         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9453                      (match_operand:QI 2 "const_int_operand")))
9454    (clobber (reg:CC FLAGS_REG))]
9455   "INTVAL (operands[2]) == 31
9456    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9457    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9458   "@
9459    {cltd|cdq}
9460    sar{l}\t{%2, %0|%0, %2}"
9461   [(set_attr "type" "imovx,ishift")
9462    (set_attr "prefix_0f" "0,*")
9463    (set_attr "length_immediate" "0,*")
9464    (set_attr "modrm" "0,1")
9465    (set_attr "mode" "SI")])
9467 (define_insn "*ashrsi3_cvt_zext"
9468   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9469         (zero_extend:DI
9470           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9471                        (match_operand:QI 2 "const_int_operand"))))
9472    (clobber (reg:CC FLAGS_REG))]
9473   "TARGET_64BIT && INTVAL (operands[2]) == 31
9474    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9475    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9476   "@
9477    {cltd|cdq}
9478    sar{l}\t{%2, %k0|%k0, %2}"
9479   [(set_attr "type" "imovx,ishift")
9480    (set_attr "prefix_0f" "0,*")
9481    (set_attr "length_immediate" "0,*")
9482    (set_attr "modrm" "0,1")
9483    (set_attr "mode" "SI")])
9485 (define_expand "x86_shift<mode>_adj_3"
9486   [(use (match_operand:SWI48 0 "register_operand"))
9487    (use (match_operand:SWI48 1 "register_operand"))
9488    (use (match_operand:QI 2 "register_operand"))]
9489   ""
9491   rtx label = gen_label_rtx ();
9492   rtx tmp;
9494   emit_insn (gen_testqi_ccz_1 (operands[2],
9495                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9497   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9498   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9499   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9500                               gen_rtx_LABEL_REF (VOIDmode, label),
9501                               pc_rtx);
9502   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9503   JUMP_LABEL (tmp) = label;
9505   emit_move_insn (operands[0], operands[1]);
9506   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9507                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9508   emit_label (label);
9509   LABEL_NUSES (label) = 1;
9511   DONE;
9514 (define_insn "*bmi2_<shift_insn><mode>3_1"
9515   [(set (match_operand:SWI48 0 "register_operand" "=r")
9516         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9517                            (match_operand:SWI48 2 "register_operand" "r")))]
9518   "TARGET_BMI2"
9519   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9520   [(set_attr "type" "ishiftx")
9521    (set_attr "mode" "<MODE>")])
9523 (define_insn "*<shift_insn><mode>3_1"
9524   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9525         (any_shiftrt:SWI48
9526           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9527           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9528    (clobber (reg:CC FLAGS_REG))]
9529   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9531   switch (get_attr_type (insn))
9532     {
9533     case TYPE_ISHIFTX:
9534       return "#";
9536     default:
9537       if (operands[2] == const1_rtx
9538           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9539         return "<shift>{<imodesuffix>}\t%0";
9540       else
9541         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9542     }
9544   [(set_attr "isa" "*,bmi2")
9545    (set_attr "type" "ishift,ishiftx")
9546    (set (attr "length_immediate")
9547      (if_then_else
9548        (and (match_operand 2 "const1_operand")
9549             (ior (match_test "TARGET_SHIFT1")
9550                  (match_test "optimize_function_for_size_p (cfun)")))
9551        (const_string "0")
9552        (const_string "*")))
9553    (set_attr "mode" "<MODE>")])
9555 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9556 (define_split
9557   [(set (match_operand:SWI48 0 "register_operand")
9558         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9559                            (match_operand:QI 2 "register_operand")))
9560    (clobber (reg:CC FLAGS_REG))]
9561   "TARGET_BMI2 && reload_completed"
9562   [(set (match_dup 0)
9563         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9564   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9566 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9567   [(set (match_operand:DI 0 "register_operand" "=r")
9568         (zero_extend:DI
9569           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9570                           (match_operand:SI 2 "register_operand" "r"))))]
9571   "TARGET_64BIT && TARGET_BMI2"
9572   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9573   [(set_attr "type" "ishiftx")
9574    (set_attr "mode" "SI")])
9576 (define_insn "*<shift_insn>si3_1_zext"
9577   [(set (match_operand:DI 0 "register_operand" "=r,r")
9578         (zero_extend:DI
9579           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9580                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9581    (clobber (reg:CC FLAGS_REG))]
9582   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9584   switch (get_attr_type (insn))
9585     {
9586     case TYPE_ISHIFTX:
9587       return "#";
9589     default:
9590       if (operands[2] == const1_rtx
9591           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592         return "<shift>{l}\t%k0";
9593       else
9594         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9595     }
9597   [(set_attr "isa" "*,bmi2")
9598    (set_attr "type" "ishift,ishiftx")
9599    (set (attr "length_immediate")
9600      (if_then_else
9601        (and (match_operand 2 "const1_operand")
9602             (ior (match_test "TARGET_SHIFT1")
9603                  (match_test "optimize_function_for_size_p (cfun)")))
9604        (const_string "0")
9605        (const_string "*")))
9606    (set_attr "mode" "SI")])
9608 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9609 (define_split
9610   [(set (match_operand:DI 0 "register_operand")
9611         (zero_extend:DI
9612           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9613                           (match_operand:QI 2 "register_operand"))))
9614    (clobber (reg:CC FLAGS_REG))]
9615   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9616   [(set (match_dup 0)
9617         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9618   "operands[2] = gen_lowpart (SImode, operands[2]);")
9620 (define_insn "*<shift_insn><mode>3_1"
9621   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9622         (any_shiftrt:SWI12
9623           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9624           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9625    (clobber (reg:CC FLAGS_REG))]
9626   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9628   if (operands[2] == const1_rtx
9629       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9630     return "<shift>{<imodesuffix>}\t%0";
9631   else
9632     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9634   [(set_attr "type" "ishift")
9635    (set (attr "length_immediate")
9636      (if_then_else
9637        (and (match_operand 2 "const1_operand")
9638             (ior (match_test "TARGET_SHIFT1")
9639                  (match_test "optimize_function_for_size_p (cfun)")))
9640        (const_string "0")
9641        (const_string "*")))
9642    (set_attr "mode" "<MODE>")])
9644 (define_insn "*<shift_insn>qi3_1_slp"
9645   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9646         (any_shiftrt:QI (match_dup 0)
9647                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9648    (clobber (reg:CC FLAGS_REG))]
9649   "(optimize_function_for_size_p (cfun)
9650     || !TARGET_PARTIAL_REG_STALL
9651     || (operands[1] == const1_rtx
9652         && TARGET_SHIFT1))"
9654   if (operands[1] == const1_rtx
9655       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9656     return "<shift>{b}\t%0";
9657   else
9658     return "<shift>{b}\t{%1, %0|%0, %1}";
9660   [(set_attr "type" "ishift1")
9661    (set (attr "length_immediate")
9662      (if_then_else
9663        (and (match_operand 1 "const1_operand")
9664             (ior (match_test "TARGET_SHIFT1")
9665                  (match_test "optimize_function_for_size_p (cfun)")))
9666        (const_string "0")
9667        (const_string "*")))
9668    (set_attr "mode" "QI")])
9670 ;; This pattern can't accept a variable shift count, since shifts by
9671 ;; zero don't affect the flags.  We assume that shifts by constant
9672 ;; zero are optimized away.
9673 (define_insn "*<shift_insn><mode>3_cmp"
9674   [(set (reg FLAGS_REG)
9675         (compare
9676           (any_shiftrt:SWI
9677             (match_operand:SWI 1 "nonimmediate_operand" "0")
9678             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9679           (const_int 0)))
9680    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9681         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9682   "(optimize_function_for_size_p (cfun)
9683     || !TARGET_PARTIAL_FLAG_REG_STALL
9684     || (operands[2] == const1_rtx
9685         && TARGET_SHIFT1))
9686    && ix86_match_ccmode (insn, CCGOCmode)
9687    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9689   if (operands[2] == const1_rtx
9690       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9691     return "<shift>{<imodesuffix>}\t%0";
9692   else
9693     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9695   [(set_attr "type" "ishift")
9696    (set (attr "length_immediate")
9697      (if_then_else
9698        (and (match_operand 2 "const1_operand")
9699             (ior (match_test "TARGET_SHIFT1")
9700                  (match_test "optimize_function_for_size_p (cfun)")))
9701        (const_string "0")
9702        (const_string "*")))
9703    (set_attr "mode" "<MODE>")])
9705 (define_insn "*<shift_insn>si3_cmp_zext"
9706   [(set (reg FLAGS_REG)
9707         (compare
9708           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9709                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9710           (const_int 0)))
9711    (set (match_operand:DI 0 "register_operand" "=r")
9712         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9713   "TARGET_64BIT
9714    && (optimize_function_for_size_p (cfun)
9715        || !TARGET_PARTIAL_FLAG_REG_STALL
9716        || (operands[2] == const1_rtx
9717            && TARGET_SHIFT1))
9718    && ix86_match_ccmode (insn, CCGOCmode)
9719    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9721   if (operands[2] == const1_rtx
9722       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9723     return "<shift>{l}\t%k0";
9724   else
9725     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9727   [(set_attr "type" "ishift")
9728    (set (attr "length_immediate")
9729      (if_then_else
9730        (and (match_operand 2 "const1_operand")
9731             (ior (match_test "TARGET_SHIFT1")
9732                  (match_test "optimize_function_for_size_p (cfun)")))
9733        (const_string "0")
9734        (const_string "*")))
9735    (set_attr "mode" "SI")])
9737 (define_insn "*<shift_insn><mode>3_cconly"
9738   [(set (reg FLAGS_REG)
9739         (compare
9740           (any_shiftrt:SWI
9741             (match_operand:SWI 1 "register_operand" "0")
9742             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9743           (const_int 0)))
9744    (clobber (match_scratch:SWI 0 "=<r>"))]
9745   "(optimize_function_for_size_p (cfun)
9746     || !TARGET_PARTIAL_FLAG_REG_STALL
9747     || (operands[2] == const1_rtx
9748         && TARGET_SHIFT1))
9749    && ix86_match_ccmode (insn, CCGOCmode)"
9751   if (operands[2] == const1_rtx
9752       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9753     return "<shift>{<imodesuffix>}\t%0";
9754   else
9755     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9757   [(set_attr "type" "ishift")
9758    (set (attr "length_immediate")
9759      (if_then_else
9760        (and (match_operand 2 "const1_operand")
9761             (ior (match_test "TARGET_SHIFT1")
9762                  (match_test "optimize_function_for_size_p (cfun)")))
9763        (const_string "0")
9764        (const_string "*")))
9765    (set_attr "mode" "<MODE>")])
9767 ;; Rotate instructions
9769 (define_expand "<rotate_insn>ti3"
9770   [(set (match_operand:TI 0 "register_operand")
9771         (any_rotate:TI (match_operand:TI 1 "register_operand")
9772                        (match_operand:QI 2 "nonmemory_operand")))]
9773   "TARGET_64BIT"
9775   if (const_1_to_63_operand (operands[2], VOIDmode))
9776     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9777                 (operands[0], operands[1], operands[2]));
9778   else
9779     FAIL;
9781   DONE;
9784 (define_expand "<rotate_insn>di3"
9785   [(set (match_operand:DI 0 "shiftdi_operand")
9786         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
9787                        (match_operand:QI 2 "nonmemory_operand")))]
9788  ""
9790   if (TARGET_64BIT)
9791     ix86_expand_binary_operator (<CODE>, DImode, operands);
9792   else if (const_1_to_31_operand (operands[2], VOIDmode))
9793     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9794                 (operands[0], operands[1], operands[2]));
9795   else
9796     FAIL;
9798   DONE;
9801 (define_expand "<rotate_insn><mode>3"
9802   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
9803         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
9804                             (match_operand:QI 2 "nonmemory_operand")))]
9805   ""
9806   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9808 ;; Avoid useless masking of count operand.
9809 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9810   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9811         (any_rotate:SWI48
9812           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9813           (subreg:QI
9814             (and:SI
9815               (match_operand:SI 2 "nonimmediate_operand" "c")
9816               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9817    (clobber (reg:CC FLAGS_REG))]
9818   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9819    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9820       == GET_MODE_BITSIZE (<MODE>mode)-1"
9821   "#"
9822   "&& 1"
9823   [(parallel [(set (match_dup 0)
9824                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9825               (clobber (reg:CC FLAGS_REG))])]
9827   if (can_create_pseudo_p ())
9828     operands [2] = force_reg (SImode, operands[2]);
9830   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9832   [(set_attr "type" "rotate")
9833    (set_attr "mode" "<MODE>")])
9835 ;; Implement rotation using two double-precision
9836 ;; shift instructions and a scratch register.
9838 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9839  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9840        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9841                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9842   (clobber (reg:CC FLAGS_REG))
9843   (clobber (match_scratch:DWIH 3 "=&r"))]
9844  ""
9845  "#"
9846  "reload_completed"
9847  [(set (match_dup 3) (match_dup 4))
9848   (parallel
9849    [(set (match_dup 4)
9850          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9851                    (lshiftrt:DWIH (match_dup 5)
9852                                   (minus:QI (match_dup 6) (match_dup 2)))))
9853     (clobber (reg:CC FLAGS_REG))])
9854   (parallel
9855    [(set (match_dup 5)
9856          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9857                    (lshiftrt:DWIH (match_dup 3)
9858                                   (minus:QI (match_dup 6) (match_dup 2)))))
9859     (clobber (reg:CC FLAGS_REG))])]
9861   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9863   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9866 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9867  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9868        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9869                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9870   (clobber (reg:CC FLAGS_REG))
9871   (clobber (match_scratch:DWIH 3 "=&r"))]
9872  ""
9873  "#"
9874  "reload_completed"
9875  [(set (match_dup 3) (match_dup 4))
9876   (parallel
9877    [(set (match_dup 4)
9878          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9879                    (ashift:DWIH (match_dup 5)
9880                                 (minus:QI (match_dup 6) (match_dup 2)))))
9881     (clobber (reg:CC FLAGS_REG))])
9882   (parallel
9883    [(set (match_dup 5)
9884          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9885                    (ashift:DWIH (match_dup 3)
9886                                 (minus:QI (match_dup 6) (match_dup 2)))))
9887     (clobber (reg:CC FLAGS_REG))])]
9889   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9891   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9894 (define_insn "*bmi2_rorx<mode>3_1"
9895   [(set (match_operand:SWI48 0 "register_operand" "=r")
9896         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9897                         (match_operand:QI 2 "immediate_operand" "<S>")))]
9898   "TARGET_BMI2"
9899   "rorx\t{%2, %1, %0|%0, %1, %2}"
9900   [(set_attr "type" "rotatex")
9901    (set_attr "mode" "<MODE>")])
9903 (define_insn "*<rotate_insn><mode>3_1"
9904   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9905         (any_rotate:SWI48
9906           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9907           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
9908    (clobber (reg:CC FLAGS_REG))]
9909   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9911   switch (get_attr_type (insn))
9912     {
9913     case TYPE_ROTATEX:
9914       return "#";
9916     default:
9917       if (operands[2] == const1_rtx
9918           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9919         return "<rotate>{<imodesuffix>}\t%0";
9920       else
9921         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9922     }
9924   [(set_attr "isa" "*,bmi2")
9925    (set_attr "type" "rotate,rotatex")
9926    (set (attr "length_immediate")
9927      (if_then_else
9928        (and (eq_attr "type" "rotate")
9929             (and (match_operand 2 "const1_operand")
9930                  (ior (match_test "TARGET_SHIFT1")
9931                       (match_test "optimize_function_for_size_p (cfun)"))))
9932        (const_string "0")
9933        (const_string "*")))
9934    (set_attr "mode" "<MODE>")])
9936 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9937 (define_split
9938   [(set (match_operand:SWI48 0 "register_operand")
9939         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9940                       (match_operand:QI 2 "immediate_operand")))
9941    (clobber (reg:CC FLAGS_REG))]
9942   "TARGET_BMI2 && reload_completed"
9943   [(set (match_dup 0)
9944         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
9946   operands[2]
9947     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
9950 (define_split
9951   [(set (match_operand:SWI48 0 "register_operand")
9952         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9953                         (match_operand:QI 2 "immediate_operand")))
9954    (clobber (reg:CC FLAGS_REG))]
9955   "TARGET_BMI2 && reload_completed"
9956   [(set (match_dup 0)
9957         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
9959 (define_insn "*bmi2_rorxsi3_1_zext"
9960   [(set (match_operand:DI 0 "register_operand" "=r")
9961         (zero_extend:DI
9962           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9963                        (match_operand:QI 2 "immediate_operand" "I"))))]
9964   "TARGET_64BIT && TARGET_BMI2"
9965   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
9966   [(set_attr "type" "rotatex")
9967    (set_attr "mode" "SI")])
9969 (define_insn "*<rotate_insn>si3_1_zext"
9970   [(set (match_operand:DI 0 "register_operand" "=r,r")
9971         (zero_extend:DI
9972           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9973                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
9974    (clobber (reg:CC FLAGS_REG))]
9975   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9977   switch (get_attr_type (insn))
9978     {
9979     case TYPE_ROTATEX:
9980       return "#";
9982     default:
9983       if (operands[2] == const1_rtx
9984           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9985         return "<rotate>{l}\t%k0";
9986       else
9987         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
9988     }
9990   [(set_attr "isa" "*,bmi2")
9991    (set_attr "type" "rotate,rotatex")
9992    (set (attr "length_immediate")
9993      (if_then_else
9994        (and (eq_attr "type" "rotate")
9995             (and (match_operand 2 "const1_operand")
9996                  (ior (match_test "TARGET_SHIFT1")
9997                       (match_test "optimize_function_for_size_p (cfun)"))))
9998        (const_string "0")
9999        (const_string "*")))
10000    (set_attr "mode" "SI")])
10002 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10003 (define_split
10004   [(set (match_operand:DI 0 "register_operand")
10005         (zero_extend:DI
10006           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10007                      (match_operand:QI 2 "immediate_operand"))))
10008    (clobber (reg:CC FLAGS_REG))]
10009   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10010   [(set (match_dup 0)
10011         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10013   operands[2]
10014     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10017 (define_split
10018   [(set (match_operand:DI 0 "register_operand")
10019         (zero_extend:DI
10020           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10021                        (match_operand:QI 2 "immediate_operand"))))
10022    (clobber (reg:CC FLAGS_REG))]
10023   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10024   [(set (match_dup 0)
10025         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10027 (define_insn "*<rotate_insn><mode>3_1"
10028   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10029         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10030                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10031    (clobber (reg:CC FLAGS_REG))]
10032   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10034   if (operands[2] == const1_rtx
10035       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036     return "<rotate>{<imodesuffix>}\t%0";
10037   else
10038     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10040   [(set_attr "type" "rotate")
10041    (set (attr "length_immediate")
10042      (if_then_else
10043        (and (match_operand 2 "const1_operand")
10044             (ior (match_test "TARGET_SHIFT1")
10045                  (match_test "optimize_function_for_size_p (cfun)")))
10046        (const_string "0")
10047        (const_string "*")))
10048    (set_attr "mode" "<MODE>")])
10050 (define_insn "*<rotate_insn>qi3_1_slp"
10051   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10052         (any_rotate:QI (match_dup 0)
10053                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10054    (clobber (reg:CC FLAGS_REG))]
10055   "(optimize_function_for_size_p (cfun)
10056     || !TARGET_PARTIAL_REG_STALL
10057     || (operands[1] == const1_rtx
10058         && TARGET_SHIFT1))"
10060   if (operands[1] == const1_rtx
10061       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062     return "<rotate>{b}\t%0";
10063   else
10064     return "<rotate>{b}\t{%1, %0|%0, %1}";
10066   [(set_attr "type" "rotate1")
10067    (set (attr "length_immediate")
10068      (if_then_else
10069        (and (match_operand 1 "const1_operand")
10070             (ior (match_test "TARGET_SHIFT1")
10071                  (match_test "optimize_function_for_size_p (cfun)")))
10072        (const_string "0")
10073        (const_string "*")))
10074    (set_attr "mode" "QI")])
10076 (define_split
10077  [(set (match_operand:HI 0 "register_operand")
10078        (any_rotate:HI (match_dup 0) (const_int 8)))
10079   (clobber (reg:CC FLAGS_REG))]
10080  "reload_completed
10081   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10082  [(parallel [(set (strict_low_part (match_dup 0))
10083                   (bswap:HI (match_dup 0)))
10084              (clobber (reg:CC FLAGS_REG))])])
10086 ;; Bit set / bit test instructions
10088 (define_expand "extv"
10089   [(set (match_operand:SI 0 "register_operand")
10090         (sign_extract:SI (match_operand:SI 1 "register_operand")
10091                          (match_operand:SI 2 "const8_operand")
10092                          (match_operand:SI 3 "const8_operand")))]
10093   ""
10095   /* Handle extractions from %ah et al.  */
10096   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10097     FAIL;
10099   /* From mips.md: extract_bit_field doesn't verify that our source
10100      matches the predicate, so check it again here.  */
10101   if (! ext_register_operand (operands[1], VOIDmode))
10102     FAIL;
10105 (define_expand "extzv"
10106   [(set (match_operand:SI 0 "register_operand")
10107         (zero_extract:SI (match_operand 1 "ext_register_operand")
10108                          (match_operand:SI 2 "const8_operand")
10109                          (match_operand:SI 3 "const8_operand")))]
10110   ""
10112   /* Handle extractions from %ah et al.  */
10113   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10114     FAIL;
10116   /* From mips.md: extract_bit_field doesn't verify that our source
10117      matches the predicate, so check it again here.  */
10118   if (! ext_register_operand (operands[1], VOIDmode))
10119     FAIL;
10122 (define_expand "insv"
10123   [(set (zero_extract (match_operand 0 "register_operand")
10124                       (match_operand 1 "const_int_operand")
10125                       (match_operand 2 "const_int_operand"))
10126         (match_operand 3 "register_operand"))]
10127   ""
10129   rtx (*gen_mov_insv_1) (rtx, rtx);
10131   if (ix86_expand_pinsr (operands))
10132     DONE;
10134   /* Handle insertions to %ah et al.  */
10135   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10136     FAIL;
10138   /* From mips.md: insert_bit_field doesn't verify that our source
10139      matches the predicate, so check it again here.  */
10140   if (! ext_register_operand (operands[0], VOIDmode))
10141     FAIL;
10143   gen_mov_insv_1 = (TARGET_64BIT
10144                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10146   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10147   DONE;
10150 ;; %%% bts, btr, btc, bt.
10151 ;; In general these instructions are *slow* when applied to memory,
10152 ;; since they enforce atomic operation.  When applied to registers,
10153 ;; it depends on the cpu implementation.  They're never faster than
10154 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10155 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10156 ;; within the instruction itself, so operating on bits in the high
10157 ;; 32-bits of a register becomes easier.
10159 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10160 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10161 ;; negdf respectively, so they can never be disabled entirely.
10163 (define_insn "*btsq"
10164   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10165                          (const_int 1)
10166                          (match_operand:DI 1 "const_0_to_63_operand"))
10167         (const_int 1))
10168    (clobber (reg:CC FLAGS_REG))]
10169   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10170   "bts{q}\t{%1, %0|%0, %1}"
10171   [(set_attr "type" "alu1")
10172    (set_attr "prefix_0f" "1")
10173    (set_attr "mode" "DI")])
10175 (define_insn "*btrq"
10176   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10177                          (const_int 1)
10178                          (match_operand:DI 1 "const_0_to_63_operand"))
10179         (const_int 0))
10180    (clobber (reg:CC FLAGS_REG))]
10181   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10182   "btr{q}\t{%1, %0|%0, %1}"
10183   [(set_attr "type" "alu1")
10184    (set_attr "prefix_0f" "1")
10185    (set_attr "mode" "DI")])
10187 (define_insn "*btcq"
10188   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10189                          (const_int 1)
10190                          (match_operand:DI 1 "const_0_to_63_operand"))
10191         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10192    (clobber (reg:CC FLAGS_REG))]
10193   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10194   "btc{q}\t{%1, %0|%0, %1}"
10195   [(set_attr "type" "alu1")
10196    (set_attr "prefix_0f" "1")
10197    (set_attr "mode" "DI")])
10199 ;; Allow Nocona to avoid these instructions if a register is available.
10201 (define_peephole2
10202   [(match_scratch:DI 2 "r")
10203    (parallel [(set (zero_extract:DI
10204                      (match_operand:DI 0 "register_operand")
10205                      (const_int 1)
10206                      (match_operand:DI 1 "const_0_to_63_operand"))
10207                    (const_int 1))
10208               (clobber (reg:CC FLAGS_REG))])]
10209   "TARGET_64BIT && !TARGET_USE_BT"
10210   [(const_int 0)]
10212   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10213   rtx op1;
10215   if (HOST_BITS_PER_WIDE_INT >= 64)
10216     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10217   else if (i < HOST_BITS_PER_WIDE_INT)
10218     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10219   else
10220     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10222   op1 = immed_double_const (lo, hi, DImode);
10223   if (i >= 31)
10224     {
10225       emit_move_insn (operands[2], op1);
10226       op1 = operands[2];
10227     }
10229   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10230   DONE;
10233 (define_peephole2
10234   [(match_scratch:DI 2 "r")
10235    (parallel [(set (zero_extract:DI
10236                      (match_operand:DI 0 "register_operand")
10237                      (const_int 1)
10238                      (match_operand:DI 1 "const_0_to_63_operand"))
10239                    (const_int 0))
10240               (clobber (reg:CC FLAGS_REG))])]
10241   "TARGET_64BIT && !TARGET_USE_BT"
10242   [(const_int 0)]
10244   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10245   rtx op1;
10247   if (HOST_BITS_PER_WIDE_INT >= 64)
10248     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10249   else if (i < HOST_BITS_PER_WIDE_INT)
10250     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10251   else
10252     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10254   op1 = immed_double_const (~lo, ~hi, DImode);
10255   if (i >= 32)
10256     {
10257       emit_move_insn (operands[2], op1);
10258       op1 = operands[2];
10259     }
10261   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10262   DONE;
10265 (define_peephole2
10266   [(match_scratch:DI 2 "r")
10267    (parallel [(set (zero_extract:DI
10268                      (match_operand:DI 0 "register_operand")
10269                      (const_int 1)
10270                      (match_operand:DI 1 "const_0_to_63_operand"))
10271               (not:DI (zero_extract:DI
10272                         (match_dup 0) (const_int 1) (match_dup 1))))
10273               (clobber (reg:CC FLAGS_REG))])]
10274   "TARGET_64BIT && !TARGET_USE_BT"
10275   [(const_int 0)]
10277   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10278   rtx op1;
10280   if (HOST_BITS_PER_WIDE_INT >= 64)
10281     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10282   else if (i < HOST_BITS_PER_WIDE_INT)
10283     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10284   else
10285     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10287   op1 = immed_double_const (lo, hi, DImode);
10288   if (i >= 31)
10289     {
10290       emit_move_insn (operands[2], op1);
10291       op1 = operands[2];
10292     }
10294   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10295   DONE;
10298 (define_insn "*bt<mode>"
10299   [(set (reg:CCC FLAGS_REG)
10300         (compare:CCC
10301           (zero_extract:SWI48
10302             (match_operand:SWI48 0 "register_operand" "r")
10303             (const_int 1)
10304             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10305           (const_int 0)))]
10306   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10307   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10308   [(set_attr "type" "alu1")
10309    (set_attr "prefix_0f" "1")
10310    (set_attr "mode" "<MODE>")])
10312 ;; Store-flag instructions.
10314 ;; For all sCOND expanders, also expand the compare or test insn that
10315 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10317 (define_insn_and_split "*setcc_di_1"
10318   [(set (match_operand:DI 0 "register_operand" "=q")
10319         (match_operator:DI 1 "ix86_comparison_operator"
10320           [(reg FLAGS_REG) (const_int 0)]))]
10321   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10322   "#"
10323   "&& reload_completed"
10324   [(set (match_dup 2) (match_dup 1))
10325    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10327   PUT_MODE (operands[1], QImode);
10328   operands[2] = gen_lowpart (QImode, operands[0]);
10331 (define_insn_and_split "*setcc_si_1_and"
10332   [(set (match_operand:SI 0 "register_operand" "=q")
10333         (match_operator:SI 1 "ix86_comparison_operator"
10334           [(reg FLAGS_REG) (const_int 0)]))
10335    (clobber (reg:CC FLAGS_REG))]
10336   "!TARGET_PARTIAL_REG_STALL
10337    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10338   "#"
10339   "&& reload_completed"
10340   [(set (match_dup 2) (match_dup 1))
10341    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10342               (clobber (reg:CC FLAGS_REG))])]
10344   PUT_MODE (operands[1], QImode);
10345   operands[2] = gen_lowpart (QImode, operands[0]);
10348 (define_insn_and_split "*setcc_si_1_movzbl"
10349   [(set (match_operand:SI 0 "register_operand" "=q")
10350         (match_operator:SI 1 "ix86_comparison_operator"
10351           [(reg FLAGS_REG) (const_int 0)]))]
10352   "!TARGET_PARTIAL_REG_STALL
10353    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10354   "#"
10355   "&& reload_completed"
10356   [(set (match_dup 2) (match_dup 1))
10357    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10359   PUT_MODE (operands[1], QImode);
10360   operands[2] = gen_lowpart (QImode, operands[0]);
10363 (define_insn "*setcc_qi"
10364   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10365         (match_operator:QI 1 "ix86_comparison_operator"
10366           [(reg FLAGS_REG) (const_int 0)]))]
10367   ""
10368   "set%C1\t%0"
10369   [(set_attr "type" "setcc")
10370    (set_attr "mode" "QI")])
10372 (define_insn "*setcc_qi_slp"
10373   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10374         (match_operator:QI 1 "ix86_comparison_operator"
10375           [(reg FLAGS_REG) (const_int 0)]))]
10376   ""
10377   "set%C1\t%0"
10378   [(set_attr "type" "setcc")
10379    (set_attr "mode" "QI")])
10381 ;; In general it is not safe to assume too much about CCmode registers,
10382 ;; so simplify-rtx stops when it sees a second one.  Under certain
10383 ;; conditions this is safe on x86, so help combine not create
10385 ;;      seta    %al
10386 ;;      testb   %al, %al
10387 ;;      sete    %al
10389 (define_split
10390   [(set (match_operand:QI 0 "nonimmediate_operand")
10391         (ne:QI (match_operator 1 "ix86_comparison_operator"
10392                  [(reg FLAGS_REG) (const_int 0)])
10393             (const_int 0)))]
10394   ""
10395   [(set (match_dup 0) (match_dup 1))]
10396   "PUT_MODE (operands[1], QImode);")
10398 (define_split
10399   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10400         (ne:QI (match_operator 1 "ix86_comparison_operator"
10401                  [(reg FLAGS_REG) (const_int 0)])
10402             (const_int 0)))]
10403   ""
10404   [(set (match_dup 0) (match_dup 1))]
10405   "PUT_MODE (operands[1], QImode);")
10407 (define_split
10408   [(set (match_operand:QI 0 "nonimmediate_operand")
10409         (eq:QI (match_operator 1 "ix86_comparison_operator"
10410                  [(reg FLAGS_REG) (const_int 0)])
10411             (const_int 0)))]
10412   ""
10413   [(set (match_dup 0) (match_dup 1))]
10415   rtx new_op1 = copy_rtx (operands[1]);
10416   operands[1] = new_op1;
10417   PUT_MODE (new_op1, QImode);
10418   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10419                                              GET_MODE (XEXP (new_op1, 0))));
10421   /* Make sure that (a) the CCmode we have for the flags is strong
10422      enough for the reversed compare or (b) we have a valid FP compare.  */
10423   if (! ix86_comparison_operator (new_op1, VOIDmode))
10424     FAIL;
10427 (define_split
10428   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10429         (eq:QI (match_operator 1 "ix86_comparison_operator"
10430                  [(reg FLAGS_REG) (const_int 0)])
10431             (const_int 0)))]
10432   ""
10433   [(set (match_dup 0) (match_dup 1))]
10435   rtx new_op1 = copy_rtx (operands[1]);
10436   operands[1] = new_op1;
10437   PUT_MODE (new_op1, QImode);
10438   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10439                                              GET_MODE (XEXP (new_op1, 0))));
10441   /* Make sure that (a) the CCmode we have for the flags is strong
10442      enough for the reversed compare or (b) we have a valid FP compare.  */
10443   if (! ix86_comparison_operator (new_op1, VOIDmode))
10444     FAIL;
10447 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10448 ;; subsequent logical operations are used to imitate conditional moves.
10449 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10450 ;; it directly.
10452 (define_insn "setcc_<mode>_sse"
10453   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10454         (match_operator:MODEF 3 "sse_comparison_operator"
10455           [(match_operand:MODEF 1 "register_operand" "0,x")
10456            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10457   "SSE_FLOAT_MODE_P (<MODE>mode)"
10458   "@
10459    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10460    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10461   [(set_attr "isa" "noavx,avx")
10462    (set_attr "type" "ssecmp")
10463    (set_attr "length_immediate" "1")
10464    (set_attr "prefix" "orig,vex")
10465    (set_attr "mode" "<MODE>")])
10467 ;; Basic conditional jump instructions.
10468 ;; We ignore the overflow flag for signed branch instructions.
10470 (define_insn "*jcc_1"
10471   [(set (pc)
10472         (if_then_else (match_operator 1 "ix86_comparison_operator"
10473                                       [(reg FLAGS_REG) (const_int 0)])
10474                       (label_ref (match_operand 0))
10475                       (pc)))]
10476   ""
10477   "%+j%C1\t%l0"
10478   [(set_attr "type" "ibr")
10479    (set_attr "modrm" "0")
10480    (set (attr "length")
10481            (if_then_else (and (ge (minus (match_dup 0) (pc))
10482                                   (const_int -126))
10483                               (lt (minus (match_dup 0) (pc))
10484                                   (const_int 128)))
10485              (const_int 2)
10486              (const_int 6)))])
10488 (define_insn "*jcc_2"
10489   [(set (pc)
10490         (if_then_else (match_operator 1 "ix86_comparison_operator"
10491                                       [(reg FLAGS_REG) (const_int 0)])
10492                       (pc)
10493                       (label_ref (match_operand 0))))]
10494   ""
10495   "%+j%c1\t%l0"
10496   [(set_attr "type" "ibr")
10497    (set_attr "modrm" "0")
10498    (set (attr "length")
10499            (if_then_else (and (ge (minus (match_dup 0) (pc))
10500                                   (const_int -126))
10501                               (lt (minus (match_dup 0) (pc))
10502                                   (const_int 128)))
10503              (const_int 2)
10504              (const_int 6)))])
10506 ;; In general it is not safe to assume too much about CCmode registers,
10507 ;; so simplify-rtx stops when it sees a second one.  Under certain
10508 ;; conditions this is safe on x86, so help combine not create
10510 ;;      seta    %al
10511 ;;      testb   %al, %al
10512 ;;      je      Lfoo
10514 (define_split
10515   [(set (pc)
10516         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10517                                       [(reg FLAGS_REG) (const_int 0)])
10518                           (const_int 0))
10519                       (label_ref (match_operand 1))
10520                       (pc)))]
10521   ""
10522   [(set (pc)
10523         (if_then_else (match_dup 0)
10524                       (label_ref (match_dup 1))
10525                       (pc)))]
10526   "PUT_MODE (operands[0], VOIDmode);")
10528 (define_split
10529   [(set (pc)
10530         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10531                                       [(reg FLAGS_REG) (const_int 0)])
10532                           (const_int 0))
10533                       (label_ref (match_operand 1))
10534                       (pc)))]
10535   ""
10536   [(set (pc)
10537         (if_then_else (match_dup 0)
10538                       (label_ref (match_dup 1))
10539                       (pc)))]
10541   rtx new_op0 = copy_rtx (operands[0]);
10542   operands[0] = new_op0;
10543   PUT_MODE (new_op0, VOIDmode);
10544   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10545                                              GET_MODE (XEXP (new_op0, 0))));
10547   /* Make sure that (a) the CCmode we have for the flags is strong
10548      enough for the reversed compare or (b) we have a valid FP compare.  */
10549   if (! ix86_comparison_operator (new_op0, VOIDmode))
10550     FAIL;
10553 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10554 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10555 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10556 ;; appropriate modulo of the bit offset value.
10558 (define_insn_and_split "*jcc_bt<mode>"
10559   [(set (pc)
10560         (if_then_else (match_operator 0 "bt_comparison_operator"
10561                         [(zero_extract:SWI48
10562                            (match_operand:SWI48 1 "register_operand" "r")
10563                            (const_int 1)
10564                            (zero_extend:SI
10565                              (match_operand:QI 2 "register_operand" "r")))
10566                          (const_int 0)])
10567                       (label_ref (match_operand 3))
10568                       (pc)))
10569    (clobber (reg:CC FLAGS_REG))]
10570   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10571   "#"
10572   "&& 1"
10573   [(set (reg:CCC FLAGS_REG)
10574         (compare:CCC
10575           (zero_extract:SWI48
10576             (match_dup 1)
10577             (const_int 1)
10578             (match_dup 2))
10579           (const_int 0)))
10580    (set (pc)
10581         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10582                       (label_ref (match_dup 3))
10583                       (pc)))]
10585   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10587   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10590 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10591 ;; also for DImode, this is what combine produces.
10592 (define_insn_and_split "*jcc_bt<mode>_mask"
10593   [(set (pc)
10594         (if_then_else (match_operator 0 "bt_comparison_operator"
10595                         [(zero_extract:SWI48
10596                            (match_operand:SWI48 1 "register_operand" "r")
10597                            (const_int 1)
10598                            (and:SI
10599                              (match_operand:SI 2 "register_operand" "r")
10600                              (match_operand:SI 3 "const_int_operand" "n")))])
10601                       (label_ref (match_operand 4))
10602                       (pc)))
10603    (clobber (reg:CC FLAGS_REG))]
10604   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10605    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10606       == GET_MODE_BITSIZE (<MODE>mode)-1"
10607   "#"
10608   "&& 1"
10609   [(set (reg:CCC FLAGS_REG)
10610         (compare:CCC
10611           (zero_extract:SWI48
10612             (match_dup 1)
10613             (const_int 1)
10614             (match_dup 2))
10615           (const_int 0)))
10616    (set (pc)
10617         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10618                       (label_ref (match_dup 4))
10619                       (pc)))]
10621   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10623   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10626 (define_insn_and_split "*jcc_btsi_1"
10627   [(set (pc)
10628         (if_then_else (match_operator 0 "bt_comparison_operator"
10629                         [(and:SI
10630                            (lshiftrt:SI
10631                              (match_operand:SI 1 "register_operand" "r")
10632                              (match_operand:QI 2 "register_operand" "r"))
10633                            (const_int 1))
10634                          (const_int 0)])
10635                       (label_ref (match_operand 3))
10636                       (pc)))
10637    (clobber (reg:CC FLAGS_REG))]
10638   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10639   "#"
10640   "&& 1"
10641   [(set (reg:CCC FLAGS_REG)
10642         (compare:CCC
10643           (zero_extract:SI
10644             (match_dup 1)
10645             (const_int 1)
10646             (match_dup 2))
10647           (const_int 0)))
10648    (set (pc)
10649         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10650                       (label_ref (match_dup 3))
10651                       (pc)))]
10653   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10655   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10658 ;; avoid useless masking of bit offset operand
10659 (define_insn_and_split "*jcc_btsi_mask_1"
10660   [(set (pc)
10661         (if_then_else
10662           (match_operator 0 "bt_comparison_operator"
10663             [(and:SI
10664                (lshiftrt:SI
10665                  (match_operand:SI 1 "register_operand" "r")
10666                  (subreg:QI
10667                    (and:SI
10668                      (match_operand:SI 2 "register_operand" "r")
10669                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10670                (const_int 1))
10671              (const_int 0)])
10672           (label_ref (match_operand 4))
10673           (pc)))
10674    (clobber (reg:CC FLAGS_REG))]
10675   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10676    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10677   "#"
10678   "&& 1"
10679   [(set (reg:CCC FLAGS_REG)
10680         (compare:CCC
10681           (zero_extract:SI
10682             (match_dup 1)
10683             (const_int 1)
10684             (match_dup 2))
10685           (const_int 0)))
10686    (set (pc)
10687         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10688                       (label_ref (match_dup 4))
10689                       (pc)))]
10690   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10692 ;; Define combination compare-and-branch fp compare instructions to help
10693 ;; combine.
10695 (define_insn "*jcc<mode>_0_i387"
10696   [(set (pc)
10697         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10698                         [(match_operand:X87MODEF 1 "register_operand" "f")
10699                          (match_operand:X87MODEF 2 "const0_operand")])
10700           (label_ref (match_operand 3))
10701           (pc)))
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 "*jcc<mode>_0_r_i387"
10709   [(set (pc)
10710         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10711                         [(match_operand:X87MODEF 1 "register_operand" "f")
10712                          (match_operand:X87MODEF 2 "const0_operand")])
10713           (pc)
10714           (label_ref (match_operand 3))))
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 "*jccxf_i387"
10722   [(set (pc)
10723         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10724                         [(match_operand:XF 1 "register_operand" "f")
10725                          (match_operand:XF 2 "register_operand" "f")])
10726           (label_ref (match_operand 3))
10727           (pc)))
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_insn "*jccxf_r_i387"
10735   [(set (pc)
10736         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10737                         [(match_operand:XF 1 "register_operand" "f")
10738                          (match_operand:XF 2 "register_operand" "f")])
10739           (pc)
10740           (label_ref (match_operand 3))))
10741    (clobber (reg:CCFP FPSR_REG))
10742    (clobber (reg:CCFP FLAGS_REG))
10743    (clobber (match_scratch:HI 4 "=a"))]
10744   "TARGET_80387 && !TARGET_CMOVE"
10745   "#")
10747 (define_insn "*jcc<mode>_i387"
10748   [(set (pc)
10749         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10750                         [(match_operand:MODEF 1 "register_operand" "f")
10751                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10752           (label_ref (match_operand 3))
10753           (pc)))
10754    (clobber (reg:CCFP FPSR_REG))
10755    (clobber (reg:CCFP FLAGS_REG))
10756    (clobber (match_scratch:HI 4 "=a"))]
10757   "TARGET_80387 && !TARGET_CMOVE"
10758   "#")
10760 (define_insn "*jcc<mode>_r_i387"
10761   [(set (pc)
10762         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10763                         [(match_operand:MODEF 1 "register_operand" "f")
10764                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10765           (pc)
10766           (label_ref (match_operand 3))))
10767    (clobber (reg:CCFP FPSR_REG))
10768    (clobber (reg:CCFP FLAGS_REG))
10769    (clobber (match_scratch:HI 4 "=a"))]
10770   "TARGET_80387 && !TARGET_CMOVE"
10771   "#")
10773 (define_insn "*jccu<mode>_i387"
10774   [(set (pc)
10775         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10776                         [(match_operand:X87MODEF 1 "register_operand" "f")
10777                          (match_operand:X87MODEF 2 "register_operand" "f")])
10778           (label_ref (match_operand 3))
10779           (pc)))
10780    (clobber (reg:CCFP FPSR_REG))
10781    (clobber (reg:CCFP FLAGS_REG))
10782    (clobber (match_scratch:HI 4 "=a"))]
10783   "TARGET_80387 && !TARGET_CMOVE"
10784   "#")
10786 (define_insn "*jccu<mode>_r_i387"
10787   [(set (pc)
10788         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10789                         [(match_operand:X87MODEF 1 "register_operand" "f")
10790                          (match_operand:X87MODEF 2 "register_operand" "f")])
10791           (pc)
10792           (label_ref (match_operand 3))))
10793    (clobber (reg:CCFP FPSR_REG))
10794    (clobber (reg:CCFP FLAGS_REG))
10795    (clobber (match_scratch:HI 4 "=a"))]
10796   "TARGET_80387 && !TARGET_CMOVE"
10797   "#")
10799 (define_split
10800   [(set (pc)
10801         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10802                         [(match_operand:X87MODEF 1 "register_operand")
10803                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
10804           (match_operand 3)
10805           (match_operand 4)))
10806    (clobber (reg:CCFP FPSR_REG))
10807    (clobber (reg:CCFP FLAGS_REG))]
10808   "TARGET_80387 && !TARGET_CMOVE
10809    && reload_completed"
10810   [(const_int 0)]
10812   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10813                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10814   DONE;
10817 (define_split
10818   [(set (pc)
10819         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10820                         [(match_operand:X87MODEF 1 "register_operand")
10821                          (match_operand:X87MODEF 2 "general_operand")])
10822           (match_operand 3)
10823           (match_operand 4)))
10824    (clobber (reg:CCFP FPSR_REG))
10825    (clobber (reg:CCFP FLAGS_REG))
10826    (clobber (match_scratch:HI 5))]
10827   "TARGET_80387 && !TARGET_CMOVE
10828    && reload_completed"
10829   [(const_int 0)]
10831   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10832                         operands[3], operands[4], operands[5], NULL_RTX);
10833   DONE;
10836 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
10837 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10838 ;; with a precedence over other operators and is always put in the first
10839 ;; place. Swap condition and operands to match ficom instruction.
10841 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
10842   [(set (pc)
10843         (if_then_else
10844           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10845             [(match_operator:X87MODEF 1 "float_operator"
10846               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10847              (match_operand:X87MODEF 3 "register_operand" "f,f")])
10848           (label_ref (match_operand 4))
10849           (pc)))
10850    (clobber (reg:CCFP FPSR_REG))
10851    (clobber (reg:CCFP FLAGS_REG))
10852    (clobber (match_scratch:HI 5 "=a,a"))]
10853   "TARGET_80387 && !TARGET_CMOVE
10854    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10855        || optimize_function_for_size_p (cfun))"
10856   "#")
10858 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
10859   [(set (pc)
10860         (if_then_else
10861           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10862             [(match_operator:X87MODEF 1 "float_operator"
10863               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10864              (match_operand:X87MODEF 3 "register_operand" "f,f")])
10865           (pc)
10866           (label_ref (match_operand 4))))
10867    (clobber (reg:CCFP FPSR_REG))
10868    (clobber (reg:CCFP FLAGS_REG))
10869    (clobber (match_scratch:HI 5 "=a,a"))]
10870   "TARGET_80387 && !TARGET_CMOVE
10871    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10872        || optimize_function_for_size_p (cfun))"
10873   "#")
10875 (define_split
10876   [(set (pc)
10877         (if_then_else
10878           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10879             [(match_operator:X87MODEF 1 "float_operator"
10880               [(match_operand:SWI24 2 "memory_operand")])
10881              (match_operand:X87MODEF 3 "register_operand")])
10882           (match_operand 4)
10883           (match_operand 5)))
10884    (clobber (reg:CCFP FPSR_REG))
10885    (clobber (reg:CCFP FLAGS_REG))
10886    (clobber (match_scratch:HI 6))]
10887   "TARGET_80387 && !TARGET_CMOVE
10888    && reload_completed"
10889   [(const_int 0)]
10891   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10892                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
10893                         operands[4], operands[5], operands[6], NULL_RTX);
10894   DONE;
10897 ;; %%% Kill this when reload knows how to do it.
10898 (define_split
10899   [(set (pc)
10900         (if_then_else
10901           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10902             [(match_operator:X87MODEF 1 "float_operator"
10903               [(match_operand:SWI24 2 "register_operand")])
10904              (match_operand:X87MODEF 3 "register_operand")])
10905           (match_operand 4)
10906           (match_operand 5)))
10907    (clobber (reg:CCFP FPSR_REG))
10908    (clobber (reg:CCFP FLAGS_REG))
10909    (clobber (match_scratch:HI 6))]
10910   "TARGET_80387 && !TARGET_CMOVE
10911    && reload_completed"
10912   [(const_int 0)]
10914   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10916   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10917                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
10918                         operands[4], operands[5], operands[6], operands[2]);
10919   DONE;
10922 ;; Unconditional and other jump instructions
10924 (define_insn "jump"
10925   [(set (pc)
10926         (label_ref (match_operand 0)))]
10927   ""
10928   "jmp\t%l0"
10929   [(set_attr "type" "ibr")
10930    (set (attr "length")
10931            (if_then_else (and (ge (minus (match_dup 0) (pc))
10932                                   (const_int -126))
10933                               (lt (minus (match_dup 0) (pc))
10934                                   (const_int 128)))
10935              (const_int 2)
10936              (const_int 5)))
10937    (set_attr "modrm" "0")])
10939 (define_expand "indirect_jump"
10940   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
10941   ""
10943   if (TARGET_X32)
10944     operands[0] = convert_memory_address (word_mode, operands[0]);
10947 (define_insn "*indirect_jump"
10948   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
10949   ""
10950   "jmp\t%A0"
10951   [(set_attr "type" "ibr")
10952    (set_attr "length_immediate" "0")])
10954 (define_expand "tablejump"
10955   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
10956               (use (label_ref (match_operand 1)))])]
10957   ""
10959   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10960      relative.  Convert the relative address to an absolute address.  */
10961   if (flag_pic)
10962     {
10963       rtx op0, op1;
10964       enum rtx_code code;
10966       /* We can't use @GOTOFF for text labels on VxWorks;
10967          see gotoff_operand.  */
10968       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10969         {
10970           code = PLUS;
10971           op0 = operands[0];
10972           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10973         }
10974       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10975         {
10976           code = PLUS;
10977           op0 = operands[0];
10978           op1 = pic_offset_table_rtx;
10979         }
10980       else
10981         {
10982           code = MINUS;
10983           op0 = pic_offset_table_rtx;
10984           op1 = operands[0];
10985         }
10987       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10988                                          OPTAB_DIRECT);
10989     }
10991   if (TARGET_X32)
10992     operands[0] = convert_memory_address (word_mode, operands[0]);
10995 (define_insn "*tablejump_1"
10996   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
10997    (use (label_ref (match_operand 1)))]
10998   ""
10999   "jmp\t%A0"
11000   [(set_attr "type" "ibr")
11001    (set_attr "length_immediate" "0")])
11003 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11005 (define_peephole2
11006   [(set (reg FLAGS_REG) (match_operand 0))
11007    (set (match_operand:QI 1 "register_operand")
11008         (match_operator:QI 2 "ix86_comparison_operator"
11009           [(reg FLAGS_REG) (const_int 0)]))
11010    (set (match_operand 3 "q_regs_operand")
11011         (zero_extend (match_dup 1)))]
11012   "(peep2_reg_dead_p (3, operands[1])
11013     || operands_match_p (operands[1], operands[3]))
11014    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11015   [(set (match_dup 4) (match_dup 0))
11016    (set (strict_low_part (match_dup 5))
11017         (match_dup 2))]
11019   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11020   operands[5] = gen_lowpart (QImode, operands[3]);
11021   ix86_expand_clear (operands[3]);
11024 (define_peephole2
11025   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11026               (match_operand 4)])
11027    (set (match_operand:QI 1 "register_operand")
11028         (match_operator:QI 2 "ix86_comparison_operator"
11029           [(reg FLAGS_REG) (const_int 0)]))
11030    (set (match_operand 3 "q_regs_operand")
11031         (zero_extend (match_dup 1)))]
11032   "(peep2_reg_dead_p (3, operands[1])
11033     || operands_match_p (operands[1], operands[3]))
11034    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11035   [(parallel [(set (match_dup 5) (match_dup 0))
11036               (match_dup 4)])
11037    (set (strict_low_part (match_dup 6))
11038         (match_dup 2))]
11040   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11041   operands[6] = gen_lowpart (QImode, operands[3]);
11042   ix86_expand_clear (operands[3]);
11045 ;; Similar, but match zero extend with andsi3.
11047 (define_peephole2
11048   [(set (reg FLAGS_REG) (match_operand 0))
11049    (set (match_operand:QI 1 "register_operand")
11050         (match_operator:QI 2 "ix86_comparison_operator"
11051           [(reg FLAGS_REG) (const_int 0)]))
11052    (parallel [(set (match_operand:SI 3 "q_regs_operand")
11053                    (and:SI (match_dup 3) (const_int 255)))
11054               (clobber (reg:CC FLAGS_REG))])]
11055   "REGNO (operands[1]) == REGNO (operands[3])
11056    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11057   [(set (match_dup 4) (match_dup 0))
11058    (set (strict_low_part (match_dup 5))
11059         (match_dup 2))]
11061   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11062   operands[5] = gen_lowpart (QImode, operands[3]);
11063   ix86_expand_clear (operands[3]);
11066 (define_peephole2
11067   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11068               (match_operand 4)])
11069    (set (match_operand:QI 1 "register_operand")
11070         (match_operator:QI 2 "ix86_comparison_operator"
11071           [(reg FLAGS_REG) (const_int 0)]))
11072    (parallel [(set (match_operand 3 "q_regs_operand")
11073                    (zero_extend (match_dup 1)))
11074               (clobber (reg:CC FLAGS_REG))])]
11075   "(peep2_reg_dead_p (3, operands[1])
11076     || operands_match_p (operands[1], operands[3]))
11077    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11078   [(parallel [(set (match_dup 5) (match_dup 0))
11079               (match_dup 4)])
11080    (set (strict_low_part (match_dup 6))
11081         (match_dup 2))]
11083   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11084   operands[6] = gen_lowpart (QImode, operands[3]);
11085   ix86_expand_clear (operands[3]);
11088 ;; Call instructions.
11090 ;; The predicates normally associated with named expanders are not properly
11091 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11092 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11094 ;; P6 processors will jump to the address after the decrement when %esp
11095 ;; is used as a call operand, so they will execute return address as a code.
11096 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11098 ;; Register constraint for call instruction.
11099 (define_mode_attr c [(SI "l") (DI "r")])
11101 ;; Call subroutine returning no value.
11103 (define_expand "call"
11104   [(call (match_operand:QI 0)
11105          (match_operand 1))
11106    (use (match_operand 2))]
11107   ""
11109   ix86_expand_call (NULL, operands[0], operands[1],
11110                     operands[2], NULL, false);
11111   DONE;
11114 (define_expand "sibcall"
11115   [(call (match_operand:QI 0)
11116          (match_operand 1))
11117    (use (match_operand 2))]
11118   ""
11120   ix86_expand_call (NULL, operands[0], operands[1],
11121                     operands[2], NULL, true);
11122   DONE;
11125 (define_insn "*call"
11126   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11127          (match_operand 1))]
11128   "!SIBLING_CALL_P (insn)"
11129   "* return ix86_output_call_insn (insn, operands[0]);"
11130   [(set_attr "type" "call")])
11132 (define_insn "*call_rex64_ms_sysv"
11133   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11134          (match_operand 1))
11135    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11136    (clobber (reg:TI XMM6_REG))
11137    (clobber (reg:TI XMM7_REG))
11138    (clobber (reg:TI XMM8_REG))
11139    (clobber (reg:TI XMM9_REG))
11140    (clobber (reg:TI XMM10_REG))
11141    (clobber (reg:TI XMM11_REG))
11142    (clobber (reg:TI XMM12_REG))
11143    (clobber (reg:TI XMM13_REG))
11144    (clobber (reg:TI XMM14_REG))
11145    (clobber (reg:TI XMM15_REG))
11146    (clobber (reg:DI SI_REG))
11147    (clobber (reg:DI DI_REG))]
11148   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11149   "* return ix86_output_call_insn (insn, operands[0]);"
11150   [(set_attr "type" "call")])
11152 (define_insn "*sibcall"
11153   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11154          (match_operand 1))]
11155   "SIBLING_CALL_P (insn)"
11156   "* return ix86_output_call_insn (insn, operands[0]);"
11157   [(set_attr "type" "call")])
11159 (define_expand "call_pop"
11160   [(parallel [(call (match_operand:QI 0)
11161                     (match_operand:SI 1))
11162               (set (reg:SI SP_REG)
11163                    (plus:SI (reg:SI SP_REG)
11164                             (match_operand:SI 3)))])]
11165   "!TARGET_64BIT"
11167   ix86_expand_call (NULL, operands[0], operands[1],
11168                     operands[2], operands[3], false);
11169   DONE;
11172 (define_insn "*call_pop"
11173   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11174          (match_operand 1))
11175    (set (reg:SI SP_REG)
11176         (plus:SI (reg:SI SP_REG)
11177                  (match_operand:SI 2 "immediate_operand" "i")))]
11178   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11179   "* return ix86_output_call_insn (insn, operands[0]);"
11180   [(set_attr "type" "call")])
11182 (define_insn "*sibcall_pop"
11183   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11184          (match_operand 1))
11185    (set (reg:SI SP_REG)
11186         (plus:SI (reg:SI SP_REG)
11187                  (match_operand:SI 2 "immediate_operand" "i")))]
11188   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11189   "* return ix86_output_call_insn (insn, operands[0]);"
11190   [(set_attr "type" "call")])
11192 ;; Call subroutine, returning value in operand 0
11194 (define_expand "call_value"
11195   [(set (match_operand 0)
11196         (call (match_operand:QI 1)
11197               (match_operand 2)))
11198    (use (match_operand 3))]
11199   ""
11201   ix86_expand_call (operands[0], operands[1], operands[2],
11202                     operands[3], NULL, false);
11203   DONE;
11206 (define_expand "sibcall_value"
11207   [(set (match_operand 0)
11208         (call (match_operand:QI 1)
11209               (match_operand 2)))
11210    (use (match_operand 3))]
11211   ""
11213   ix86_expand_call (operands[0], operands[1], operands[2],
11214                     operands[3], NULL, true);
11215   DONE;
11218 (define_insn "*call_value"
11219   [(set (match_operand 0)
11220         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11221               (match_operand 2)))]
11222   "!SIBLING_CALL_P (insn)"
11223   "* return ix86_output_call_insn (insn, operands[1]);"
11224   [(set_attr "type" "callv")])
11226 (define_insn "*sibcall_value"
11227   [(set (match_operand 0)
11228         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11229               (match_operand 2)))]
11230   "SIBLING_CALL_P (insn)"
11231   "* return ix86_output_call_insn (insn, operands[1]);"
11232   [(set_attr "type" "callv")])
11234 (define_insn "*call_value_rex64_ms_sysv"
11235   [(set (match_operand 0)
11236         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11237               (match_operand 2)))
11238    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11239    (clobber (reg:TI XMM6_REG))
11240    (clobber (reg:TI XMM7_REG))
11241    (clobber (reg:TI XMM8_REG))
11242    (clobber (reg:TI XMM9_REG))
11243    (clobber (reg:TI XMM10_REG))
11244    (clobber (reg:TI XMM11_REG))
11245    (clobber (reg:TI XMM12_REG))
11246    (clobber (reg:TI XMM13_REG))
11247    (clobber (reg:TI XMM14_REG))
11248    (clobber (reg:TI XMM15_REG))
11249    (clobber (reg:DI SI_REG))
11250    (clobber (reg:DI DI_REG))]
11251   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11252   "* return ix86_output_call_insn (insn, operands[1]);"
11253   [(set_attr "type" "callv")])
11255 (define_expand "call_value_pop"
11256   [(parallel [(set (match_operand 0)
11257                    (call (match_operand:QI 1)
11258                          (match_operand:SI 2)))
11259               (set (reg:SI SP_REG)
11260                    (plus:SI (reg:SI SP_REG)
11261                             (match_operand:SI 4)))])]
11262   "!TARGET_64BIT"
11264   ix86_expand_call (operands[0], operands[1], operands[2],
11265                     operands[3], operands[4], false);
11266   DONE;
11269 (define_insn "*call_value_pop"
11270   [(set (match_operand 0)
11271         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11272               (match_operand 2)))
11273    (set (reg:SI SP_REG)
11274         (plus:SI (reg:SI SP_REG)
11275                  (match_operand:SI 3 "immediate_operand" "i")))]
11276   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11277   "* return ix86_output_call_insn (insn, operands[1]);"
11278   [(set_attr "type" "callv")])
11280 (define_insn "*sibcall_value_pop"
11281   [(set (match_operand 0)
11282         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11283               (match_operand 2)))
11284    (set (reg:SI SP_REG)
11285         (plus:SI (reg:SI SP_REG)
11286                  (match_operand:SI 3 "immediate_operand" "i")))]
11287   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11288   "* return ix86_output_call_insn (insn, operands[1]);"
11289   [(set_attr "type" "callv")])
11291 ;; Call subroutine returning any type.
11293 (define_expand "untyped_call"
11294   [(parallel [(call (match_operand 0)
11295                     (const_int 0))
11296               (match_operand 1)
11297               (match_operand 2)])]
11298   ""
11300   int i;
11302   /* In order to give reg-stack an easier job in validating two
11303      coprocessor registers as containing a possible return value,
11304      simply pretend the untyped call returns a complex long double
11305      value. 
11307      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11308      and should have the default ABI.  */
11310   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11311                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11312                     operands[0], const0_rtx,
11313                     GEN_INT ((TARGET_64BIT
11314                               ? (ix86_abi == SYSV_ABI
11315                                  ? X86_64_SSE_REGPARM_MAX
11316                                  : X86_64_MS_SSE_REGPARM_MAX)
11317                               : X86_32_SSE_REGPARM_MAX)
11318                              - 1),
11319                     NULL, false);
11321   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11322     {
11323       rtx set = XVECEXP (operands[2], 0, i);
11324       emit_move_insn (SET_DEST (set), SET_SRC (set));
11325     }
11327   /* The optimizer does not know that the call sets the function value
11328      registers we stored in the result block.  We avoid problems by
11329      claiming that all hard registers are used and clobbered at this
11330      point.  */
11331   emit_insn (gen_blockage ());
11333   DONE;
11336 ;; Prologue and epilogue instructions
11338 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11339 ;; all of memory.  This blocks insns from being moved across this point.
11341 (define_insn "blockage"
11342   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11343   ""
11344   ""
11345   [(set_attr "length" "0")])
11347 ;; Do not schedule instructions accessing memory across this point.
11349 (define_expand "memory_blockage"
11350   [(set (match_dup 0)
11351         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11352   ""
11354   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11355   MEM_VOLATILE_P (operands[0]) = 1;
11358 (define_insn "*memory_blockage"
11359   [(set (match_operand:BLK 0)
11360         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11361   ""
11362   ""
11363   [(set_attr "length" "0")])
11365 ;; As USE insns aren't meaningful after reload, this is used instead
11366 ;; to prevent deleting instructions setting registers for PIC code
11367 (define_insn "prologue_use"
11368   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11369   ""
11370   ""
11371   [(set_attr "length" "0")])
11373 ;; Insn emitted into the body of a function to return from a function.
11374 ;; This is only done if the function's epilogue is known to be simple.
11375 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11377 (define_expand "return"
11378   [(simple_return)]
11379   "ix86_can_use_return_insn_p ()"
11381   if (crtl->args.pops_args)
11382     {
11383       rtx popc = GEN_INT (crtl->args.pops_args);
11384       emit_jump_insn (gen_simple_return_pop_internal (popc));
11385       DONE;
11386     }
11389 ;; We need to disable this for TARGET_SEH, as otherwise
11390 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11391 ;; the maximum size of prologue in unwind information.
11393 (define_expand "simple_return"
11394   [(simple_return)]
11395   "!TARGET_SEH"
11397   if (crtl->args.pops_args)
11398     {
11399       rtx popc = GEN_INT (crtl->args.pops_args);
11400       emit_jump_insn (gen_simple_return_pop_internal (popc));
11401       DONE;
11402     }
11405 (define_insn "simple_return_internal"
11406   [(simple_return)]
11407   "reload_completed"
11408   "ret"
11409   [(set_attr "length" "1")
11410    (set_attr "atom_unit" "jeu")
11411    (set_attr "length_immediate" "0")
11412    (set_attr "modrm" "0")])
11414 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11415 ;; instruction Athlon and K8 have.
11417 (define_insn "simple_return_internal_long"
11418   [(simple_return)
11419    (unspec [(const_int 0)] UNSPEC_REP)]
11420   "reload_completed"
11421   "rep%; ret"
11422   [(set_attr "length" "2")
11423    (set_attr "atom_unit" "jeu")
11424    (set_attr "length_immediate" "0")
11425    (set_attr "prefix_rep" "1")
11426    (set_attr "modrm" "0")])
11428 (define_insn "simple_return_pop_internal"
11429   [(simple_return)
11430    (use (match_operand:SI 0 "const_int_operand"))]
11431   "reload_completed"
11432   "ret\t%0"
11433   [(set_attr "length" "3")
11434    (set_attr "atom_unit" "jeu")
11435    (set_attr "length_immediate" "2")
11436    (set_attr "modrm" "0")])
11438 (define_insn "simple_return_indirect_internal"
11439   [(simple_return)
11440    (use (match_operand:SI 0 "register_operand" "r"))]
11441   "reload_completed"
11442   "jmp\t%A0"
11443   [(set_attr "type" "ibr")
11444    (set_attr "length_immediate" "0")])
11446 (define_insn "nop"
11447   [(const_int 0)]
11448   ""
11449   "nop"
11450   [(set_attr "length" "1")
11451    (set_attr "length_immediate" "0")
11452    (set_attr "modrm" "0")])
11454 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11455 (define_insn "nops"
11456   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11457                     UNSPECV_NOPS)]
11458   "reload_completed"
11460   int num = INTVAL (operands[0]);
11462   gcc_assert (IN_RANGE (num, 1, 8));
11464   while (num--)
11465     fputs ("\tnop\n", asm_out_file);
11467   return "";
11469   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11470    (set_attr "length_immediate" "0")
11471    (set_attr "modrm" "0")])
11473 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11474 ;; branch prediction penalty for the third jump in a 16-byte
11475 ;; block on K8.
11477 (define_insn "pad"
11478   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11479   ""
11481 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11482   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11483 #else
11484   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11485      The align insn is used to avoid 3 jump instructions in the row to improve
11486      branch prediction and the benefits hardly outweigh the cost of extra 8
11487      nops on the average inserted by full alignment pseudo operation.  */
11488 #endif
11489   return "";
11491   [(set_attr "length" "16")])
11493 (define_expand "prologue"
11494   [(const_int 0)]
11495   ""
11496   "ix86_expand_prologue (); DONE;")
11498 (define_insn "set_got"
11499   [(set (match_operand:SI 0 "register_operand" "=r")
11500         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11501    (clobber (reg:CC FLAGS_REG))]
11502   "!TARGET_64BIT"
11503   "* return output_set_got (operands[0], NULL_RTX);"
11504   [(set_attr "type" "multi")
11505    (set_attr "length" "12")])
11507 (define_insn "set_got_labelled"
11508   [(set (match_operand:SI 0 "register_operand" "=r")
11509         (unspec:SI [(label_ref (match_operand 1))]
11510          UNSPEC_SET_GOT))
11511    (clobber (reg:CC FLAGS_REG))]
11512   "!TARGET_64BIT"
11513   "* return output_set_got (operands[0], operands[1]);"
11514   [(set_attr "type" "multi")
11515    (set_attr "length" "12")])
11517 (define_insn "set_got_rex64"
11518   [(set (match_operand:DI 0 "register_operand" "=r")
11519         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11520   "TARGET_64BIT"
11521   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11522   [(set_attr "type" "lea")
11523    (set_attr "length_address" "4")
11524    (set_attr "mode" "DI")])
11526 (define_insn "set_rip_rex64"
11527   [(set (match_operand:DI 0 "register_operand" "=r")
11528         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11529   "TARGET_64BIT"
11530   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11531   [(set_attr "type" "lea")
11532    (set_attr "length_address" "4")
11533    (set_attr "mode" "DI")])
11535 (define_insn "set_got_offset_rex64"
11536   [(set (match_operand:DI 0 "register_operand" "=r")
11537         (unspec:DI
11538           [(label_ref (match_operand 1))]
11539           UNSPEC_SET_GOT_OFFSET))]
11540   "TARGET_LP64"
11541   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11542   [(set_attr "type" "imov")
11543    (set_attr "length_immediate" "0")
11544    (set_attr "length_address" "8")
11545    (set_attr "mode" "DI")])
11547 (define_expand "epilogue"
11548   [(const_int 0)]
11549   ""
11550   "ix86_expand_epilogue (1); DONE;")
11552 (define_expand "sibcall_epilogue"
11553   [(const_int 0)]
11554   ""
11555   "ix86_expand_epilogue (0); DONE;")
11557 (define_expand "eh_return"
11558   [(use (match_operand 0 "register_operand"))]
11559   ""
11561   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11563   /* Tricky bit: we write the address of the handler to which we will
11564      be returning into someone else's stack frame, one word below the
11565      stack address we wish to restore.  */
11566   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11567   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11568   tmp = gen_rtx_MEM (Pmode, tmp);
11569   emit_move_insn (tmp, ra);
11571   emit_jump_insn (gen_eh_return_internal ());
11572   emit_barrier ();
11573   DONE;
11576 (define_insn_and_split "eh_return_internal"
11577   [(eh_return)]
11578   ""
11579   "#"
11580   "epilogue_completed"
11581   [(const_int 0)]
11582   "ix86_expand_epilogue (2); DONE;")
11584 (define_insn "leave"
11585   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11586    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11587    (clobber (mem:BLK (scratch)))]
11588   "!TARGET_64BIT"
11589   "leave"
11590   [(set_attr "type" "leave")])
11592 (define_insn "leave_rex64"
11593   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11594    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11595    (clobber (mem:BLK (scratch)))]
11596   "TARGET_64BIT"
11597   "leave"
11598   [(set_attr "type" "leave")])
11600 ;; Handle -fsplit-stack.
11602 (define_expand "split_stack_prologue"
11603   [(const_int 0)]
11604   ""
11606   ix86_expand_split_stack_prologue ();
11607   DONE;
11610 ;; In order to support the call/return predictor, we use a return
11611 ;; instruction which the middle-end doesn't see.
11612 (define_insn "split_stack_return"
11613   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11614                      UNSPECV_SPLIT_STACK_RETURN)]
11615   ""
11617   if (operands[0] == const0_rtx)
11618     return "ret";
11619   else
11620     return "ret\t%0";
11622   [(set_attr "atom_unit" "jeu")
11623    (set_attr "modrm" "0")
11624    (set (attr "length")
11625         (if_then_else (match_operand:SI 0 "const0_operand")
11626                       (const_int 1)
11627                       (const_int 3)))
11628    (set (attr "length_immediate")
11629         (if_then_else (match_operand:SI 0 "const0_operand")
11630                       (const_int 0)
11631                       (const_int 2)))])
11633 ;; If there are operand 0 bytes available on the stack, jump to
11634 ;; operand 1.
11636 (define_expand "split_stack_space_check"
11637   [(set (pc) (if_then_else
11638               (ltu (minus (reg SP_REG)
11639                           (match_operand 0 "register_operand"))
11640                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11641               (label_ref (match_operand 1))
11642               (pc)))]
11643   ""
11645   rtx reg, size, limit;
11647   reg = gen_reg_rtx (Pmode);
11648   size = force_reg (Pmode, operands[0]);
11649   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11650   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11651                           UNSPEC_STACK_CHECK);
11652   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11653   ix86_expand_branch (GEU, reg, limit, operands[1]);
11655   DONE;
11658 ;; Bit manipulation instructions.
11660 (define_expand "ffs<mode>2"
11661   [(set (match_dup 2) (const_int -1))
11662    (parallel [(set (match_dup 3) (match_dup 4))
11663               (set (match_operand:SWI48 0 "register_operand")
11664                    (ctz:SWI48
11665                      (match_operand:SWI48 1 "nonimmediate_operand")))])
11666    (set (match_dup 0) (if_then_else:SWI48
11667                         (eq (match_dup 3) (const_int 0))
11668                         (match_dup 2)
11669                         (match_dup 0)))
11670    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11671               (clobber (reg:CC FLAGS_REG))])]
11672   ""
11674   enum machine_mode flags_mode;
11676   if (<MODE>mode == SImode && !TARGET_CMOVE)
11677     {
11678       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11679       DONE;
11680     }
11682   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11684   operands[2] = gen_reg_rtx (<MODE>mode);
11685   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
11686   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11689 (define_insn_and_split "ffssi2_no_cmove"
11690   [(set (match_operand:SI 0 "register_operand" "=r")
11691         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11692    (clobber (match_scratch:SI 2 "=&q"))
11693    (clobber (reg:CC FLAGS_REG))]
11694   "!TARGET_CMOVE"
11695   "#"
11696   "&& reload_completed"
11697   [(parallel [(set (match_dup 4) (match_dup 5))
11698               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11699    (set (strict_low_part (match_dup 3))
11700         (eq:QI (match_dup 4) (const_int 0)))
11701    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11702               (clobber (reg:CC FLAGS_REG))])
11703    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11704               (clobber (reg:CC FLAGS_REG))])
11705    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11706               (clobber (reg:CC FLAGS_REG))])]
11708   enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11710   operands[3] = gen_lowpart (QImode, operands[2]);
11711   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
11712   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11714   ix86_expand_clear (operands[2]);
11717 (define_insn "*tzcnt<mode>_1"
11718   [(set (reg:CCC FLAGS_REG)
11719         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11720                      (const_int 0)))
11721    (set (match_operand:SWI48 0 "register_operand" "=r")
11722         (ctz:SWI48 (match_dup 1)))]
11723   "TARGET_BMI"
11724   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11725   [(set_attr "type" "alu1")
11726    (set_attr "prefix_0f" "1")
11727    (set_attr "prefix_rep" "1")
11728    (set_attr "btver2_decode" "double")
11729    (set_attr "mode" "<MODE>")])
11731 (define_insn "*bsf<mode>_1"
11732   [(set (reg:CCZ FLAGS_REG)
11733         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11734                      (const_int 0)))
11735    (set (match_operand:SWI48 0 "register_operand" "=r")
11736         (ctz:SWI48 (match_dup 1)))]
11737   ""
11738   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11739   [(set_attr "type" "alu1")
11740    (set_attr "prefix_0f" "1")
11741    (set_attr "btver2_decode" "double")
11742    (set_attr "mode" "<MODE>")])
11744 (define_insn "ctz<mode>2"
11745   [(set (match_operand:SWI248 0 "register_operand" "=r")
11746         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11747    (clobber (reg:CC FLAGS_REG))]
11748   ""
11750   if (TARGET_BMI)
11751     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11752   else if (optimize_function_for_size_p (cfun))
11753     ;
11754   else if (TARGET_GENERIC)
11755     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
11756     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11758   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11760   [(set_attr "type" "alu1")
11761    (set_attr "prefix_0f" "1")
11762    (set (attr "prefix_rep")
11763      (if_then_else
11764        (ior (match_test "TARGET_BMI")
11765             (and (not (match_test "optimize_function_for_size_p (cfun)"))
11766                  (match_test "TARGET_GENERIC")))
11767        (const_string "1")
11768        (const_string "0")))
11769    (set_attr "mode" "<MODE>")])
11771 (define_expand "clz<mode>2"
11772   [(parallel
11773      [(set (match_operand:SWI248 0 "register_operand")
11774            (minus:SWI248
11775              (match_dup 2)
11776              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
11777       (clobber (reg:CC FLAGS_REG))])
11778    (parallel
11779      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11780       (clobber (reg:CC FLAGS_REG))])]
11781   ""
11783   if (TARGET_LZCNT)
11784     {
11785       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11786       DONE;
11787     }
11788   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11791 (define_insn "clz<mode>2_lzcnt"
11792   [(set (match_operand:SWI248 0 "register_operand" "=r")
11793         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11794    (clobber (reg:CC FLAGS_REG))]
11795   "TARGET_LZCNT"
11796   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11797   [(set_attr "prefix_rep" "1")
11798    (set_attr "type" "bitmanip")
11799    (set_attr "mode" "<MODE>")])
11801 ;; BMI instructions.
11802 (define_insn "*bmi_andn_<mode>"
11803   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11804         (and:SWI48
11805           (not:SWI48
11806             (match_operand:SWI48 1 "register_operand" "r,r"))
11807             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
11808    (clobber (reg:CC FLAGS_REG))]
11809   "TARGET_BMI"
11810   "andn\t{%2, %1, %0|%0, %1, %2}"
11811   [(set_attr "type" "bitmanip")
11812    (set_attr "btver2_decode" "direct, double")
11813    (set_attr "mode" "<MODE>")])
11815 (define_insn "bmi_bextr_<mode>"
11816   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11817         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r,r")
11818                        (match_operand:SWI48 2 "nonimmediate_operand" "r,m")]
11819                        UNSPEC_BEXTR))
11820    (clobber (reg:CC FLAGS_REG))]
11821   "TARGET_BMI"
11822   "bextr\t{%2, %1, %0|%0, %1, %2}"
11823   [(set_attr "type" "bitmanip")
11824    (set_attr "btver2_decode" "direct, double")
11825    (set_attr "mode" "<MODE>")])
11827 (define_insn "*bmi_blsi_<mode>"
11828   [(set (match_operand:SWI48 0 "register_operand" "=r")
11829         (and:SWI48
11830           (neg:SWI48
11831             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11832           (match_dup 1)))
11833    (clobber (reg:CC FLAGS_REG))]
11834   "TARGET_BMI"
11835   "blsi\t{%1, %0|%0, %1}"
11836   [(set_attr "type" "bitmanip")
11837    (set_attr "btver2_decode" "double")
11838    (set_attr "mode" "<MODE>")])
11840 (define_insn "*bmi_blsmsk_<mode>"
11841   [(set (match_operand:SWI48 0 "register_operand" "=r")
11842         (xor:SWI48
11843           (plus:SWI48
11844             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11845             (const_int -1))
11846           (match_dup 1)))
11847    (clobber (reg:CC FLAGS_REG))]
11848   "TARGET_BMI"
11849   "blsmsk\t{%1, %0|%0, %1}"
11850   [(set_attr "type" "bitmanip")
11851    (set_attr "btver2_decode" "double")
11852    (set_attr "mode" "<MODE>")])
11854 (define_insn "*bmi_blsr_<mode>"
11855   [(set (match_operand:SWI48 0 "register_operand" "=r")
11856         (and:SWI48
11857           (plus:SWI48
11858             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11859             (const_int -1))
11860           (match_dup 1)))
11861    (clobber (reg:CC FLAGS_REG))]
11862    "TARGET_BMI"
11863    "blsr\t{%1, %0|%0, %1}"
11864   [(set_attr "type" "bitmanip")
11865    (set_attr "btver2_decode" "double")
11866    (set_attr "mode" "<MODE>")])
11868 ;; BMI2 instructions.
11869 (define_insn "bmi2_bzhi_<mode>3"
11870   [(set (match_operand:SWI48 0 "register_operand" "=r")
11871         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
11872                    (lshiftrt:SWI48 (const_int -1)
11873                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
11874    (clobber (reg:CC FLAGS_REG))]
11875   "TARGET_BMI2"
11876   "bzhi\t{%2, %1, %0|%0, %1, %2}"
11877   [(set_attr "type" "bitmanip")
11878    (set_attr "prefix" "vex")
11879    (set_attr "mode" "<MODE>")])
11881 (define_insn "bmi2_pdep_<mode>3"
11882   [(set (match_operand:SWI48 0 "register_operand" "=r")
11883         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11884                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11885                        UNSPEC_PDEP))]
11886   "TARGET_BMI2"
11887   "pdep\t{%2, %1, %0|%0, %1, %2}"
11888   [(set_attr "type" "bitmanip")
11889    (set_attr "prefix" "vex")
11890    (set_attr "mode" "<MODE>")])
11892 (define_insn "bmi2_pext_<mode>3"
11893   [(set (match_operand:SWI48 0 "register_operand" "=r")
11894         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11895                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11896                        UNSPEC_PEXT))]
11897   "TARGET_BMI2"
11898   "pext\t{%2, %1, %0|%0, %1, %2}"
11899   [(set_attr "type" "bitmanip")
11900    (set_attr "prefix" "vex")
11901    (set_attr "mode" "<MODE>")])
11903 ;; TBM instructions.
11904 (define_insn "tbm_bextri_<mode>"
11905   [(set (match_operand:SWI48 0 "register_operand" "=r")
11906         (zero_extract:SWI48
11907           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11908           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11909           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11910    (clobber (reg:CC FLAGS_REG))]
11911    "TARGET_TBM"
11913   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11914   return "bextr\t{%2, %1, %0|%0, %1, %2}";
11916   [(set_attr "type" "bitmanip")
11917    (set_attr "mode" "<MODE>")])
11919 (define_insn "*tbm_blcfill_<mode>"
11920   [(set (match_operand:SWI48 0 "register_operand" "=r")
11921         (and:SWI48
11922           (plus:SWI48
11923             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11924             (const_int 1))
11925           (match_dup 1)))
11926    (clobber (reg:CC FLAGS_REG))]
11927    "TARGET_TBM"
11928    "blcfill\t{%1, %0|%0, %1}"
11929   [(set_attr "type" "bitmanip")
11930    (set_attr "mode" "<MODE>")])
11932 (define_insn "*tbm_blci_<mode>"
11933   [(set (match_operand:SWI48 0 "register_operand" "=r")
11934         (ior:SWI48
11935           (not:SWI48
11936             (plus:SWI48
11937               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11938               (const_int 1)))
11939           (match_dup 1)))
11940    (clobber (reg:CC FLAGS_REG))]
11941    "TARGET_TBM"
11942    "blci\t{%1, %0|%0, %1}"
11943   [(set_attr "type" "bitmanip")
11944    (set_attr "mode" "<MODE>")])
11946 (define_insn "*tbm_blcic_<mode>"
11947   [(set (match_operand:SWI48 0 "register_operand" "=r")
11948         (and:SWI48
11949           (plus:SWI48
11950             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11951             (const_int 1))
11952           (not:SWI48
11953             (match_dup 1))))
11954    (clobber (reg:CC FLAGS_REG))]
11955    "TARGET_TBM"
11956    "blcic\t{%1, %0|%0, %1}"
11957   [(set_attr "type" "bitmanip")
11958    (set_attr "mode" "<MODE>")])
11960 (define_insn "*tbm_blcmsk_<mode>"
11961   [(set (match_operand:SWI48 0 "register_operand" "=r")
11962         (xor:SWI48
11963           (plus:SWI48
11964             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11965             (const_int 1))
11966           (match_dup 1)))
11967    (clobber (reg:CC FLAGS_REG))]
11968    "TARGET_TBM"
11969    "blcmsk\t{%1, %0|%0, %1}"
11970   [(set_attr "type" "bitmanip")
11971    (set_attr "mode" "<MODE>")])
11973 (define_insn "*tbm_blcs_<mode>"
11974   [(set (match_operand:SWI48 0 "register_operand" "=r")
11975         (ior:SWI48
11976           (plus:SWI48
11977             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11978             (const_int 1))
11979           (match_dup 1)))
11980    (clobber (reg:CC FLAGS_REG))]
11981    "TARGET_TBM"
11982    "blcs\t{%1, %0|%0, %1}"
11983   [(set_attr "type" "bitmanip")
11984    (set_attr "mode" "<MODE>")])
11986 (define_insn "*tbm_blsfill_<mode>"
11987   [(set (match_operand:SWI48 0 "register_operand" "=r")
11988         (ior:SWI48
11989           (plus:SWI48
11990             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11991             (const_int -1))
11992           (match_dup 1)))
11993    (clobber (reg:CC FLAGS_REG))]
11994    "TARGET_TBM"
11995    "blsfill\t{%1, %0|%0, %1}"
11996   [(set_attr "type" "bitmanip")
11997    (set_attr "mode" "<MODE>")])
11999 (define_insn "*tbm_blsic_<mode>"
12000   [(set (match_operand:SWI48 0 "register_operand" "=r")
12001         (ior:SWI48
12002           (plus:SWI48
12003             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12004             (const_int -1))
12005           (not:SWI48
12006             (match_dup 1))))
12007    (clobber (reg:CC FLAGS_REG))]
12008    "TARGET_TBM"
12009    "blsic\t{%1, %0|%0, %1}"
12010   [(set_attr "type" "bitmanip")
12011    (set_attr "mode" "<MODE>")])
12013 (define_insn "*tbm_t1mskc_<mode>"
12014   [(set (match_operand:SWI48 0 "register_operand" "=r")
12015         (ior:SWI48
12016           (plus:SWI48
12017             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12018             (const_int 1))
12019           (not:SWI48
12020             (match_dup 1))))
12021    (clobber (reg:CC FLAGS_REG))]
12022    "TARGET_TBM"
12023    "t1mskc\t{%1, %0|%0, %1}"
12024   [(set_attr "type" "bitmanip")
12025    (set_attr "mode" "<MODE>")])
12027 (define_insn "*tbm_tzmsk_<mode>"
12028   [(set (match_operand:SWI48 0 "register_operand" "=r")
12029         (and:SWI48
12030           (plus:SWI48
12031             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12032             (const_int -1))
12033           (not:SWI48
12034             (match_dup 1))))
12035    (clobber (reg:CC FLAGS_REG))]
12036    "TARGET_TBM"
12037    "tzmsk\t{%1, %0|%0, %1}"
12038   [(set_attr "type" "bitmanip")
12039    (set_attr "mode" "<MODE>")])
12041 (define_insn "bsr_rex64"
12042   [(set (match_operand:DI 0 "register_operand" "=r")
12043         (minus:DI (const_int 63)
12044                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12045    (clobber (reg:CC FLAGS_REG))]
12046   "TARGET_64BIT"
12047   "bsr{q}\t{%1, %0|%0, %1}"
12048   [(set_attr "type" "alu1")
12049    (set_attr "prefix_0f" "1")
12050    (set_attr "mode" "DI")])
12052 (define_insn "bsr"
12053   [(set (match_operand:SI 0 "register_operand" "=r")
12054         (minus:SI (const_int 31)
12055                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12056    (clobber (reg:CC FLAGS_REG))]
12057   ""
12058   "bsr{l}\t{%1, %0|%0, %1}"
12059   [(set_attr "type" "alu1")
12060    (set_attr "prefix_0f" "1")
12061    (set_attr "mode" "SI")])
12063 (define_insn "*bsrhi"
12064   [(set (match_operand:HI 0 "register_operand" "=r")
12065         (minus:HI (const_int 15)
12066                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12067    (clobber (reg:CC FLAGS_REG))]
12068   ""
12069   "bsr{w}\t{%1, %0|%0, %1}"
12070   [(set_attr "type" "alu1")
12071    (set_attr "prefix_0f" "1")
12072    (set_attr "mode" "HI")])
12074 (define_insn "popcount<mode>2"
12075   [(set (match_operand:SWI248 0 "register_operand" "=r")
12076         (popcount:SWI248
12077           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12078    (clobber (reg:CC FLAGS_REG))]
12079   "TARGET_POPCNT"
12081 #if TARGET_MACHO
12082   return "popcnt\t{%1, %0|%0, %1}";
12083 #else
12084   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12085 #endif
12087   [(set_attr "prefix_rep" "1")
12088    (set_attr "type" "bitmanip")
12089    (set_attr "mode" "<MODE>")])
12091 (define_insn "*popcount<mode>2_cmp"
12092   [(set (reg FLAGS_REG)
12093         (compare
12094           (popcount:SWI248
12095             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12096           (const_int 0)))
12097    (set (match_operand:SWI248 0 "register_operand" "=r")
12098         (popcount:SWI248 (match_dup 1)))]
12099   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12101 #if TARGET_MACHO
12102   return "popcnt\t{%1, %0|%0, %1}";
12103 #else
12104   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12105 #endif
12107   [(set_attr "prefix_rep" "1")
12108    (set_attr "type" "bitmanip")
12109    (set_attr "mode" "<MODE>")])
12111 (define_insn "*popcountsi2_cmp_zext"
12112   [(set (reg FLAGS_REG)
12113         (compare
12114           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12115           (const_int 0)))
12116    (set (match_operand:DI 0 "register_operand" "=r")
12117         (zero_extend:DI(popcount:SI (match_dup 1))))]
12118   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12120 #if TARGET_MACHO
12121   return "popcnt\t{%1, %0|%0, %1}";
12122 #else
12123   return "popcnt{l}\t{%1, %0|%0, %1}";
12124 #endif
12126   [(set_attr "prefix_rep" "1")
12127    (set_attr "type" "bitmanip")
12128    (set_attr "mode" "SI")])
12130 (define_expand "bswapdi2"
12131   [(set (match_operand:DI 0 "register_operand")
12132         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12133   "TARGET_64BIT"
12135   if (!TARGET_MOVBE)
12136     operands[1] = force_reg (DImode, operands[1]);
12139 (define_expand "bswapsi2"
12140   [(set (match_operand:SI 0 "register_operand")
12141         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12142   ""
12144   if (TARGET_MOVBE)
12145     ;
12146   else if (TARGET_BSWAP)
12147     operands[1] = force_reg (SImode, operands[1]);
12148   else
12149     {
12150       rtx x = operands[0];
12152       emit_move_insn (x, operands[1]);
12153       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12154       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12155       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12156       DONE;
12157     }
12160 (define_insn "*bswap<mode>2_movbe"
12161   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12162         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12163   "TARGET_MOVBE
12164    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12165   "@
12166     bswap\t%0
12167     movbe\t{%1, %0|%0, %1}
12168     movbe\t{%1, %0|%0, %1}"
12169   [(set_attr "type" "bitmanip,imov,imov")
12170    (set_attr "modrm" "0,1,1")
12171    (set_attr "prefix_0f" "*,1,1")
12172    (set_attr "prefix_extra" "*,1,1")
12173    (set_attr "mode" "<MODE>")])
12175 (define_insn "*bswap<mode>2"
12176   [(set (match_operand:SWI48 0 "register_operand" "=r")
12177         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12178   "TARGET_BSWAP"
12179   "bswap\t%0"
12180   [(set_attr "type" "bitmanip")
12181    (set_attr "modrm" "0")
12182    (set_attr "mode" "<MODE>")])
12184 (define_insn "*bswaphi_lowpart_1"
12185   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12186         (bswap:HI (match_dup 0)))
12187    (clobber (reg:CC FLAGS_REG))]
12188   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12189   "@
12190     xchg{b}\t{%h0, %b0|%b0, %h0}
12191     rol{w}\t{$8, %0|%0, 8}"
12192   [(set_attr "length" "2,4")
12193    (set_attr "mode" "QI,HI")])
12195 (define_insn "bswaphi_lowpart"
12196   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12197         (bswap:HI (match_dup 0)))
12198    (clobber (reg:CC FLAGS_REG))]
12199   ""
12200   "rol{w}\t{$8, %0|%0, 8}"
12201   [(set_attr "length" "4")
12202    (set_attr "mode" "HI")])
12204 (define_expand "paritydi2"
12205   [(set (match_operand:DI 0 "register_operand")
12206         (parity:DI (match_operand:DI 1 "register_operand")))]
12207   "! TARGET_POPCNT"
12209   rtx scratch = gen_reg_rtx (QImode);
12210   rtx cond;
12212   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12213                                 NULL_RTX, operands[1]));
12215   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12216                          gen_rtx_REG (CCmode, FLAGS_REG),
12217                          const0_rtx);
12218   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12220   if (TARGET_64BIT)
12221     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12222   else
12223     {
12224       rtx tmp = gen_reg_rtx (SImode);
12226       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12227       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12228     }
12229   DONE;
12232 (define_expand "paritysi2"
12233   [(set (match_operand:SI 0 "register_operand")
12234         (parity:SI (match_operand:SI 1 "register_operand")))]
12235   "! TARGET_POPCNT"
12237   rtx scratch = gen_reg_rtx (QImode);
12238   rtx cond;
12240   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12242   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12243                          gen_rtx_REG (CCmode, FLAGS_REG),
12244                          const0_rtx);
12245   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12247   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12248   DONE;
12251 (define_insn_and_split "paritydi2_cmp"
12252   [(set (reg:CC FLAGS_REG)
12253         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12254                    UNSPEC_PARITY))
12255    (clobber (match_scratch:DI 0 "=r"))
12256    (clobber (match_scratch:SI 1 "=&r"))
12257    (clobber (match_scratch:HI 2 "=Q"))]
12258   "! TARGET_POPCNT"
12259   "#"
12260   "&& reload_completed"
12261   [(parallel
12262      [(set (match_dup 1)
12263            (xor:SI (match_dup 1) (match_dup 4)))
12264       (clobber (reg:CC FLAGS_REG))])
12265    (parallel
12266      [(set (reg:CC FLAGS_REG)
12267            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12268       (clobber (match_dup 1))
12269       (clobber (match_dup 2))])]
12271   operands[4] = gen_lowpart (SImode, operands[3]);
12273   if (TARGET_64BIT)
12274     {
12275       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12276       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12277     }
12278   else
12279     operands[1] = gen_highpart (SImode, operands[3]);
12282 (define_insn_and_split "paritysi2_cmp"
12283   [(set (reg:CC FLAGS_REG)
12284         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12285                    UNSPEC_PARITY))
12286    (clobber (match_scratch:SI 0 "=r"))
12287    (clobber (match_scratch:HI 1 "=&Q"))]
12288   "! TARGET_POPCNT"
12289   "#"
12290   "&& reload_completed"
12291   [(parallel
12292      [(set (match_dup 1)
12293            (xor:HI (match_dup 1) (match_dup 3)))
12294       (clobber (reg:CC FLAGS_REG))])
12295    (parallel
12296      [(set (reg:CC FLAGS_REG)
12297            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12298       (clobber (match_dup 1))])]
12300   operands[3] = gen_lowpart (HImode, operands[2]);
12302   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12303   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12306 (define_insn "*parityhi2_cmp"
12307   [(set (reg:CC FLAGS_REG)
12308         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12309                    UNSPEC_PARITY))
12310    (clobber (match_scratch:HI 0 "=Q"))]
12311   "! TARGET_POPCNT"
12312   "xor{b}\t{%h0, %b0|%b0, %h0}"
12313   [(set_attr "length" "2")
12314    (set_attr "mode" "HI")])
12317 ;; Thread-local storage patterns for ELF.
12319 ;; Note that these code sequences must appear exactly as shown
12320 ;; in order to allow linker relaxation.
12322 (define_insn "*tls_global_dynamic_32_gnu"
12323   [(set (match_operand:SI 0 "register_operand" "=a")
12324         (unspec:SI
12325          [(match_operand:SI 1 "register_operand" "b")
12326           (match_operand 2 "tls_symbolic_operand")
12327           (match_operand 3 "constant_call_address_operand" "z")]
12328          UNSPEC_TLS_GD))
12329    (clobber (match_scratch:SI 4 "=d"))
12330    (clobber (match_scratch:SI 5 "=c"))
12331    (clobber (reg:CC FLAGS_REG))]
12332   "!TARGET_64BIT && TARGET_GNU_TLS"
12334   output_asm_insn
12335     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12336   if (TARGET_SUN_TLS)
12337 #ifdef HAVE_AS_IX86_TLSGDPLT
12338     return "call\t%a2@tlsgdplt";
12339 #else
12340     return "call\t%p3@plt";
12341 #endif
12342   return "call\t%P3";
12344   [(set_attr "type" "multi")
12345    (set_attr "length" "12")])
12347 (define_expand "tls_global_dynamic_32"
12348   [(parallel
12349     [(set (match_operand:SI 0 "register_operand")
12350           (unspec:SI [(match_operand:SI 2 "register_operand")
12351                       (match_operand 1 "tls_symbolic_operand")
12352                       (match_operand 3 "constant_call_address_operand")]
12353                      UNSPEC_TLS_GD))
12354      (clobber (match_scratch:SI 4))
12355      (clobber (match_scratch:SI 5))
12356      (clobber (reg:CC FLAGS_REG))])])
12358 (define_insn "*tls_global_dynamic_64_<mode>"
12359   [(set (match_operand:P 0 "register_operand" "=a")
12360         (call:P
12361          (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12362          (match_operand 3)))
12363    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12364              UNSPEC_TLS_GD)]
12365   "TARGET_64BIT"
12367   if (!TARGET_X32)
12368     fputs (ASM_BYTE "0x66\n", asm_out_file);
12369   output_asm_insn
12370     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12371   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12372   fputs ("\trex64\n", asm_out_file);
12373   if (TARGET_SUN_TLS)
12374     return "call\t%p2@plt";
12375   return "call\t%P2";
12377   [(set_attr "type" "multi")
12378    (set (attr "length")
12379         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12381 (define_expand "tls_global_dynamic_64_<mode>"
12382   [(parallel
12383     [(set (match_operand:P 0 "register_operand")
12384           (call:P
12385            (mem:QI (match_operand 2 "constant_call_address_operand"))
12386            (const_int 0)))
12387      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12388                UNSPEC_TLS_GD)])]
12389   "TARGET_64BIT")
12391 (define_insn "*tls_local_dynamic_base_32_gnu"
12392   [(set (match_operand:SI 0 "register_operand" "=a")
12393         (unspec:SI
12394          [(match_operand:SI 1 "register_operand" "b")
12395           (match_operand 2 "constant_call_address_operand" "z")]
12396          UNSPEC_TLS_LD_BASE))
12397    (clobber (match_scratch:SI 3 "=d"))
12398    (clobber (match_scratch:SI 4 "=c"))
12399    (clobber (reg:CC FLAGS_REG))]
12400   "!TARGET_64BIT && TARGET_GNU_TLS"
12402   output_asm_insn
12403     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12404   if (TARGET_SUN_TLS)
12405 #ifdef HAVE_AS_IX86_TLSLDMPLT
12406     return "call\t%&@tlsldmplt";
12407 #else
12408     return "call\t%p2@plt";
12409 #endif
12410   return "call\t%P2";
12412   [(set_attr "type" "multi")
12413    (set_attr "length" "11")])
12415 (define_expand "tls_local_dynamic_base_32"
12416   [(parallel
12417      [(set (match_operand:SI 0 "register_operand")
12418            (unspec:SI
12419             [(match_operand:SI 1 "register_operand")
12420              (match_operand 2 "constant_call_address_operand")]
12421             UNSPEC_TLS_LD_BASE))
12422       (clobber (match_scratch:SI 3))
12423       (clobber (match_scratch:SI 4))
12424       (clobber (reg:CC FLAGS_REG))])])
12426 (define_insn "*tls_local_dynamic_base_64_<mode>"
12427   [(set (match_operand:P 0 "register_operand" "=a")
12428         (call:P
12429          (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12430          (match_operand 2)))
12431    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12432   "TARGET_64BIT"
12434   output_asm_insn
12435     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12436   if (TARGET_SUN_TLS)
12437     return "call\t%p1@plt";
12438   return "call\t%P1";
12440   [(set_attr "type" "multi")
12441    (set_attr "length" "12")])
12443 (define_expand "tls_local_dynamic_base_64_<mode>"
12444   [(parallel
12445      [(set (match_operand:P 0 "register_operand")
12446            (call:P
12447             (mem:QI (match_operand 1 "constant_call_address_operand"))
12448             (const_int 0)))
12449       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12450   "TARGET_64BIT")
12452 ;; Local dynamic of a single variable is a lose.  Show combine how
12453 ;; to convert that back to global dynamic.
12455 (define_insn_and_split "*tls_local_dynamic_32_once"
12456   [(set (match_operand:SI 0 "register_operand" "=a")
12457         (plus:SI
12458          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12459                      (match_operand 2 "constant_call_address_operand" "z")]
12460                     UNSPEC_TLS_LD_BASE)
12461          (const:SI (unspec:SI
12462                     [(match_operand 3 "tls_symbolic_operand")]
12463                     UNSPEC_DTPOFF))))
12464    (clobber (match_scratch:SI 4 "=d"))
12465    (clobber (match_scratch:SI 5 "=c"))
12466    (clobber (reg:CC FLAGS_REG))]
12467   ""
12468   "#"
12469   ""
12470   [(parallel
12471      [(set (match_dup 0)
12472            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12473                       UNSPEC_TLS_GD))
12474       (clobber (match_dup 4))
12475       (clobber (match_dup 5))
12476       (clobber (reg:CC FLAGS_REG))])])
12478 ;; Segment register for the thread base ptr load
12479 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12481 ;; Load and add the thread base pointer from %<tp_seg>:0.
12482 (define_insn "*load_tp_x32"
12483   [(set (match_operand:SI 0 "register_operand" "=r")
12484         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12485   "TARGET_X32"
12486   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12487   [(set_attr "type" "imov")
12488    (set_attr "modrm" "0")
12489    (set_attr "length" "7")
12490    (set_attr "memory" "load")
12491    (set_attr "imm_disp" "false")])
12493 (define_insn "*load_tp_x32_zext"
12494   [(set (match_operand:DI 0 "register_operand" "=r")
12495         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12496   "TARGET_X32"
12497   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12498   [(set_attr "type" "imov")
12499    (set_attr "modrm" "0")
12500    (set_attr "length" "7")
12501    (set_attr "memory" "load")
12502    (set_attr "imm_disp" "false")])
12504 (define_insn "*load_tp_<mode>"
12505   [(set (match_operand:P 0 "register_operand" "=r")
12506         (unspec:P [(const_int 0)] UNSPEC_TP))]
12507   "!TARGET_X32"
12508   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12509   [(set_attr "type" "imov")
12510    (set_attr "modrm" "0")
12511    (set_attr "length" "7")
12512    (set_attr "memory" "load")
12513    (set_attr "imm_disp" "false")])
12515 (define_insn "*add_tp_x32"
12516   [(set (match_operand:SI 0 "register_operand" "=r")
12517         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12518                  (match_operand:SI 1 "register_operand" "0")))
12519    (clobber (reg:CC FLAGS_REG))]
12520   "TARGET_X32"
12521   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12522   [(set_attr "type" "alu")
12523    (set_attr "modrm" "0")
12524    (set_attr "length" "7")
12525    (set_attr "memory" "load")
12526    (set_attr "imm_disp" "false")])
12528 (define_insn "*add_tp_x32_zext"
12529   [(set (match_operand:DI 0 "register_operand" "=r")
12530         (zero_extend:DI
12531           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12532                    (match_operand:SI 1 "register_operand" "0"))))
12533    (clobber (reg:CC FLAGS_REG))]
12534   "TARGET_X32"
12535   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12536   [(set_attr "type" "alu")
12537    (set_attr "modrm" "0")
12538    (set_attr "length" "7")
12539    (set_attr "memory" "load")
12540    (set_attr "imm_disp" "false")])
12542 (define_insn "*add_tp_<mode>"
12543   [(set (match_operand:P 0 "register_operand" "=r")
12544         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12545                 (match_operand:P 1 "register_operand" "0")))
12546    (clobber (reg:CC FLAGS_REG))]
12547   "!TARGET_X32"
12548   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12549   [(set_attr "type" "alu")
12550    (set_attr "modrm" "0")
12551    (set_attr "length" "7")
12552    (set_attr "memory" "load")
12553    (set_attr "imm_disp" "false")])
12555 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12556 ;; %rax as destination of the initial executable code sequence.
12557 (define_insn "tls_initial_exec_64_sun"
12558   [(set (match_operand:DI 0 "register_operand" "=a")
12559         (unspec:DI
12560          [(match_operand 1 "tls_symbolic_operand")]
12561          UNSPEC_TLS_IE_SUN))
12562    (clobber (reg:CC FLAGS_REG))]
12563   "TARGET_64BIT && TARGET_SUN_TLS"
12565   output_asm_insn
12566     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12567   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12569   [(set_attr "type" "multi")])
12571 ;; GNU2 TLS patterns can be split.
12573 (define_expand "tls_dynamic_gnu2_32"
12574   [(set (match_dup 3)
12575         (plus:SI (match_operand:SI 2 "register_operand")
12576                  (const:SI
12577                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12578                              UNSPEC_TLSDESC))))
12579    (parallel
12580     [(set (match_operand:SI 0 "register_operand")
12581           (unspec:SI [(match_dup 1) (match_dup 3)
12582                       (match_dup 2) (reg:SI SP_REG)]
12583                       UNSPEC_TLSDESC))
12584      (clobber (reg:CC FLAGS_REG))])]
12585   "!TARGET_64BIT && TARGET_GNU2_TLS"
12587   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12588   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12591 (define_insn "*tls_dynamic_gnu2_lea_32"
12592   [(set (match_operand:SI 0 "register_operand" "=r")
12593         (plus:SI (match_operand:SI 1 "register_operand" "b")
12594                  (const:SI
12595                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12596                               UNSPEC_TLSDESC))))]
12597   "!TARGET_64BIT && TARGET_GNU2_TLS"
12598   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12599   [(set_attr "type" "lea")
12600    (set_attr "mode" "SI")
12601    (set_attr "length" "6")
12602    (set_attr "length_address" "4")])
12604 (define_insn "*tls_dynamic_gnu2_call_32"
12605   [(set (match_operand:SI 0 "register_operand" "=a")
12606         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12607                     (match_operand:SI 2 "register_operand" "0")
12608                     ;; we have to make sure %ebx still points to the GOT
12609                     (match_operand:SI 3 "register_operand" "b")
12610                     (reg:SI SP_REG)]
12611                    UNSPEC_TLSDESC))
12612    (clobber (reg:CC FLAGS_REG))]
12613   "!TARGET_64BIT && TARGET_GNU2_TLS"
12614   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12615   [(set_attr "type" "call")
12616    (set_attr "length" "2")
12617    (set_attr "length_address" "0")])
12619 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12620   [(set (match_operand:SI 0 "register_operand" "=&a")
12621         (plus:SI
12622          (unspec:SI [(match_operand 3 "tls_modbase_operand")
12623                      (match_operand:SI 4)
12624                      (match_operand:SI 2 "register_operand" "b")
12625                      (reg:SI SP_REG)]
12626                     UNSPEC_TLSDESC)
12627          (const:SI (unspec:SI
12628                     [(match_operand 1 "tls_symbolic_operand")]
12629                     UNSPEC_DTPOFF))))
12630    (clobber (reg:CC FLAGS_REG))]
12631   "!TARGET_64BIT && TARGET_GNU2_TLS"
12632   "#"
12633   ""
12634   [(set (match_dup 0) (match_dup 5))]
12636   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12637   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12640 (define_expand "tls_dynamic_gnu2_64"
12641   [(set (match_dup 2)
12642         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12643                    UNSPEC_TLSDESC))
12644    (parallel
12645     [(set (match_operand:DI 0 "register_operand")
12646           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12647                      UNSPEC_TLSDESC))
12648      (clobber (reg:CC FLAGS_REG))])]
12649   "TARGET_64BIT && TARGET_GNU2_TLS"
12651   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12652   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12655 (define_insn "*tls_dynamic_gnu2_lea_64"
12656   [(set (match_operand:DI 0 "register_operand" "=r")
12657         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12658                    UNSPEC_TLSDESC))]
12659   "TARGET_64BIT && TARGET_GNU2_TLS"
12660   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12661   [(set_attr "type" "lea")
12662    (set_attr "mode" "DI")
12663    (set_attr "length" "7")
12664    (set_attr "length_address" "4")])
12666 (define_insn "*tls_dynamic_gnu2_call_64"
12667   [(set (match_operand:DI 0 "register_operand" "=a")
12668         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12669                     (match_operand:DI 2 "register_operand" "0")
12670                     (reg:DI SP_REG)]
12671                    UNSPEC_TLSDESC))
12672    (clobber (reg:CC FLAGS_REG))]
12673   "TARGET_64BIT && TARGET_GNU2_TLS"
12674   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12675   [(set_attr "type" "call")
12676    (set_attr "length" "2")
12677    (set_attr "length_address" "0")])
12679 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12680   [(set (match_operand:DI 0 "register_operand" "=&a")
12681         (plus:DI
12682          (unspec:DI [(match_operand 2 "tls_modbase_operand")
12683                      (match_operand:DI 3)
12684                      (reg:DI SP_REG)]
12685                     UNSPEC_TLSDESC)
12686          (const:DI (unspec:DI
12687                     [(match_operand 1 "tls_symbolic_operand")]
12688                     UNSPEC_DTPOFF))))
12689    (clobber (reg:CC FLAGS_REG))]
12690   "TARGET_64BIT && TARGET_GNU2_TLS"
12691   "#"
12692   ""
12693   [(set (match_dup 0) (match_dup 4))]
12695   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12696   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12699 ;; These patterns match the binary 387 instructions for addM3, subM3,
12700 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12701 ;; SFmode.  The first is the normal insn, the second the same insn but
12702 ;; with one operand a conversion, and the third the same insn but with
12703 ;; the other operand a conversion.  The conversion may be SFmode or
12704 ;; SImode if the target mode DFmode, but only SImode if the target mode
12705 ;; is SFmode.
12707 ;; Gcc is slightly more smart about handling normal two address instructions
12708 ;; so use special patterns for add and mull.
12710 (define_insn "*fop_<mode>_comm_mixed"
12711   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12712         (match_operator:MODEF 3 "binary_fp_operator"
12713           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12714            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12715   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12716    && COMMUTATIVE_ARITH_P (operands[3])
12717    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12718   "* return output_387_binary_op (insn, operands);"
12719   [(set (attr "type")
12720         (if_then_else (eq_attr "alternative" "1,2")
12721            (if_then_else (match_operand:MODEF 3 "mult_operator")
12722               (const_string "ssemul")
12723               (const_string "sseadd"))
12724            (if_then_else (match_operand:MODEF 3 "mult_operator")
12725               (const_string "fmul")
12726               (const_string "fop"))))
12727    (set_attr "isa" "*,noavx,avx")
12728    (set_attr "prefix" "orig,orig,vex")
12729    (set_attr "mode" "<MODE>")])
12731 (define_insn "*fop_<mode>_comm_sse"
12732   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12733         (match_operator:MODEF 3 "binary_fp_operator"
12734           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12735            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12736   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12737    && COMMUTATIVE_ARITH_P (operands[3])
12738    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12739   "* return output_387_binary_op (insn, operands);"
12740   [(set (attr "type")
12741         (if_then_else (match_operand:MODEF 3 "mult_operator")
12742            (const_string "ssemul")
12743            (const_string "sseadd")))
12744    (set_attr "isa" "noavx,avx")
12745    (set_attr "prefix" "orig,vex")
12746    (set_attr "mode" "<MODE>")])
12748 (define_insn "*fop_<mode>_comm_i387"
12749   [(set (match_operand:MODEF 0 "register_operand" "=f")
12750         (match_operator:MODEF 3 "binary_fp_operator"
12751           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12752            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12753   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12754    && COMMUTATIVE_ARITH_P (operands[3])
12755    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12756   "* return output_387_binary_op (insn, operands);"
12757   [(set (attr "type")
12758         (if_then_else (match_operand:MODEF 3 "mult_operator")
12759            (const_string "fmul")
12760            (const_string "fop")))
12761    (set_attr "mode" "<MODE>")])
12763 (define_insn "*fop_<mode>_1_mixed"
12764   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12765         (match_operator:MODEF 3 "binary_fp_operator"
12766           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12767            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12768   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12769    && !COMMUTATIVE_ARITH_P (operands[3])
12770    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12771   "* return output_387_binary_op (insn, operands);"
12772   [(set (attr "type")
12773         (cond [(and (eq_attr "alternative" "2,3")
12774                     (match_operand:MODEF 3 "mult_operator"))
12775                  (const_string "ssemul")
12776                (and (eq_attr "alternative" "2,3")
12777                     (match_operand:MODEF 3 "div_operator"))
12778                  (const_string "ssediv")
12779                (eq_attr "alternative" "2,3")
12780                  (const_string "sseadd")
12781                (match_operand:MODEF 3 "mult_operator")
12782                  (const_string "fmul")
12783                (match_operand:MODEF 3 "div_operator")
12784                  (const_string "fdiv")
12785               ]
12786               (const_string "fop")))
12787    (set_attr "isa" "*,*,noavx,avx")
12788    (set_attr "prefix" "orig,orig,orig,vex")
12789    (set_attr "mode" "<MODE>")])
12791 (define_insn "*rcpsf2_sse"
12792   [(set (match_operand:SF 0 "register_operand" "=x")
12793         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12794                    UNSPEC_RCP))]
12795   "TARGET_SSE_MATH"
12796   "%vrcpss\t{%1, %d0|%d0, %1}"
12797   [(set_attr "type" "sse")
12798    (set_attr "atom_sse_attr" "rcp")
12799    (set_attr "btver2_sse_attr" "rcp")
12800    (set_attr "prefix" "maybe_vex")
12801    (set_attr "mode" "SF")])
12803 (define_insn "*fop_<mode>_1_sse"
12804   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12805         (match_operator:MODEF 3 "binary_fp_operator"
12806           [(match_operand:MODEF 1 "register_operand" "0,x")
12807            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12808   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12809    && !COMMUTATIVE_ARITH_P (operands[3])"
12810   "* return output_387_binary_op (insn, operands);"
12811   [(set (attr "type")
12812         (cond [(match_operand:MODEF 3 "mult_operator")
12813                  (const_string "ssemul")
12814                (match_operand:MODEF 3 "div_operator")
12815                  (const_string "ssediv")
12816               ]
12817               (const_string "sseadd")))
12818    (set_attr "isa" "noavx,avx")
12819    (set_attr "prefix" "orig,vex")
12820    (set_attr "mode" "<MODE>")])
12822 ;; This pattern is not fully shadowed by the pattern above.
12823 (define_insn "*fop_<mode>_1_i387"
12824   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12825         (match_operator:MODEF 3 "binary_fp_operator"
12826           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12827            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12828   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12829    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12830    && !COMMUTATIVE_ARITH_P (operands[3])
12831    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12832   "* return output_387_binary_op (insn, operands);"
12833   [(set (attr "type")
12834         (cond [(match_operand:MODEF 3 "mult_operator")
12835                  (const_string "fmul")
12836                (match_operand:MODEF 3 "div_operator")
12837                  (const_string "fdiv")
12838               ]
12839               (const_string "fop")))
12840    (set_attr "mode" "<MODE>")])
12842 ;; ??? Add SSE splitters for these!
12843 (define_insn "*fop_<MODEF:mode>_2_i387"
12844   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12845         (match_operator:MODEF 3 "binary_fp_operator"
12846           [(float:MODEF
12847              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12848            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12849   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12850    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12851    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12852   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12853   [(set (attr "type")
12854         (cond [(match_operand:MODEF 3 "mult_operator")
12855                  (const_string "fmul")
12856                (match_operand:MODEF 3 "div_operator")
12857                  (const_string "fdiv")
12858               ]
12859               (const_string "fop")))
12860    (set_attr "fp_int_src" "true")
12861    (set_attr "mode" "<SWI24:MODE>")])
12863 (define_insn "*fop_<MODEF:mode>_3_i387"
12864   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12865         (match_operator:MODEF 3 "binary_fp_operator"
12866           [(match_operand:MODEF 1 "register_operand" "0,0")
12867            (float:MODEF
12868              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12869   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12870    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12871    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12872   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12873   [(set (attr "type")
12874         (cond [(match_operand:MODEF 3 "mult_operator")
12875                  (const_string "fmul")
12876                (match_operand:MODEF 3 "div_operator")
12877                  (const_string "fdiv")
12878               ]
12879               (const_string "fop")))
12880    (set_attr "fp_int_src" "true")
12881    (set_attr "mode" "<MODE>")])
12883 (define_insn "*fop_df_4_i387"
12884   [(set (match_operand:DF 0 "register_operand" "=f,f")
12885         (match_operator:DF 3 "binary_fp_operator"
12886            [(float_extend:DF
12887              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12888             (match_operand:DF 2 "register_operand" "0,f")]))]
12889   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12890    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12891    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12892   "* return output_387_binary_op (insn, operands);"
12893   [(set (attr "type")
12894         (cond [(match_operand:DF 3 "mult_operator")
12895                  (const_string "fmul")
12896                (match_operand:DF 3 "div_operator")
12897                  (const_string "fdiv")
12898               ]
12899               (const_string "fop")))
12900    (set_attr "mode" "SF")])
12902 (define_insn "*fop_df_5_i387"
12903   [(set (match_operand:DF 0 "register_operand" "=f,f")
12904         (match_operator:DF 3 "binary_fp_operator"
12905           [(match_operand:DF 1 "register_operand" "0,f")
12906            (float_extend:DF
12907             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12908   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12909    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12910   "* return output_387_binary_op (insn, operands);"
12911   [(set (attr "type")
12912         (cond [(match_operand:DF 3 "mult_operator")
12913                  (const_string "fmul")
12914                (match_operand:DF 3 "div_operator")
12915                  (const_string "fdiv")
12916               ]
12917               (const_string "fop")))
12918    (set_attr "mode" "SF")])
12920 (define_insn "*fop_df_6_i387"
12921   [(set (match_operand:DF 0 "register_operand" "=f,f")
12922         (match_operator:DF 3 "binary_fp_operator"
12923           [(float_extend:DF
12924             (match_operand:SF 1 "register_operand" "0,f"))
12925            (float_extend:DF
12926             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12927   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12928    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12929   "* return output_387_binary_op (insn, operands);"
12930   [(set (attr "type")
12931         (cond [(match_operand:DF 3 "mult_operator")
12932                  (const_string "fmul")
12933                (match_operand:DF 3 "div_operator")
12934                  (const_string "fdiv")
12935               ]
12936               (const_string "fop")))
12937    (set_attr "mode" "SF")])
12939 (define_insn "*fop_xf_comm_i387"
12940   [(set (match_operand:XF 0 "register_operand" "=f")
12941         (match_operator:XF 3 "binary_fp_operator"
12942                         [(match_operand:XF 1 "register_operand" "%0")
12943                          (match_operand:XF 2 "register_operand" "f")]))]
12944   "TARGET_80387
12945    && COMMUTATIVE_ARITH_P (operands[3])"
12946   "* return output_387_binary_op (insn, operands);"
12947   [(set (attr "type")
12948         (if_then_else (match_operand:XF 3 "mult_operator")
12949            (const_string "fmul")
12950            (const_string "fop")))
12951    (set_attr "mode" "XF")])
12953 (define_insn "*fop_xf_1_i387"
12954   [(set (match_operand:XF 0 "register_operand" "=f,f")
12955         (match_operator:XF 3 "binary_fp_operator"
12956                         [(match_operand:XF 1 "register_operand" "0,f")
12957                          (match_operand:XF 2 "register_operand" "f,0")]))]
12958   "TARGET_80387
12959    && !COMMUTATIVE_ARITH_P (operands[3])"
12960   "* return output_387_binary_op (insn, operands);"
12961   [(set (attr "type")
12962         (cond [(match_operand:XF 3 "mult_operator")
12963                  (const_string "fmul")
12964                (match_operand:XF 3 "div_operator")
12965                  (const_string "fdiv")
12966               ]
12967               (const_string "fop")))
12968    (set_attr "mode" "XF")])
12970 (define_insn "*fop_xf_2_i387"
12971   [(set (match_operand:XF 0 "register_operand" "=f,f")
12972         (match_operator:XF 3 "binary_fp_operator"
12973           [(float:XF
12974              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12975            (match_operand:XF 2 "register_operand" "0,0")]))]
12976   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12977   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12978   [(set (attr "type")
12979         (cond [(match_operand:XF 3 "mult_operator")
12980                  (const_string "fmul")
12981                (match_operand:XF 3 "div_operator")
12982                  (const_string "fdiv")
12983               ]
12984               (const_string "fop")))
12985    (set_attr "fp_int_src" "true")
12986    (set_attr "mode" "<MODE>")])
12988 (define_insn "*fop_xf_3_i387"
12989   [(set (match_operand:XF 0 "register_operand" "=f,f")
12990         (match_operator:XF 3 "binary_fp_operator"
12991           [(match_operand:XF 1 "register_operand" "0,0")
12992            (float:XF
12993              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12994   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12995   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12996   [(set (attr "type")
12997         (cond [(match_operand:XF 3 "mult_operator")
12998                  (const_string "fmul")
12999                (match_operand:XF 3 "div_operator")
13000                  (const_string "fdiv")
13001               ]
13002               (const_string "fop")))
13003    (set_attr "fp_int_src" "true")
13004    (set_attr "mode" "<MODE>")])
13006 (define_insn "*fop_xf_4_i387"
13007   [(set (match_operand:XF 0 "register_operand" "=f,f")
13008         (match_operator:XF 3 "binary_fp_operator"
13009            [(float_extend:XF
13010               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13011             (match_operand:XF 2 "register_operand" "0,f")]))]
13012   "TARGET_80387"
13013   "* return output_387_binary_op (insn, operands);"
13014   [(set (attr "type")
13015         (cond [(match_operand:XF 3 "mult_operator")
13016                  (const_string "fmul")
13017                (match_operand:XF 3 "div_operator")
13018                  (const_string "fdiv")
13019               ]
13020               (const_string "fop")))
13021    (set_attr "mode" "<MODE>")])
13023 (define_insn "*fop_xf_5_i387"
13024   [(set (match_operand:XF 0 "register_operand" "=f,f")
13025         (match_operator:XF 3 "binary_fp_operator"
13026           [(match_operand:XF 1 "register_operand" "0,f")
13027            (float_extend:XF
13028              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13029   "TARGET_80387"
13030   "* return output_387_binary_op (insn, operands);"
13031   [(set (attr "type")
13032         (cond [(match_operand:XF 3 "mult_operator")
13033                  (const_string "fmul")
13034                (match_operand:XF 3 "div_operator")
13035                  (const_string "fdiv")
13036               ]
13037               (const_string "fop")))
13038    (set_attr "mode" "<MODE>")])
13040 (define_insn "*fop_xf_6_i387"
13041   [(set (match_operand:XF 0 "register_operand" "=f,f")
13042         (match_operator:XF 3 "binary_fp_operator"
13043           [(float_extend:XF
13044              (match_operand:MODEF 1 "register_operand" "0,f"))
13045            (float_extend:XF
13046              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13047   "TARGET_80387"
13048   "* return output_387_binary_op (insn, operands);"
13049   [(set (attr "type")
13050         (cond [(match_operand:XF 3 "mult_operator")
13051                  (const_string "fmul")
13052                (match_operand:XF 3 "div_operator")
13053                  (const_string "fdiv")
13054               ]
13055               (const_string "fop")))
13056    (set_attr "mode" "<MODE>")])
13058 (define_split
13059   [(set (match_operand 0 "register_operand")
13060         (match_operator 3 "binary_fp_operator"
13061            [(float (match_operand:SWI24 1 "register_operand"))
13062             (match_operand 2 "register_operand")]))]
13063   "reload_completed
13064    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13065    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13066   [(const_int 0)]
13068   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13069   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13070   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13071                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13072                                           GET_MODE (operands[3]),
13073                                           operands[4],
13074                                           operands[2])));
13075   ix86_free_from_memory (GET_MODE (operands[1]));
13076   DONE;
13079 (define_split
13080   [(set (match_operand 0 "register_operand")
13081         (match_operator 3 "binary_fp_operator"
13082            [(match_operand 1 "register_operand")
13083             (float (match_operand:SWI24 2 "register_operand"))]))]
13084   "reload_completed
13085    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13086    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13087   [(const_int 0)]
13089   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13090   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13091   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13092                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13093                                           GET_MODE (operands[3]),
13094                                           operands[1],
13095                                           operands[4])));
13096   ix86_free_from_memory (GET_MODE (operands[2]));
13097   DONE;
13100 ;; FPU special functions.
13102 ;; This pattern implements a no-op XFmode truncation for
13103 ;; all fancy i386 XFmode math functions.
13105 (define_insn "truncxf<mode>2_i387_noop_unspec"
13106   [(set (match_operand:MODEF 0 "register_operand" "=f")
13107         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13108         UNSPEC_TRUNC_NOOP))]
13109   "TARGET_USE_FANCY_MATH_387"
13110   "* return output_387_reg_move (insn, operands);"
13111   [(set_attr "type" "fmov")
13112    (set_attr "mode" "<MODE>")])
13114 (define_insn "sqrtxf2"
13115   [(set (match_operand:XF 0 "register_operand" "=f")
13116         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13117   "TARGET_USE_FANCY_MATH_387"
13118   "fsqrt"
13119   [(set_attr "type" "fpspc")
13120    (set_attr "mode" "XF")
13121    (set_attr "athlon_decode" "direct")
13122    (set_attr "amdfam10_decode" "direct")
13123    (set_attr "bdver1_decode" "direct")])
13125 (define_insn "sqrt_extend<mode>xf2_i387"
13126   [(set (match_operand:XF 0 "register_operand" "=f")
13127         (sqrt:XF
13128           (float_extend:XF
13129             (match_operand:MODEF 1 "register_operand" "0"))))]
13130   "TARGET_USE_FANCY_MATH_387"
13131   "fsqrt"
13132   [(set_attr "type" "fpspc")
13133    (set_attr "mode" "XF")
13134    (set_attr "athlon_decode" "direct")
13135    (set_attr "amdfam10_decode" "direct")
13136    (set_attr "bdver1_decode" "direct")])
13138 (define_insn "*rsqrtsf2_sse"
13139   [(set (match_operand:SF 0 "register_operand" "=x")
13140         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13141                    UNSPEC_RSQRT))]
13142   "TARGET_SSE_MATH"
13143   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13144   [(set_attr "type" "sse")
13145    (set_attr "atom_sse_attr" "rcp")
13146    (set_attr "btver2_sse_attr" "rcp")
13147    (set_attr "prefix" "maybe_vex")
13148    (set_attr "mode" "SF")])
13150 (define_expand "rsqrtsf2"
13151   [(set (match_operand:SF 0 "register_operand")
13152         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13153                    UNSPEC_RSQRT))]
13154   "TARGET_SSE_MATH"
13156   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13157   DONE;
13160 (define_insn "*sqrt<mode>2_sse"
13161   [(set (match_operand:MODEF 0 "register_operand" "=x")
13162         (sqrt:MODEF
13163           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13164   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13165   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13166   [(set_attr "type" "sse")
13167    (set_attr "atom_sse_attr" "sqrt")
13168    (set_attr "btver2_sse_attr" "sqrt")
13169    (set_attr "prefix" "maybe_vex")
13170    (set_attr "mode" "<MODE>")
13171    (set_attr "athlon_decode" "*")
13172    (set_attr "amdfam10_decode" "*")
13173    (set_attr "bdver1_decode" "*")])
13175 (define_expand "sqrt<mode>2"
13176   [(set (match_operand:MODEF 0 "register_operand")
13177         (sqrt:MODEF
13178           (match_operand:MODEF 1 "nonimmediate_operand")))]
13179   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13180    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13182   if (<MODE>mode == SFmode
13183       && TARGET_SSE_MATH
13184       && TARGET_RECIP_SQRT
13185       && !optimize_function_for_size_p (cfun)
13186       && flag_finite_math_only && !flag_trapping_math
13187       && flag_unsafe_math_optimizations)
13188     {
13189       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13190       DONE;
13191     }
13193   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13194     {
13195       rtx op0 = gen_reg_rtx (XFmode);
13196       rtx op1 = force_reg (<MODE>mode, operands[1]);
13198       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13199       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13200       DONE;
13201    }
13204 (define_insn "fpremxf4_i387"
13205   [(set (match_operand:XF 0 "register_operand" "=f")
13206         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13207                     (match_operand:XF 3 "register_operand" "1")]
13208                    UNSPEC_FPREM_F))
13209    (set (match_operand:XF 1 "register_operand" "=u")
13210         (unspec:XF [(match_dup 2) (match_dup 3)]
13211                    UNSPEC_FPREM_U))
13212    (set (reg:CCFP FPSR_REG)
13213         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13214                      UNSPEC_C2_FLAG))]
13215   "TARGET_USE_FANCY_MATH_387"
13216   "fprem"
13217   [(set_attr "type" "fpspc")
13218    (set_attr "mode" "XF")])
13220 (define_expand "fmodxf3"
13221   [(use (match_operand:XF 0 "register_operand"))
13222    (use (match_operand:XF 1 "general_operand"))
13223    (use (match_operand:XF 2 "general_operand"))]
13224   "TARGET_USE_FANCY_MATH_387"
13226   rtx label = gen_label_rtx ();
13228   rtx op1 = gen_reg_rtx (XFmode);
13229   rtx op2 = gen_reg_rtx (XFmode);
13231   emit_move_insn (op2, operands[2]);
13232   emit_move_insn (op1, operands[1]);
13234   emit_label (label);
13235   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13236   ix86_emit_fp_unordered_jump (label);
13237   LABEL_NUSES (label) = 1;
13239   emit_move_insn (operands[0], op1);
13240   DONE;
13243 (define_expand "fmod<mode>3"
13244   [(use (match_operand:MODEF 0 "register_operand"))
13245    (use (match_operand:MODEF 1 "general_operand"))
13246    (use (match_operand:MODEF 2 "general_operand"))]
13247   "TARGET_USE_FANCY_MATH_387"
13249   rtx (*gen_truncxf) (rtx, rtx);
13251   rtx label = gen_label_rtx ();
13253   rtx op1 = gen_reg_rtx (XFmode);
13254   rtx op2 = gen_reg_rtx (XFmode);
13256   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13257   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13259   emit_label (label);
13260   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13261   ix86_emit_fp_unordered_jump (label);
13262   LABEL_NUSES (label) = 1;
13264   /* Truncate the result properly for strict SSE math.  */
13265   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13266       && !TARGET_MIX_SSE_I387)
13267     gen_truncxf = gen_truncxf<mode>2;
13268   else
13269     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13271   emit_insn (gen_truncxf (operands[0], op1));
13272   DONE;
13275 (define_insn "fprem1xf4_i387"
13276   [(set (match_operand:XF 0 "register_operand" "=f")
13277         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13278                     (match_operand:XF 3 "register_operand" "1")]
13279                    UNSPEC_FPREM1_F))
13280    (set (match_operand:XF 1 "register_operand" "=u")
13281         (unspec:XF [(match_dup 2) (match_dup 3)]
13282                    UNSPEC_FPREM1_U))
13283    (set (reg:CCFP FPSR_REG)
13284         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13285                      UNSPEC_C2_FLAG))]
13286   "TARGET_USE_FANCY_MATH_387"
13287   "fprem1"
13288   [(set_attr "type" "fpspc")
13289    (set_attr "mode" "XF")])
13291 (define_expand "remainderxf3"
13292   [(use (match_operand:XF 0 "register_operand"))
13293    (use (match_operand:XF 1 "general_operand"))
13294    (use (match_operand:XF 2 "general_operand"))]
13295   "TARGET_USE_FANCY_MATH_387"
13297   rtx label = gen_label_rtx ();
13299   rtx op1 = gen_reg_rtx (XFmode);
13300   rtx op2 = gen_reg_rtx (XFmode);
13302   emit_move_insn (op2, operands[2]);
13303   emit_move_insn (op1, operands[1]);
13305   emit_label (label);
13306   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13307   ix86_emit_fp_unordered_jump (label);
13308   LABEL_NUSES (label) = 1;
13310   emit_move_insn (operands[0], op1);
13311   DONE;
13314 (define_expand "remainder<mode>3"
13315   [(use (match_operand:MODEF 0 "register_operand"))
13316    (use (match_operand:MODEF 1 "general_operand"))
13317    (use (match_operand:MODEF 2 "general_operand"))]
13318   "TARGET_USE_FANCY_MATH_387"
13320   rtx (*gen_truncxf) (rtx, rtx);
13322   rtx label = gen_label_rtx ();
13324   rtx op1 = gen_reg_rtx (XFmode);
13325   rtx op2 = gen_reg_rtx (XFmode);
13327   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13328   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13330   emit_label (label);
13332   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13333   ix86_emit_fp_unordered_jump (label);
13334   LABEL_NUSES (label) = 1;
13336   /* Truncate the result properly for strict SSE math.  */
13337   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13338       && !TARGET_MIX_SSE_I387)
13339     gen_truncxf = gen_truncxf<mode>2;
13340   else
13341     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13343   emit_insn (gen_truncxf (operands[0], op1));
13344   DONE;
13347 (define_int_iterator SINCOS
13348         [UNSPEC_SIN
13349          UNSPEC_COS])
13351 (define_int_attr sincos
13352         [(UNSPEC_SIN "sin")
13353          (UNSPEC_COS "cos")])
13355 (define_insn "*<sincos>xf2_i387"
13356   [(set (match_operand:XF 0 "register_operand" "=f")
13357         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13358                    SINCOS))]
13359   "TARGET_USE_FANCY_MATH_387
13360    && flag_unsafe_math_optimizations"
13361   "f<sincos>"
13362   [(set_attr "type" "fpspc")
13363    (set_attr "mode" "XF")])
13365 (define_insn "*<sincos>_extend<mode>xf2_i387"
13366   [(set (match_operand:XF 0 "register_operand" "=f")
13367         (unspec:XF [(float_extend:XF
13368                       (match_operand:MODEF 1 "register_operand" "0"))]
13369                    SINCOS))]
13370   "TARGET_USE_FANCY_MATH_387
13371    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13372        || TARGET_MIX_SSE_I387)
13373    && flag_unsafe_math_optimizations"
13374   "f<sincos>"
13375   [(set_attr "type" "fpspc")
13376    (set_attr "mode" "XF")])
13378 ;; When sincos pattern is defined, sin and cos builtin functions will be
13379 ;; expanded to sincos pattern with one of its outputs left unused.
13380 ;; CSE pass will figure out if two sincos patterns can be combined,
13381 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13382 ;; depending on the unused output.
13384 (define_insn "sincosxf3"
13385   [(set (match_operand:XF 0 "register_operand" "=f")
13386         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13387                    UNSPEC_SINCOS_COS))
13388    (set (match_operand:XF 1 "register_operand" "=u")
13389         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13390   "TARGET_USE_FANCY_MATH_387
13391    && flag_unsafe_math_optimizations"
13392   "fsincos"
13393   [(set_attr "type" "fpspc")
13394    (set_attr "mode" "XF")])
13396 (define_split
13397   [(set (match_operand:XF 0 "register_operand")
13398         (unspec:XF [(match_operand:XF 2 "register_operand")]
13399                    UNSPEC_SINCOS_COS))
13400    (set (match_operand:XF 1 "register_operand")
13401         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13402   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13403    && can_create_pseudo_p ()"
13404   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13406 (define_split
13407   [(set (match_operand:XF 0 "register_operand")
13408         (unspec:XF [(match_operand:XF 2 "register_operand")]
13409                    UNSPEC_SINCOS_COS))
13410    (set (match_operand:XF 1 "register_operand")
13411         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13412   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13413    && can_create_pseudo_p ()"
13414   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13416 (define_insn "sincos_extend<mode>xf3_i387"
13417   [(set (match_operand:XF 0 "register_operand" "=f")
13418         (unspec:XF [(float_extend:XF
13419                       (match_operand:MODEF 2 "register_operand" "0"))]
13420                    UNSPEC_SINCOS_COS))
13421    (set (match_operand:XF 1 "register_operand" "=u")
13422         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13423   "TARGET_USE_FANCY_MATH_387
13424    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13425        || TARGET_MIX_SSE_I387)
13426    && flag_unsafe_math_optimizations"
13427   "fsincos"
13428   [(set_attr "type" "fpspc")
13429    (set_attr "mode" "XF")])
13431 (define_split
13432   [(set (match_operand:XF 0 "register_operand")
13433         (unspec:XF [(float_extend:XF
13434                       (match_operand:MODEF 2 "register_operand"))]
13435                    UNSPEC_SINCOS_COS))
13436    (set (match_operand:XF 1 "register_operand")
13437         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13438   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13439    && can_create_pseudo_p ()"
13440   [(set (match_dup 1)
13441         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13443 (define_split
13444   [(set (match_operand:XF 0 "register_operand")
13445         (unspec:XF [(float_extend:XF
13446                       (match_operand:MODEF 2 "register_operand"))]
13447                    UNSPEC_SINCOS_COS))
13448    (set (match_operand:XF 1 "register_operand")
13449         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13450   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13451    && can_create_pseudo_p ()"
13452   [(set (match_dup 0)
13453         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13455 (define_expand "sincos<mode>3"
13456   [(use (match_operand:MODEF 0 "register_operand"))
13457    (use (match_operand:MODEF 1 "register_operand"))
13458    (use (match_operand:MODEF 2 "register_operand"))]
13459   "TARGET_USE_FANCY_MATH_387
13460    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13461        || TARGET_MIX_SSE_I387)
13462    && flag_unsafe_math_optimizations"
13464   rtx op0 = gen_reg_rtx (XFmode);
13465   rtx op1 = gen_reg_rtx (XFmode);
13467   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13468   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13469   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13470   DONE;
13473 (define_insn "fptanxf4_i387"
13474   [(set (match_operand:XF 0 "register_operand" "=f")
13475         (match_operand:XF 3 "const_double_operand" "F"))
13476    (set (match_operand:XF 1 "register_operand" "=u")
13477         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13478                    UNSPEC_TAN))]
13479   "TARGET_USE_FANCY_MATH_387
13480    && flag_unsafe_math_optimizations
13481    && standard_80387_constant_p (operands[3]) == 2"
13482   "fptan"
13483   [(set_attr "type" "fpspc")
13484    (set_attr "mode" "XF")])
13486 (define_insn "fptan_extend<mode>xf4_i387"
13487   [(set (match_operand:MODEF 0 "register_operand" "=f")
13488         (match_operand:MODEF 3 "const_double_operand" "F"))
13489    (set (match_operand:XF 1 "register_operand" "=u")
13490         (unspec:XF [(float_extend:XF
13491                       (match_operand:MODEF 2 "register_operand" "0"))]
13492                    UNSPEC_TAN))]
13493   "TARGET_USE_FANCY_MATH_387
13494    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13495        || TARGET_MIX_SSE_I387)
13496    && flag_unsafe_math_optimizations
13497    && standard_80387_constant_p (operands[3]) == 2"
13498   "fptan"
13499   [(set_attr "type" "fpspc")
13500    (set_attr "mode" "XF")])
13502 (define_expand "tanxf2"
13503   [(use (match_operand:XF 0 "register_operand"))
13504    (use (match_operand:XF 1 "register_operand"))]
13505   "TARGET_USE_FANCY_MATH_387
13506    && flag_unsafe_math_optimizations"
13508   rtx one = gen_reg_rtx (XFmode);
13509   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13511   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13512   DONE;
13515 (define_expand "tan<mode>2"
13516   [(use (match_operand:MODEF 0 "register_operand"))
13517    (use (match_operand:MODEF 1 "register_operand"))]
13518   "TARGET_USE_FANCY_MATH_387
13519    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13520        || TARGET_MIX_SSE_I387)
13521    && flag_unsafe_math_optimizations"
13523   rtx op0 = gen_reg_rtx (XFmode);
13525   rtx one = gen_reg_rtx (<MODE>mode);
13526   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13528   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13529                                              operands[1], op2));
13530   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13531   DONE;
13534 (define_insn "*fpatanxf3_i387"
13535   [(set (match_operand:XF 0 "register_operand" "=f")
13536         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13537                     (match_operand:XF 2 "register_operand" "u")]
13538                    UNSPEC_FPATAN))
13539    (clobber (match_scratch:XF 3 "=2"))]
13540   "TARGET_USE_FANCY_MATH_387
13541    && flag_unsafe_math_optimizations"
13542   "fpatan"
13543   [(set_attr "type" "fpspc")
13544    (set_attr "mode" "XF")])
13546 (define_insn "fpatan_extend<mode>xf3_i387"
13547   [(set (match_operand:XF 0 "register_operand" "=f")
13548         (unspec:XF [(float_extend:XF
13549                       (match_operand:MODEF 1 "register_operand" "0"))
13550                     (float_extend:XF
13551                       (match_operand:MODEF 2 "register_operand" "u"))]
13552                    UNSPEC_FPATAN))
13553    (clobber (match_scratch:XF 3 "=2"))]
13554   "TARGET_USE_FANCY_MATH_387
13555    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13556        || TARGET_MIX_SSE_I387)
13557    && flag_unsafe_math_optimizations"
13558   "fpatan"
13559   [(set_attr "type" "fpspc")
13560    (set_attr "mode" "XF")])
13562 (define_expand "atan2xf3"
13563   [(parallel [(set (match_operand:XF 0 "register_operand")
13564                    (unspec:XF [(match_operand:XF 2 "register_operand")
13565                                (match_operand:XF 1 "register_operand")]
13566                               UNSPEC_FPATAN))
13567               (clobber (match_scratch:XF 3))])]
13568   "TARGET_USE_FANCY_MATH_387
13569    && flag_unsafe_math_optimizations")
13571 (define_expand "atan2<mode>3"
13572   [(use (match_operand:MODEF 0 "register_operand"))
13573    (use (match_operand:MODEF 1 "register_operand"))
13574    (use (match_operand:MODEF 2 "register_operand"))]
13575   "TARGET_USE_FANCY_MATH_387
13576    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13577        || TARGET_MIX_SSE_I387)
13578    && flag_unsafe_math_optimizations"
13580   rtx op0 = gen_reg_rtx (XFmode);
13582   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13583   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13584   DONE;
13587 (define_expand "atanxf2"
13588   [(parallel [(set (match_operand:XF 0 "register_operand")
13589                    (unspec:XF [(match_dup 2)
13590                                (match_operand:XF 1 "register_operand")]
13591                               UNSPEC_FPATAN))
13592               (clobber (match_scratch:XF 3))])]
13593   "TARGET_USE_FANCY_MATH_387
13594    && flag_unsafe_math_optimizations"
13596   operands[2] = gen_reg_rtx (XFmode);
13597   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13600 (define_expand "atan<mode>2"
13601   [(use (match_operand:MODEF 0 "register_operand"))
13602    (use (match_operand:MODEF 1 "register_operand"))]
13603   "TARGET_USE_FANCY_MATH_387
13604    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13605        || TARGET_MIX_SSE_I387)
13606    && flag_unsafe_math_optimizations"
13608   rtx op0 = gen_reg_rtx (XFmode);
13610   rtx op2 = gen_reg_rtx (<MODE>mode);
13611   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13613   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13614   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13615   DONE;
13618 (define_expand "asinxf2"
13619   [(set (match_dup 2)
13620         (mult:XF (match_operand:XF 1 "register_operand")
13621                  (match_dup 1)))
13622    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13623    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13624    (parallel [(set (match_operand:XF 0 "register_operand")
13625                    (unspec:XF [(match_dup 5) (match_dup 1)]
13626                               UNSPEC_FPATAN))
13627               (clobber (match_scratch:XF 6))])]
13628   "TARGET_USE_FANCY_MATH_387
13629    && flag_unsafe_math_optimizations"
13631   int i;
13633   if (optimize_insn_for_size_p ())
13634     FAIL;
13636   for (i = 2; i < 6; i++)
13637     operands[i] = gen_reg_rtx (XFmode);
13639   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13642 (define_expand "asin<mode>2"
13643   [(use (match_operand:MODEF 0 "register_operand"))
13644    (use (match_operand:MODEF 1 "general_operand"))]
13645  "TARGET_USE_FANCY_MATH_387
13646    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13647        || TARGET_MIX_SSE_I387)
13648    && flag_unsafe_math_optimizations"
13650   rtx op0 = gen_reg_rtx (XFmode);
13651   rtx op1 = gen_reg_rtx (XFmode);
13653   if (optimize_insn_for_size_p ())
13654     FAIL;
13656   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13657   emit_insn (gen_asinxf2 (op0, op1));
13658   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13659   DONE;
13662 (define_expand "acosxf2"
13663   [(set (match_dup 2)
13664         (mult:XF (match_operand:XF 1 "register_operand")
13665                  (match_dup 1)))
13666    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13667    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13668    (parallel [(set (match_operand:XF 0 "register_operand")
13669                    (unspec:XF [(match_dup 1) (match_dup 5)]
13670                               UNSPEC_FPATAN))
13671               (clobber (match_scratch:XF 6))])]
13672   "TARGET_USE_FANCY_MATH_387
13673    && flag_unsafe_math_optimizations"
13675   int i;
13677   if (optimize_insn_for_size_p ())
13678     FAIL;
13680   for (i = 2; i < 6; i++)
13681     operands[i] = gen_reg_rtx (XFmode);
13683   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13686 (define_expand "acos<mode>2"
13687   [(use (match_operand:MODEF 0 "register_operand"))
13688    (use (match_operand:MODEF 1 "general_operand"))]
13689  "TARGET_USE_FANCY_MATH_387
13690    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13691        || TARGET_MIX_SSE_I387)
13692    && flag_unsafe_math_optimizations"
13694   rtx op0 = gen_reg_rtx (XFmode);
13695   rtx op1 = gen_reg_rtx (XFmode);
13697   if (optimize_insn_for_size_p ())
13698     FAIL;
13700   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13701   emit_insn (gen_acosxf2 (op0, op1));
13702   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13703   DONE;
13706 (define_insn "fyl2xxf3_i387"
13707   [(set (match_operand:XF 0 "register_operand" "=f")
13708         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13709                     (match_operand:XF 2 "register_operand" "u")]
13710                    UNSPEC_FYL2X))
13711    (clobber (match_scratch:XF 3 "=2"))]
13712   "TARGET_USE_FANCY_MATH_387
13713    && flag_unsafe_math_optimizations"
13714   "fyl2x"
13715   [(set_attr "type" "fpspc")
13716    (set_attr "mode" "XF")])
13718 (define_insn "fyl2x_extend<mode>xf3_i387"
13719   [(set (match_operand:XF 0 "register_operand" "=f")
13720         (unspec:XF [(float_extend:XF
13721                       (match_operand:MODEF 1 "register_operand" "0"))
13722                     (match_operand:XF 2 "register_operand" "u")]
13723                    UNSPEC_FYL2X))
13724    (clobber (match_scratch:XF 3 "=2"))]
13725   "TARGET_USE_FANCY_MATH_387
13726    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13727        || TARGET_MIX_SSE_I387)
13728    && flag_unsafe_math_optimizations"
13729   "fyl2x"
13730   [(set_attr "type" "fpspc")
13731    (set_attr "mode" "XF")])
13733 (define_expand "logxf2"
13734   [(parallel [(set (match_operand:XF 0 "register_operand")
13735                    (unspec:XF [(match_operand:XF 1 "register_operand")
13736                                (match_dup 2)] UNSPEC_FYL2X))
13737               (clobber (match_scratch:XF 3))])]
13738   "TARGET_USE_FANCY_MATH_387
13739    && flag_unsafe_math_optimizations"
13741   operands[2] = gen_reg_rtx (XFmode);
13742   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13745 (define_expand "log<mode>2"
13746   [(use (match_operand:MODEF 0 "register_operand"))
13747    (use (match_operand:MODEF 1 "register_operand"))]
13748   "TARGET_USE_FANCY_MATH_387
13749    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13750        || TARGET_MIX_SSE_I387)
13751    && flag_unsafe_math_optimizations"
13753   rtx op0 = gen_reg_rtx (XFmode);
13755   rtx op2 = gen_reg_rtx (XFmode);
13756   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13758   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13759   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13760   DONE;
13763 (define_expand "log10xf2"
13764   [(parallel [(set (match_operand:XF 0 "register_operand")
13765                    (unspec:XF [(match_operand:XF 1 "register_operand")
13766                                (match_dup 2)] UNSPEC_FYL2X))
13767               (clobber (match_scratch:XF 3))])]
13768   "TARGET_USE_FANCY_MATH_387
13769    && flag_unsafe_math_optimizations"
13771   operands[2] = gen_reg_rtx (XFmode);
13772   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13775 (define_expand "log10<mode>2"
13776   [(use (match_operand:MODEF 0 "register_operand"))
13777    (use (match_operand:MODEF 1 "register_operand"))]
13778   "TARGET_USE_FANCY_MATH_387
13779    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13780        || TARGET_MIX_SSE_I387)
13781    && flag_unsafe_math_optimizations"
13783   rtx op0 = gen_reg_rtx (XFmode);
13785   rtx op2 = gen_reg_rtx (XFmode);
13786   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13788   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13789   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13790   DONE;
13793 (define_expand "log2xf2"
13794   [(parallel [(set (match_operand:XF 0 "register_operand")
13795                    (unspec:XF [(match_operand:XF 1 "register_operand")
13796                                (match_dup 2)] UNSPEC_FYL2X))
13797               (clobber (match_scratch:XF 3))])]
13798   "TARGET_USE_FANCY_MATH_387
13799    && flag_unsafe_math_optimizations"
13801   operands[2] = gen_reg_rtx (XFmode);
13802   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13805 (define_expand "log2<mode>2"
13806   [(use (match_operand:MODEF 0 "register_operand"))
13807    (use (match_operand:MODEF 1 "register_operand"))]
13808   "TARGET_USE_FANCY_MATH_387
13809    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13810        || TARGET_MIX_SSE_I387)
13811    && flag_unsafe_math_optimizations"
13813   rtx op0 = gen_reg_rtx (XFmode);
13815   rtx op2 = gen_reg_rtx (XFmode);
13816   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13818   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13819   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13820   DONE;
13823 (define_insn "fyl2xp1xf3_i387"
13824   [(set (match_operand:XF 0 "register_operand" "=f")
13825         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13826                     (match_operand:XF 2 "register_operand" "u")]
13827                    UNSPEC_FYL2XP1))
13828    (clobber (match_scratch:XF 3 "=2"))]
13829   "TARGET_USE_FANCY_MATH_387
13830    && flag_unsafe_math_optimizations"
13831   "fyl2xp1"
13832   [(set_attr "type" "fpspc")
13833    (set_attr "mode" "XF")])
13835 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13836   [(set (match_operand:XF 0 "register_operand" "=f")
13837         (unspec:XF [(float_extend:XF
13838                       (match_operand:MODEF 1 "register_operand" "0"))
13839                     (match_operand:XF 2 "register_operand" "u")]
13840                    UNSPEC_FYL2XP1))
13841    (clobber (match_scratch:XF 3 "=2"))]
13842   "TARGET_USE_FANCY_MATH_387
13843    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13844        || TARGET_MIX_SSE_I387)
13845    && flag_unsafe_math_optimizations"
13846   "fyl2xp1"
13847   [(set_attr "type" "fpspc")
13848    (set_attr "mode" "XF")])
13850 (define_expand "log1pxf2"
13851   [(use (match_operand:XF 0 "register_operand"))
13852    (use (match_operand:XF 1 "register_operand"))]
13853   "TARGET_USE_FANCY_MATH_387
13854    && flag_unsafe_math_optimizations"
13856   if (optimize_insn_for_size_p ())
13857     FAIL;
13859   ix86_emit_i387_log1p (operands[0], operands[1]);
13860   DONE;
13863 (define_expand "log1p<mode>2"
13864   [(use (match_operand:MODEF 0 "register_operand"))
13865    (use (match_operand:MODEF 1 "register_operand"))]
13866   "TARGET_USE_FANCY_MATH_387
13867    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13868        || TARGET_MIX_SSE_I387)
13869    && flag_unsafe_math_optimizations"
13871   rtx op0;
13873   if (optimize_insn_for_size_p ())
13874     FAIL;
13876   op0 = gen_reg_rtx (XFmode);
13878   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13880   ix86_emit_i387_log1p (op0, operands[1]);
13881   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13882   DONE;
13885 (define_insn "fxtractxf3_i387"
13886   [(set (match_operand:XF 0 "register_operand" "=f")
13887         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13888                    UNSPEC_XTRACT_FRACT))
13889    (set (match_operand:XF 1 "register_operand" "=u")
13890         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13891   "TARGET_USE_FANCY_MATH_387
13892    && flag_unsafe_math_optimizations"
13893   "fxtract"
13894   [(set_attr "type" "fpspc")
13895    (set_attr "mode" "XF")])
13897 (define_insn "fxtract_extend<mode>xf3_i387"
13898   [(set (match_operand:XF 0 "register_operand" "=f")
13899         (unspec:XF [(float_extend:XF
13900                       (match_operand:MODEF 2 "register_operand" "0"))]
13901                    UNSPEC_XTRACT_FRACT))
13902    (set (match_operand:XF 1 "register_operand" "=u")
13903         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13904   "TARGET_USE_FANCY_MATH_387
13905    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13906        || TARGET_MIX_SSE_I387)
13907    && flag_unsafe_math_optimizations"
13908   "fxtract"
13909   [(set_attr "type" "fpspc")
13910    (set_attr "mode" "XF")])
13912 (define_expand "logbxf2"
13913   [(parallel [(set (match_dup 2)
13914                    (unspec:XF [(match_operand:XF 1 "register_operand")]
13915                               UNSPEC_XTRACT_FRACT))
13916               (set (match_operand:XF 0 "register_operand")
13917                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13918   "TARGET_USE_FANCY_MATH_387
13919    && flag_unsafe_math_optimizations"
13920   "operands[2] = gen_reg_rtx (XFmode);")
13922 (define_expand "logb<mode>2"
13923   [(use (match_operand:MODEF 0 "register_operand"))
13924    (use (match_operand:MODEF 1 "register_operand"))]
13925   "TARGET_USE_FANCY_MATH_387
13926    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13927        || TARGET_MIX_SSE_I387)
13928    && flag_unsafe_math_optimizations"
13930   rtx op0 = gen_reg_rtx (XFmode);
13931   rtx op1 = gen_reg_rtx (XFmode);
13933   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13934   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13935   DONE;
13938 (define_expand "ilogbxf2"
13939   [(use (match_operand:SI 0 "register_operand"))
13940    (use (match_operand:XF 1 "register_operand"))]
13941   "TARGET_USE_FANCY_MATH_387
13942    && flag_unsafe_math_optimizations"
13944   rtx op0, op1;
13946   if (optimize_insn_for_size_p ())
13947     FAIL;
13949   op0 = gen_reg_rtx (XFmode);
13950   op1 = gen_reg_rtx (XFmode);
13952   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13953   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13954   DONE;
13957 (define_expand "ilogb<mode>2"
13958   [(use (match_operand:SI 0 "register_operand"))
13959    (use (match_operand:MODEF 1 "register_operand"))]
13960   "TARGET_USE_FANCY_MATH_387
13961    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13962        || TARGET_MIX_SSE_I387)
13963    && flag_unsafe_math_optimizations"
13965   rtx op0, op1;
13967   if (optimize_insn_for_size_p ())
13968     FAIL;
13970   op0 = gen_reg_rtx (XFmode);
13971   op1 = gen_reg_rtx (XFmode);
13973   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13974   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13975   DONE;
13978 (define_insn "*f2xm1xf2_i387"
13979   [(set (match_operand:XF 0 "register_operand" "=f")
13980         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13981                    UNSPEC_F2XM1))]
13982   "TARGET_USE_FANCY_MATH_387
13983    && flag_unsafe_math_optimizations"
13984   "f2xm1"
13985   [(set_attr "type" "fpspc")
13986    (set_attr "mode" "XF")])
13988 (define_insn "*fscalexf4_i387"
13989   [(set (match_operand:XF 0 "register_operand" "=f")
13990         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13991                     (match_operand:XF 3 "register_operand" "1")]
13992                    UNSPEC_FSCALE_FRACT))
13993    (set (match_operand:XF 1 "register_operand" "=u")
13994         (unspec:XF [(match_dup 2) (match_dup 3)]
13995                    UNSPEC_FSCALE_EXP))]
13996   "TARGET_USE_FANCY_MATH_387
13997    && flag_unsafe_math_optimizations"
13998   "fscale"
13999   [(set_attr "type" "fpspc")
14000    (set_attr "mode" "XF")])
14002 (define_expand "expNcorexf3"
14003   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14004                                (match_operand:XF 2 "register_operand")))
14005    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14006    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14007    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14008    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14009    (parallel [(set (match_operand:XF 0 "register_operand")
14010                    (unspec:XF [(match_dup 8) (match_dup 4)]
14011                               UNSPEC_FSCALE_FRACT))
14012               (set (match_dup 9)
14013                    (unspec:XF [(match_dup 8) (match_dup 4)]
14014                               UNSPEC_FSCALE_EXP))])]
14015   "TARGET_USE_FANCY_MATH_387
14016    && flag_unsafe_math_optimizations"
14018   int i;
14020   if (optimize_insn_for_size_p ())
14021     FAIL;
14023   for (i = 3; i < 10; i++)
14024     operands[i] = gen_reg_rtx (XFmode);
14026   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14029 (define_expand "expxf2"
14030   [(use (match_operand:XF 0 "register_operand"))
14031    (use (match_operand:XF 1 "register_operand"))]
14032   "TARGET_USE_FANCY_MATH_387
14033    && flag_unsafe_math_optimizations"
14035   rtx op2;
14037   if (optimize_insn_for_size_p ())
14038     FAIL;
14040   op2 = gen_reg_rtx (XFmode);
14041   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14043   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14044   DONE;
14047 (define_expand "exp<mode>2"
14048   [(use (match_operand:MODEF 0 "register_operand"))
14049    (use (match_operand:MODEF 1 "general_operand"))]
14050  "TARGET_USE_FANCY_MATH_387
14051    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14052        || TARGET_MIX_SSE_I387)
14053    && flag_unsafe_math_optimizations"
14055   rtx op0, op1;
14057   if (optimize_insn_for_size_p ())
14058     FAIL;
14060   op0 = gen_reg_rtx (XFmode);
14061   op1 = gen_reg_rtx (XFmode);
14063   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14064   emit_insn (gen_expxf2 (op0, op1));
14065   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14066   DONE;
14069 (define_expand "exp10xf2"
14070   [(use (match_operand:XF 0 "register_operand"))
14071    (use (match_operand:XF 1 "register_operand"))]
14072   "TARGET_USE_FANCY_MATH_387
14073    && flag_unsafe_math_optimizations"
14075   rtx op2;
14077   if (optimize_insn_for_size_p ())
14078     FAIL;
14080   op2 = gen_reg_rtx (XFmode);
14081   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14083   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14084   DONE;
14087 (define_expand "exp10<mode>2"
14088   [(use (match_operand:MODEF 0 "register_operand"))
14089    (use (match_operand:MODEF 1 "general_operand"))]
14090  "TARGET_USE_FANCY_MATH_387
14091    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14092        || TARGET_MIX_SSE_I387)
14093    && flag_unsafe_math_optimizations"
14095   rtx op0, op1;
14097   if (optimize_insn_for_size_p ())
14098     FAIL;
14100   op0 = gen_reg_rtx (XFmode);
14101   op1 = gen_reg_rtx (XFmode);
14103   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14104   emit_insn (gen_exp10xf2 (op0, op1));
14105   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14106   DONE;
14109 (define_expand "exp2xf2"
14110   [(use (match_operand:XF 0 "register_operand"))
14111    (use (match_operand:XF 1 "register_operand"))]
14112   "TARGET_USE_FANCY_MATH_387
14113    && flag_unsafe_math_optimizations"
14115   rtx op2;
14117   if (optimize_insn_for_size_p ())
14118     FAIL;
14120   op2 = gen_reg_rtx (XFmode);
14121   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14123   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14124   DONE;
14127 (define_expand "exp2<mode>2"
14128   [(use (match_operand:MODEF 0 "register_operand"))
14129    (use (match_operand:MODEF 1 "general_operand"))]
14130  "TARGET_USE_FANCY_MATH_387
14131    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14132        || TARGET_MIX_SSE_I387)
14133    && flag_unsafe_math_optimizations"
14135   rtx op0, op1;
14137   if (optimize_insn_for_size_p ())
14138     FAIL;
14140   op0 = gen_reg_rtx (XFmode);
14141   op1 = gen_reg_rtx (XFmode);
14143   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14144   emit_insn (gen_exp2xf2 (op0, op1));
14145   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14146   DONE;
14149 (define_expand "expm1xf2"
14150   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14151                                (match_dup 2)))
14152    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14153    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14154    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14155    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14156    (parallel [(set (match_dup 7)
14157                    (unspec:XF [(match_dup 6) (match_dup 4)]
14158                               UNSPEC_FSCALE_FRACT))
14159               (set (match_dup 8)
14160                    (unspec:XF [(match_dup 6) (match_dup 4)]
14161                               UNSPEC_FSCALE_EXP))])
14162    (parallel [(set (match_dup 10)
14163                    (unspec:XF [(match_dup 9) (match_dup 8)]
14164                               UNSPEC_FSCALE_FRACT))
14165               (set (match_dup 11)
14166                    (unspec:XF [(match_dup 9) (match_dup 8)]
14167                               UNSPEC_FSCALE_EXP))])
14168    (set (match_dup 12) (minus:XF (match_dup 10)
14169                                  (float_extend:XF (match_dup 13))))
14170    (set (match_operand:XF 0 "register_operand")
14171         (plus:XF (match_dup 12) (match_dup 7)))]
14172   "TARGET_USE_FANCY_MATH_387
14173    && flag_unsafe_math_optimizations"
14175   int i;
14177   if (optimize_insn_for_size_p ())
14178     FAIL;
14180   for (i = 2; i < 13; i++)
14181     operands[i] = gen_reg_rtx (XFmode);
14183   operands[13]
14184     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14186   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14189 (define_expand "expm1<mode>2"
14190   [(use (match_operand:MODEF 0 "register_operand"))
14191    (use (match_operand:MODEF 1 "general_operand"))]
14192  "TARGET_USE_FANCY_MATH_387
14193    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14194        || TARGET_MIX_SSE_I387)
14195    && flag_unsafe_math_optimizations"
14197   rtx op0, op1;
14199   if (optimize_insn_for_size_p ())
14200     FAIL;
14202   op0 = gen_reg_rtx (XFmode);
14203   op1 = gen_reg_rtx (XFmode);
14205   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14206   emit_insn (gen_expm1xf2 (op0, op1));
14207   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14208   DONE;
14211 (define_expand "ldexpxf3"
14212   [(set (match_dup 3)
14213         (float:XF (match_operand:SI 2 "register_operand")))
14214    (parallel [(set (match_operand:XF 0 " register_operand")
14215                    (unspec:XF [(match_operand:XF 1 "register_operand")
14216                                (match_dup 3)]
14217                               UNSPEC_FSCALE_FRACT))
14218               (set (match_dup 4)
14219                    (unspec:XF [(match_dup 1) (match_dup 3)]
14220                               UNSPEC_FSCALE_EXP))])]
14221   "TARGET_USE_FANCY_MATH_387
14222    && flag_unsafe_math_optimizations"
14224   if (optimize_insn_for_size_p ())
14225     FAIL;
14227   operands[3] = gen_reg_rtx (XFmode);
14228   operands[4] = gen_reg_rtx (XFmode);
14231 (define_expand "ldexp<mode>3"
14232   [(use (match_operand:MODEF 0 "register_operand"))
14233    (use (match_operand:MODEF 1 "general_operand"))
14234    (use (match_operand:SI 2 "register_operand"))]
14235  "TARGET_USE_FANCY_MATH_387
14236    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14237        || TARGET_MIX_SSE_I387)
14238    && flag_unsafe_math_optimizations"
14240   rtx op0, op1;
14242   if (optimize_insn_for_size_p ())
14243     FAIL;
14245   op0 = gen_reg_rtx (XFmode);
14246   op1 = gen_reg_rtx (XFmode);
14248   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14249   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14250   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14251   DONE;
14254 (define_expand "scalbxf3"
14255   [(parallel [(set (match_operand:XF 0 " register_operand")
14256                    (unspec:XF [(match_operand:XF 1 "register_operand")
14257                                (match_operand:XF 2 "register_operand")]
14258                               UNSPEC_FSCALE_FRACT))
14259               (set (match_dup 3)
14260                    (unspec:XF [(match_dup 1) (match_dup 2)]
14261                               UNSPEC_FSCALE_EXP))])]
14262   "TARGET_USE_FANCY_MATH_387
14263    && flag_unsafe_math_optimizations"
14265   if (optimize_insn_for_size_p ())
14266     FAIL;
14268   operands[3] = gen_reg_rtx (XFmode);
14271 (define_expand "scalb<mode>3"
14272   [(use (match_operand:MODEF 0 "register_operand"))
14273    (use (match_operand:MODEF 1 "general_operand"))
14274    (use (match_operand:MODEF 2 "general_operand"))]
14275  "TARGET_USE_FANCY_MATH_387
14276    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14277        || TARGET_MIX_SSE_I387)
14278    && flag_unsafe_math_optimizations"
14280   rtx op0, op1, op2;
14282   if (optimize_insn_for_size_p ())
14283     FAIL;
14285   op0 = gen_reg_rtx (XFmode);
14286   op1 = gen_reg_rtx (XFmode);
14287   op2 = gen_reg_rtx (XFmode);
14289   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14290   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14291   emit_insn (gen_scalbxf3 (op0, op1, op2));
14292   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14293   DONE;
14296 (define_expand "significandxf2"
14297   [(parallel [(set (match_operand:XF 0 "register_operand")
14298                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14299                               UNSPEC_XTRACT_FRACT))
14300               (set (match_dup 2)
14301                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14302   "TARGET_USE_FANCY_MATH_387
14303    && flag_unsafe_math_optimizations"
14304   "operands[2] = gen_reg_rtx (XFmode);")
14306 (define_expand "significand<mode>2"
14307   [(use (match_operand:MODEF 0 "register_operand"))
14308    (use (match_operand:MODEF 1 "register_operand"))]
14309   "TARGET_USE_FANCY_MATH_387
14310    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14311        || TARGET_MIX_SSE_I387)
14312    && flag_unsafe_math_optimizations"
14314   rtx op0 = gen_reg_rtx (XFmode);
14315   rtx op1 = gen_reg_rtx (XFmode);
14317   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14318   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14319   DONE;
14323 (define_insn "sse4_1_round<mode>2"
14324   [(set (match_operand:MODEF 0 "register_operand" "=x")
14325         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14326                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14327                       UNSPEC_ROUND))]
14328   "TARGET_ROUND"
14329   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14330   [(set_attr "type" "ssecvt")
14331    (set_attr "prefix_extra" "1")
14332    (set_attr "prefix" "maybe_vex")
14333    (set_attr "mode" "<MODE>")])
14335 (define_insn "rintxf2"
14336   [(set (match_operand:XF 0 "register_operand" "=f")
14337         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14338                    UNSPEC_FRNDINT))]
14339   "TARGET_USE_FANCY_MATH_387
14340    && flag_unsafe_math_optimizations"
14341   "frndint"
14342   [(set_attr "type" "fpspc")
14343    (set_attr "mode" "XF")])
14345 (define_expand "rint<mode>2"
14346   [(use (match_operand:MODEF 0 "register_operand"))
14347    (use (match_operand:MODEF 1 "register_operand"))]
14348   "(TARGET_USE_FANCY_MATH_387
14349     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14350         || TARGET_MIX_SSE_I387)
14351     && flag_unsafe_math_optimizations)
14352    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14353        && !flag_trapping_math)"
14355   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14356       && !flag_trapping_math)
14357     {
14358       if (TARGET_ROUND)
14359         emit_insn (gen_sse4_1_round<mode>2
14360                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14361       else if (optimize_insn_for_size_p ())
14362         FAIL;
14363       else
14364         ix86_expand_rint (operands[0], operands[1]);
14365     }
14366   else
14367     {
14368       rtx op0 = gen_reg_rtx (XFmode);
14369       rtx op1 = gen_reg_rtx (XFmode);
14371       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14372       emit_insn (gen_rintxf2 (op0, op1));
14374       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14375     }
14376   DONE;
14379 (define_expand "round<mode>2"
14380   [(match_operand:X87MODEF 0 "register_operand")
14381    (match_operand:X87MODEF 1 "nonimmediate_operand")]
14382   "(TARGET_USE_FANCY_MATH_387
14383     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14384         || TARGET_MIX_SSE_I387)
14385     && flag_unsafe_math_optimizations)
14386    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14387        && !flag_trapping_math && !flag_rounding_math)"
14389   if (optimize_insn_for_size_p ())
14390     FAIL;
14392   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14393       && !flag_trapping_math && !flag_rounding_math)
14394     {
14395       if (TARGET_ROUND)
14396         {
14397           operands[1] = force_reg (<MODE>mode, operands[1]);
14398           ix86_expand_round_sse4 (operands[0], operands[1]);
14399         }
14400       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14401         ix86_expand_round (operands[0], operands[1]);
14402       else
14403         ix86_expand_rounddf_32 (operands[0], operands[1]);
14404     }
14405   else
14406     {
14407       operands[1] = force_reg (<MODE>mode, operands[1]);
14408       ix86_emit_i387_round (operands[0], operands[1]);
14409     }
14410   DONE;
14413 (define_insn_and_split "*fistdi2_1"
14414   [(set (match_operand:DI 0 "nonimmediate_operand")
14415         (unspec:DI [(match_operand:XF 1 "register_operand")]
14416                    UNSPEC_FIST))]
14417   "TARGET_USE_FANCY_MATH_387
14418    && can_create_pseudo_p ()"
14419   "#"
14420   "&& 1"
14421   [(const_int 0)]
14423   if (memory_operand (operands[0], VOIDmode))
14424     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14425   else
14426     {
14427       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14428       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14429                                          operands[2]));
14430     }
14431   DONE;
14433   [(set_attr "type" "fpspc")
14434    (set_attr "mode" "DI")])
14436 (define_insn "fistdi2"
14437   [(set (match_operand:DI 0 "memory_operand" "=m")
14438         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14439                    UNSPEC_FIST))
14440    (clobber (match_scratch:XF 2 "=&1f"))]
14441   "TARGET_USE_FANCY_MATH_387"
14442   "* return output_fix_trunc (insn, operands, false);"
14443   [(set_attr "type" "fpspc")
14444    (set_attr "mode" "DI")])
14446 (define_insn "fistdi2_with_temp"
14447   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14448         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14449                    UNSPEC_FIST))
14450    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14451    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14452   "TARGET_USE_FANCY_MATH_387"
14453   "#"
14454   [(set_attr "type" "fpspc")
14455    (set_attr "mode" "DI")])
14457 (define_split
14458   [(set (match_operand:DI 0 "register_operand")
14459         (unspec:DI [(match_operand:XF 1 "register_operand")]
14460                    UNSPEC_FIST))
14461    (clobber (match_operand:DI 2 "memory_operand"))
14462    (clobber (match_scratch 3))]
14463   "reload_completed"
14464   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14465               (clobber (match_dup 3))])
14466    (set (match_dup 0) (match_dup 2))])
14468 (define_split
14469   [(set (match_operand:DI 0 "memory_operand")
14470         (unspec:DI [(match_operand:XF 1 "register_operand")]
14471                    UNSPEC_FIST))
14472    (clobber (match_operand:DI 2 "memory_operand"))
14473    (clobber (match_scratch 3))]
14474   "reload_completed"
14475   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14476               (clobber (match_dup 3))])])
14478 (define_insn_and_split "*fist<mode>2_1"
14479   [(set (match_operand:SWI24 0 "register_operand")
14480         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14481                       UNSPEC_FIST))]
14482   "TARGET_USE_FANCY_MATH_387
14483    && can_create_pseudo_p ()"
14484   "#"
14485   "&& 1"
14486   [(const_int 0)]
14488   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14489   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14490                                         operands[2]));
14491   DONE;
14493   [(set_attr "type" "fpspc")
14494    (set_attr "mode" "<MODE>")])
14496 (define_insn "fist<mode>2"
14497   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14498         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14499                       UNSPEC_FIST))]
14500   "TARGET_USE_FANCY_MATH_387"
14501   "* return output_fix_trunc (insn, operands, false);"
14502   [(set_attr "type" "fpspc")
14503    (set_attr "mode" "<MODE>")])
14505 (define_insn "fist<mode>2_with_temp"
14506   [(set (match_operand:SWI24 0 "register_operand" "=r")
14507         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14508                       UNSPEC_FIST))
14509    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14510   "TARGET_USE_FANCY_MATH_387"
14511   "#"
14512   [(set_attr "type" "fpspc")
14513    (set_attr "mode" "<MODE>")])
14515 (define_split
14516   [(set (match_operand:SWI24 0 "register_operand")
14517         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14518                       UNSPEC_FIST))
14519    (clobber (match_operand:SWI24 2 "memory_operand"))]
14520   "reload_completed"
14521   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14522    (set (match_dup 0) (match_dup 2))])
14524 (define_split
14525   [(set (match_operand:SWI24 0 "memory_operand")
14526         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14527                       UNSPEC_FIST))
14528    (clobber (match_operand:SWI24 2 "memory_operand"))]
14529   "reload_completed"
14530   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14532 (define_expand "lrintxf<mode>2"
14533   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14534      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14535                      UNSPEC_FIST))]
14536   "TARGET_USE_FANCY_MATH_387")
14538 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14539   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14540      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14541                    UNSPEC_FIX_NOTRUNC))]
14542   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14544 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14545   [(match_operand:SWI248x 0 "nonimmediate_operand")
14546    (match_operand:X87MODEF 1 "register_operand")]
14547   "(TARGET_USE_FANCY_MATH_387
14548     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14549         || TARGET_MIX_SSE_I387)
14550     && flag_unsafe_math_optimizations)
14551    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14552        && <SWI248x:MODE>mode != HImode 
14553        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14554        && !flag_trapping_math && !flag_rounding_math)"
14556   if (optimize_insn_for_size_p ())
14557     FAIL;
14559   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14560       && <SWI248x:MODE>mode != HImode
14561       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14562       && !flag_trapping_math && !flag_rounding_math)
14563     ix86_expand_lround (operands[0], operands[1]);
14564   else
14565     ix86_emit_i387_round (operands[0], operands[1]);
14566   DONE;
14569 (define_int_iterator FRNDINT_ROUNDING
14570         [UNSPEC_FRNDINT_FLOOR
14571          UNSPEC_FRNDINT_CEIL
14572          UNSPEC_FRNDINT_TRUNC])
14574 (define_int_iterator FIST_ROUNDING
14575         [UNSPEC_FIST_FLOOR
14576          UNSPEC_FIST_CEIL])
14578 ;; Base name for define_insn
14579 (define_int_attr rounding_insn
14580         [(UNSPEC_FRNDINT_FLOOR "floor")
14581          (UNSPEC_FRNDINT_CEIL "ceil")
14582          (UNSPEC_FRNDINT_TRUNC "btrunc")
14583          (UNSPEC_FIST_FLOOR "floor")
14584          (UNSPEC_FIST_CEIL "ceil")])
14586 (define_int_attr rounding
14587         [(UNSPEC_FRNDINT_FLOOR "floor")
14588          (UNSPEC_FRNDINT_CEIL "ceil")
14589          (UNSPEC_FRNDINT_TRUNC "trunc")
14590          (UNSPEC_FIST_FLOOR "floor")
14591          (UNSPEC_FIST_CEIL "ceil")])
14593 (define_int_attr ROUNDING
14594         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14595          (UNSPEC_FRNDINT_CEIL "CEIL")
14596          (UNSPEC_FRNDINT_TRUNC "TRUNC")
14597          (UNSPEC_FIST_FLOOR "FLOOR")
14598          (UNSPEC_FIST_CEIL "CEIL")])
14600 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14601 (define_insn_and_split "frndintxf2_<rounding>"
14602   [(set (match_operand:XF 0 "register_operand")
14603         (unspec:XF [(match_operand:XF 1 "register_operand")]
14604                    FRNDINT_ROUNDING))
14605    (clobber (reg:CC FLAGS_REG))]
14606   "TARGET_USE_FANCY_MATH_387
14607    && flag_unsafe_math_optimizations
14608    && can_create_pseudo_p ()"
14609   "#"
14610   "&& 1"
14611   [(const_int 0)]
14613   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14615   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14616   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14618   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14619                                              operands[2], operands[3]));
14620   DONE;
14622   [(set_attr "type" "frndint")
14623    (set_attr "i387_cw" "<rounding>")
14624    (set_attr "mode" "XF")])
14626 (define_insn "frndintxf2_<rounding>_i387"
14627   [(set (match_operand:XF 0 "register_operand" "=f")
14628         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14629                    FRNDINT_ROUNDING))
14630    (use (match_operand:HI 2 "memory_operand" "m"))
14631    (use (match_operand:HI 3 "memory_operand" "m"))]
14632   "TARGET_USE_FANCY_MATH_387
14633    && flag_unsafe_math_optimizations"
14634   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14635   [(set_attr "type" "frndint")
14636    (set_attr "i387_cw" "<rounding>")
14637    (set_attr "mode" "XF")])
14639 (define_expand "<rounding_insn>xf2"
14640   [(parallel [(set (match_operand:XF 0 "register_operand")
14641                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14642                               FRNDINT_ROUNDING))
14643               (clobber (reg:CC FLAGS_REG))])]
14644   "TARGET_USE_FANCY_MATH_387
14645    && flag_unsafe_math_optimizations
14646    && !optimize_insn_for_size_p ()")
14648 (define_expand "<rounding_insn><mode>2"
14649   [(parallel [(set (match_operand:MODEF 0 "register_operand")
14650                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14651                                  FRNDINT_ROUNDING))
14652               (clobber (reg:CC FLAGS_REG))])]
14653   "(TARGET_USE_FANCY_MATH_387
14654     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14655         || TARGET_MIX_SSE_I387)
14656     && flag_unsafe_math_optimizations)
14657    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14658        && !flag_trapping_math)"
14660   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14661       && !flag_trapping_math)
14662     {
14663       if (TARGET_ROUND)
14664         emit_insn (gen_sse4_1_round<mode>2
14665                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14666       else if (optimize_insn_for_size_p ())
14667         FAIL;
14668       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14669         {
14670           if (ROUND_<ROUNDING> == ROUND_FLOOR)
14671             ix86_expand_floorceil (operands[0], operands[1], true);
14672           else if (ROUND_<ROUNDING> == ROUND_CEIL)
14673             ix86_expand_floorceil (operands[0], operands[1], false);
14674           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14675             ix86_expand_trunc (operands[0], operands[1]);
14676           else
14677             gcc_unreachable ();
14678         }
14679       else
14680         {
14681           if (ROUND_<ROUNDING> == ROUND_FLOOR)
14682             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14683           else if (ROUND_<ROUNDING> == ROUND_CEIL)
14684             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
14685           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14686             ix86_expand_truncdf_32 (operands[0], operands[1]);
14687           else
14688             gcc_unreachable ();
14689         }
14690     }
14691   else
14692     {
14693       rtx op0, op1;
14695       if (optimize_insn_for_size_p ())
14696         FAIL;
14698       op0 = gen_reg_rtx (XFmode);
14699       op1 = gen_reg_rtx (XFmode);
14700       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14701       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
14703       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14704     }
14705   DONE;
14708 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14709 (define_insn_and_split "frndintxf2_mask_pm"
14710   [(set (match_operand:XF 0 "register_operand")
14711         (unspec:XF [(match_operand:XF 1 "register_operand")]
14712                    UNSPEC_FRNDINT_MASK_PM))
14713    (clobber (reg:CC FLAGS_REG))]
14714   "TARGET_USE_FANCY_MATH_387
14715    && flag_unsafe_math_optimizations
14716    && can_create_pseudo_p ()"
14717   "#"
14718   "&& 1"
14719   [(const_int 0)]
14721   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14723   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14724   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14726   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14727                                           operands[2], operands[3]));
14728   DONE;
14730   [(set_attr "type" "frndint")
14731    (set_attr "i387_cw" "mask_pm")
14732    (set_attr "mode" "XF")])
14734 (define_insn "frndintxf2_mask_pm_i387"
14735   [(set (match_operand:XF 0 "register_operand" "=f")
14736         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14737                    UNSPEC_FRNDINT_MASK_PM))
14738    (use (match_operand:HI 2 "memory_operand" "m"))
14739    (use (match_operand:HI 3 "memory_operand" "m"))]
14740   "TARGET_USE_FANCY_MATH_387
14741    && flag_unsafe_math_optimizations"
14742   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14743   [(set_attr "type" "frndint")
14744    (set_attr "i387_cw" "mask_pm")
14745    (set_attr "mode" "XF")])
14747 (define_expand "nearbyintxf2"
14748   [(parallel [(set (match_operand:XF 0 "register_operand")
14749                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14750                               UNSPEC_FRNDINT_MASK_PM))
14751               (clobber (reg:CC FLAGS_REG))])]
14752   "TARGET_USE_FANCY_MATH_387
14753    && flag_unsafe_math_optimizations")
14755 (define_expand "nearbyint<mode>2"
14756   [(use (match_operand:MODEF 0 "register_operand"))
14757    (use (match_operand:MODEF 1 "register_operand"))]
14758   "TARGET_USE_FANCY_MATH_387
14759    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14760        || TARGET_MIX_SSE_I387)
14761    && flag_unsafe_math_optimizations"
14763   rtx op0 = gen_reg_rtx (XFmode);
14764   rtx op1 = gen_reg_rtx (XFmode);
14766   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14767   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14769   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14770   DONE;
14773 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14774 (define_insn_and_split "*fist<mode>2_<rounding>_1"
14775   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14776         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14777                         FIST_ROUNDING))
14778    (clobber (reg:CC FLAGS_REG))]
14779   "TARGET_USE_FANCY_MATH_387
14780    && flag_unsafe_math_optimizations
14781    && can_create_pseudo_p ()"
14782   "#"
14783   "&& 1"
14784   [(const_int 0)]
14786   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14788   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14789   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14790   if (memory_operand (operands[0], VOIDmode))
14791     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
14792                                            operands[2], operands[3]));
14793   else
14794     {
14795       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14796       emit_insn (gen_fist<mode>2_<rounding>_with_temp
14797                   (operands[0], operands[1], operands[2],
14798                    operands[3], operands[4]));
14799     }
14800   DONE;
14802   [(set_attr "type" "fistp")
14803    (set_attr "i387_cw" "<rounding>")
14804    (set_attr "mode" "<MODE>")])
14806 (define_insn "fistdi2_<rounding>"
14807   [(set (match_operand:DI 0 "memory_operand" "=m")
14808         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14809                    FIST_ROUNDING))
14810    (use (match_operand:HI 2 "memory_operand" "m"))
14811    (use (match_operand:HI 3 "memory_operand" "m"))
14812    (clobber (match_scratch:XF 4 "=&1f"))]
14813   "TARGET_USE_FANCY_MATH_387
14814    && flag_unsafe_math_optimizations"
14815   "* return output_fix_trunc (insn, operands, false);"
14816   [(set_attr "type" "fistp")
14817    (set_attr "i387_cw" "<rounding>")
14818    (set_attr "mode" "DI")])
14820 (define_insn "fistdi2_<rounding>_with_temp"
14821   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14822         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14823                    FIST_ROUNDING))
14824    (use (match_operand:HI 2 "memory_operand" "m,m"))
14825    (use (match_operand:HI 3 "memory_operand" "m,m"))
14826    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14827    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14828   "TARGET_USE_FANCY_MATH_387
14829    && flag_unsafe_math_optimizations"
14830   "#"
14831   [(set_attr "type" "fistp")
14832    (set_attr "i387_cw" "<rounding>")
14833    (set_attr "mode" "DI")])
14835 (define_split
14836   [(set (match_operand:DI 0 "register_operand")
14837         (unspec:DI [(match_operand:XF 1 "register_operand")]
14838                    FIST_ROUNDING))
14839    (use (match_operand:HI 2 "memory_operand"))
14840    (use (match_operand:HI 3 "memory_operand"))
14841    (clobber (match_operand:DI 4 "memory_operand"))
14842    (clobber (match_scratch 5))]
14843   "reload_completed"
14844   [(parallel [(set (match_dup 4)
14845                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14846               (use (match_dup 2))
14847               (use (match_dup 3))
14848               (clobber (match_dup 5))])
14849    (set (match_dup 0) (match_dup 4))])
14851 (define_split
14852   [(set (match_operand:DI 0 "memory_operand")
14853         (unspec:DI [(match_operand:XF 1 "register_operand")]
14854                    FIST_ROUNDING))
14855    (use (match_operand:HI 2 "memory_operand"))
14856    (use (match_operand:HI 3 "memory_operand"))
14857    (clobber (match_operand:DI 4 "memory_operand"))
14858    (clobber (match_scratch 5))]
14859   "reload_completed"
14860   [(parallel [(set (match_dup 0)
14861                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14862               (use (match_dup 2))
14863               (use (match_dup 3))
14864               (clobber (match_dup 5))])])
14866 (define_insn "fist<mode>2_<rounding>"
14867   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14868         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14869                       FIST_ROUNDING))
14870    (use (match_operand:HI 2 "memory_operand" "m"))
14871    (use (match_operand:HI 3 "memory_operand" "m"))]
14872   "TARGET_USE_FANCY_MATH_387
14873    && flag_unsafe_math_optimizations"
14874   "* return output_fix_trunc (insn, operands, false);"
14875   [(set_attr "type" "fistp")
14876    (set_attr "i387_cw" "<rounding>")
14877    (set_attr "mode" "<MODE>")])
14879 (define_insn "fist<mode>2_<rounding>_with_temp"
14880   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14881         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14882                       FIST_ROUNDING))
14883    (use (match_operand:HI 2 "memory_operand" "m,m"))
14884    (use (match_operand:HI 3 "memory_operand" "m,m"))
14885    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14886   "TARGET_USE_FANCY_MATH_387
14887    && flag_unsafe_math_optimizations"
14888   "#"
14889   [(set_attr "type" "fistp")
14890    (set_attr "i387_cw" "<rounding>")
14891    (set_attr "mode" "<MODE>")])
14893 (define_split
14894   [(set (match_operand:SWI24 0 "register_operand")
14895         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14896                       FIST_ROUNDING))
14897    (use (match_operand:HI 2 "memory_operand"))
14898    (use (match_operand:HI 3 "memory_operand"))
14899    (clobber (match_operand:SWI24 4 "memory_operand"))]
14900   "reload_completed"
14901   [(parallel [(set (match_dup 4)
14902                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14903               (use (match_dup 2))
14904               (use (match_dup 3))])
14905    (set (match_dup 0) (match_dup 4))])
14907 (define_split
14908   [(set (match_operand:SWI24 0 "memory_operand")
14909         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14910                       FIST_ROUNDING))
14911    (use (match_operand:HI 2 "memory_operand"))
14912    (use (match_operand:HI 3 "memory_operand"))
14913    (clobber (match_operand:SWI24 4 "memory_operand"))]
14914   "reload_completed"
14915   [(parallel [(set (match_dup 0)
14916                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14917               (use (match_dup 2))
14918               (use (match_dup 3))])])
14920 (define_expand "l<rounding_insn>xf<mode>2"
14921   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14922                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14923                                    FIST_ROUNDING))
14924               (clobber (reg:CC FLAGS_REG))])]
14925   "TARGET_USE_FANCY_MATH_387
14926    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14927    && flag_unsafe_math_optimizations")
14929 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
14930   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
14931                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14932                                  FIST_ROUNDING))
14933               (clobber (reg:CC FLAGS_REG))])]
14934   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14935    && !flag_trapping_math"
14937   if (TARGET_64BIT && optimize_insn_for_size_p ())
14938     FAIL;
14940   if (ROUND_<ROUNDING> == ROUND_FLOOR)
14941     ix86_expand_lfloorceil (operands[0], operands[1], true);
14942   else if (ROUND_<ROUNDING> == ROUND_CEIL)
14943     ix86_expand_lfloorceil (operands[0], operands[1], false);
14944   else
14945     gcc_unreachable ();
14947   DONE;
14950 (define_insn "fxam<mode>2_i387"
14951   [(set (match_operand:HI 0 "register_operand" "=a")
14952         (unspec:HI
14953           [(match_operand:X87MODEF 1 "register_operand" "f")]
14954           UNSPEC_FXAM))]
14955   "TARGET_USE_FANCY_MATH_387"
14956   "fxam\n\tfnstsw\t%0"
14957   [(set_attr "type" "multi")
14958    (set_attr "length" "4")
14959    (set_attr "unit" "i387")
14960    (set_attr "mode" "<MODE>")])
14962 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14963   [(set (match_operand:HI 0 "register_operand")
14964         (unspec:HI
14965           [(match_operand:MODEF 1 "memory_operand")]
14966           UNSPEC_FXAM_MEM))]
14967   "TARGET_USE_FANCY_MATH_387
14968    && can_create_pseudo_p ()"
14969   "#"
14970   "&& 1"
14971   [(set (match_dup 2)(match_dup 1))
14972    (set (match_dup 0)
14973         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14975   operands[2] = gen_reg_rtx (<MODE>mode);
14977   MEM_VOLATILE_P (operands[1]) = 1;
14979   [(set_attr "type" "multi")
14980    (set_attr "unit" "i387")
14981    (set_attr "mode" "<MODE>")])
14983 (define_expand "isinfxf2"
14984   [(use (match_operand:SI 0 "register_operand"))
14985    (use (match_operand:XF 1 "register_operand"))]
14986   "TARGET_USE_FANCY_MATH_387
14987    && TARGET_C99_FUNCTIONS"
14989   rtx mask = GEN_INT (0x45);
14990   rtx val = GEN_INT (0x05);
14992   rtx cond;
14994   rtx scratch = gen_reg_rtx (HImode);
14995   rtx res = gen_reg_rtx (QImode);
14997   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14999   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15000   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15001   cond = gen_rtx_fmt_ee (EQ, QImode,
15002                          gen_rtx_REG (CCmode, FLAGS_REG),
15003                          const0_rtx);
15004   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15005   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15006   DONE;
15009 (define_expand "isinf<mode>2"
15010   [(use (match_operand:SI 0 "register_operand"))
15011    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15012   "TARGET_USE_FANCY_MATH_387
15013    && TARGET_C99_FUNCTIONS
15014    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15016   rtx mask = GEN_INT (0x45);
15017   rtx val = GEN_INT (0x05);
15019   rtx cond;
15021   rtx scratch = gen_reg_rtx (HImode);
15022   rtx res = gen_reg_rtx (QImode);
15024   /* Remove excess precision by forcing value through memory. */
15025   if (memory_operand (operands[1], VOIDmode))
15026     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15027   else
15028     {
15029       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15031       emit_move_insn (temp, operands[1]);
15032       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15033     }
15035   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15036   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15037   cond = gen_rtx_fmt_ee (EQ, QImode,
15038                          gen_rtx_REG (CCmode, FLAGS_REG),
15039                          const0_rtx);
15040   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15041   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15042   DONE;
15045 (define_expand "signbitxf2"
15046   [(use (match_operand:SI 0 "register_operand"))
15047    (use (match_operand:XF 1 "register_operand"))]
15048   "TARGET_USE_FANCY_MATH_387"
15050   rtx scratch = gen_reg_rtx (HImode);
15052   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15053   emit_insn (gen_andsi3 (operands[0],
15054              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15055   DONE;
15058 (define_insn "movmsk_df"
15059   [(set (match_operand:SI 0 "register_operand" "=r")
15060         (unspec:SI
15061           [(match_operand:DF 1 "register_operand" "x")]
15062           UNSPEC_MOVMSK))]
15063   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15064   "%vmovmskpd\t{%1, %0|%0, %1}"
15065   [(set_attr "type" "ssemov")
15066    (set_attr "prefix" "maybe_vex")
15067    (set_attr "mode" "DF")])
15069 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15070 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15071 (define_expand "signbitdf2"
15072   [(use (match_operand:SI 0 "register_operand"))
15073    (use (match_operand:DF 1 "register_operand"))]
15074   "TARGET_USE_FANCY_MATH_387
15075    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15077   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15078     {
15079       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15080       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15081     }
15082   else
15083     {
15084       rtx scratch = gen_reg_rtx (HImode);
15086       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15087       emit_insn (gen_andsi3 (operands[0],
15088                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15089     }
15090   DONE;
15093 (define_expand "signbitsf2"
15094   [(use (match_operand:SI 0 "register_operand"))
15095    (use (match_operand:SF 1 "register_operand"))]
15096   "TARGET_USE_FANCY_MATH_387
15097    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15099   rtx scratch = gen_reg_rtx (HImode);
15101   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15102   emit_insn (gen_andsi3 (operands[0],
15103              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15104   DONE;
15107 ;; Block operation instructions
15109 (define_insn "cld"
15110   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15111   ""
15112   "cld"
15113   [(set_attr "length" "1")
15114    (set_attr "length_immediate" "0")
15115    (set_attr "modrm" "0")])
15117 (define_expand "movmem<mode>"
15118   [(use (match_operand:BLK 0 "memory_operand"))
15119    (use (match_operand:BLK 1 "memory_operand"))
15120    (use (match_operand:SWI48 2 "nonmemory_operand"))
15121    (use (match_operand:SWI48 3 "const_int_operand"))
15122    (use (match_operand:SI 4 "const_int_operand"))
15123    (use (match_operand:SI 5 "const_int_operand"))]
15124   ""
15126  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15127                          operands[4], operands[5]))
15128    DONE;
15129  else
15130    FAIL;
15133 ;; Most CPUs don't like single string operations
15134 ;; Handle this case here to simplify previous expander.
15136 (define_expand "strmov"
15137   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15138    (set (match_operand 1 "memory_operand") (match_dup 4))
15139    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15140               (clobber (reg:CC FLAGS_REG))])
15141    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15142               (clobber (reg:CC FLAGS_REG))])]
15143   ""
15145   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15147   /* If .md ever supports :P for Pmode, these can be directly
15148      in the pattern above.  */
15149   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15150   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15152   /* Can't use this if the user has appropriated esi or edi.  */
15153   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15154       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15155     {
15156       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15157                                       operands[2], operands[3],
15158                                       operands[5], operands[6]));
15159       DONE;
15160     }
15162   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15165 (define_expand "strmov_singleop"
15166   [(parallel [(set (match_operand 1 "memory_operand")
15167                    (match_operand 3 "memory_operand"))
15168               (set (match_operand 0 "register_operand")
15169                    (match_operand 4))
15170               (set (match_operand 2 "register_operand")
15171                    (match_operand 5))])]
15172   ""
15173   "ix86_current_function_needs_cld = 1;")
15175 (define_insn "*strmovdi_rex_1"
15176   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15177         (mem:DI (match_operand:P 3 "register_operand" "1")))
15178    (set (match_operand:P 0 "register_operand" "=D")
15179         (plus:P (match_dup 2)
15180                 (const_int 8)))
15181    (set (match_operand:P 1 "register_operand" "=S")
15182         (plus:P (match_dup 3)
15183                 (const_int 8)))]
15184   "TARGET_64BIT
15185    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15186   "%^movsq"
15187   [(set_attr "type" "str")
15188    (set_attr "memory" "both")
15189    (set_attr "mode" "DI")])
15191 (define_insn "*strmovsi_1"
15192   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15193         (mem:SI (match_operand:P 3 "register_operand" "1")))
15194    (set (match_operand:P 0 "register_operand" "=D")
15195         (plus:P (match_dup 2)
15196                 (const_int 4)))
15197    (set (match_operand:P 1 "register_operand" "=S")
15198         (plus:P (match_dup 3)
15199                 (const_int 4)))]
15200   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15201   "%^movs{l|d}"
15202   [(set_attr "type" "str")
15203    (set_attr "memory" "both")
15204    (set_attr "mode" "SI")])
15206 (define_insn "*strmovhi_1"
15207   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15208         (mem:HI (match_operand:P 3 "register_operand" "1")))
15209    (set (match_operand:P 0 "register_operand" "=D")
15210         (plus:P (match_dup 2)
15211                 (const_int 2)))
15212    (set (match_operand:P 1 "register_operand" "=S")
15213         (plus:P (match_dup 3)
15214                 (const_int 2)))]
15215   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15216   "%^movsw"
15217   [(set_attr "type" "str")
15218    (set_attr "memory" "both")
15219    (set_attr "mode" "HI")])
15221 (define_insn "*strmovqi_1"
15222   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15223         (mem:QI (match_operand:P 3 "register_operand" "1")))
15224    (set (match_operand:P 0 "register_operand" "=D")
15225         (plus:P (match_dup 2)
15226                 (const_int 1)))
15227    (set (match_operand:P 1 "register_operand" "=S")
15228         (plus:P (match_dup 3)
15229                 (const_int 1)))]
15230   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15231   "%^movsb"
15232   [(set_attr "type" "str")
15233    (set_attr "memory" "both")
15234    (set (attr "prefix_rex")
15235         (if_then_else
15236           (match_test "<P:MODE>mode == DImode")
15237           (const_string "0")
15238           (const_string "*")))
15239    (set_attr "mode" "QI")])
15241 (define_expand "rep_mov"
15242   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15243               (set (match_operand 0 "register_operand")
15244                    (match_operand 5))
15245               (set (match_operand 2 "register_operand")
15246                    (match_operand 6))
15247               (set (match_operand 1 "memory_operand")
15248                    (match_operand 3 "memory_operand"))
15249               (use (match_dup 4))])]
15250   ""
15251   "ix86_current_function_needs_cld = 1;")
15253 (define_insn "*rep_movdi_rex64"
15254   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15255    (set (match_operand:P 0 "register_operand" "=D")
15256         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15257                           (const_int 3))
15258                 (match_operand:P 3 "register_operand" "0")))
15259    (set (match_operand:P 1 "register_operand" "=S")
15260         (plus:P (ashift:P (match_dup 5) (const_int 3))
15261                 (match_operand:P 4 "register_operand" "1")))
15262    (set (mem:BLK (match_dup 3))
15263         (mem:BLK (match_dup 4)))
15264    (use (match_dup 5))]
15265   "TARGET_64BIT
15266    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15267   "%^rep{%;} movsq"
15268   [(set_attr "type" "str")
15269    (set_attr "prefix_rep" "1")
15270    (set_attr "memory" "both")
15271    (set_attr "mode" "DI")])
15273 (define_insn "*rep_movsi"
15274   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15275    (set (match_operand:P 0 "register_operand" "=D")
15276         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15277                           (const_int 2))
15278                  (match_operand:P 3 "register_operand" "0")))
15279    (set (match_operand:P 1 "register_operand" "=S")
15280         (plus:P (ashift:P (match_dup 5) (const_int 2))
15281                 (match_operand:P 4 "register_operand" "1")))
15282    (set (mem:BLK (match_dup 3))
15283         (mem:BLK (match_dup 4)))
15284    (use (match_dup 5))]
15285   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15286   "%^rep{%;} movs{l|d}"
15287   [(set_attr "type" "str")
15288    (set_attr "prefix_rep" "1")
15289    (set_attr "memory" "both")
15290    (set_attr "mode" "SI")])
15292 (define_insn "*rep_movqi"
15293   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15294    (set (match_operand:P 0 "register_operand" "=D")
15295         (plus:P (match_operand:P 3 "register_operand" "0")
15296                 (match_operand:P 5 "register_operand" "2")))
15297    (set (match_operand:P 1 "register_operand" "=S")
15298         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15299    (set (mem:BLK (match_dup 3))
15300         (mem:BLK (match_dup 4)))
15301    (use (match_dup 5))]
15302   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15303   "%^rep{%;} movsb"
15304   [(set_attr "type" "str")
15305    (set_attr "prefix_rep" "1")
15306    (set_attr "memory" "both")
15307    (set_attr "mode" "QI")])
15309 (define_expand "setmem<mode>"
15310    [(use (match_operand:BLK 0 "memory_operand"))
15311     (use (match_operand:SWI48 1 "nonmemory_operand"))
15312     (use (match_operand:QI 2 "nonmemory_operand"))
15313     (use (match_operand 3 "const_int_operand"))
15314     (use (match_operand:SI 4 "const_int_operand"))
15315     (use (match_operand:SI 5 "const_int_operand"))]
15316   ""
15318  if (ix86_expand_setmem (operands[0], operands[1],
15319                          operands[2], operands[3],
15320                          operands[4], operands[5]))
15321    DONE;
15322  else
15323    FAIL;
15326 ;; Most CPUs don't like single string operations
15327 ;; Handle this case here to simplify previous expander.
15329 (define_expand "strset"
15330   [(set (match_operand 1 "memory_operand")
15331         (match_operand 2 "register_operand"))
15332    (parallel [(set (match_operand 0 "register_operand")
15333                    (match_dup 3))
15334               (clobber (reg:CC FLAGS_REG))])]
15335   ""
15337   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15338     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15340   /* If .md ever supports :P for Pmode, this can be directly
15341      in the pattern above.  */
15342   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15343                               GEN_INT (GET_MODE_SIZE (GET_MODE
15344                                                       (operands[2]))));
15345   /* Can't use this if the user has appropriated eax or edi.  */
15346   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15347       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15348     {
15349       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15350                                       operands[3]));
15351       DONE;
15352     }
15355 (define_expand "strset_singleop"
15356   [(parallel [(set (match_operand 1 "memory_operand")
15357                    (match_operand 2 "register_operand"))
15358               (set (match_operand 0 "register_operand")
15359                    (match_operand 3))
15360               (unspec [(const_int 0)] UNSPEC_STOS)])]
15361   ""
15362   "ix86_current_function_needs_cld = 1;")
15364 (define_insn "*strsetdi_rex_1"
15365   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15366         (match_operand:DI 2 "register_operand" "a"))
15367    (set (match_operand:P 0 "register_operand" "=D")
15368         (plus:P (match_dup 1)
15369                 (const_int 8)))
15370    (unspec [(const_int 0)] UNSPEC_STOS)]
15371   "TARGET_64BIT
15372    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15373   "%^stosq"
15374   [(set_attr "type" "str")
15375    (set_attr "memory" "store")
15376    (set_attr "mode" "DI")])
15378 (define_insn "*strsetsi_1"
15379   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15380         (match_operand:SI 2 "register_operand" "a"))
15381    (set (match_operand:P 0 "register_operand" "=D")
15382         (plus:P (match_dup 1)
15383                 (const_int 4)))
15384    (unspec [(const_int 0)] UNSPEC_STOS)]
15385   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15386   "%^stos{l|d}"
15387   [(set_attr "type" "str")
15388    (set_attr "memory" "store")
15389    (set_attr "mode" "SI")])
15391 (define_insn "*strsethi_1"
15392   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15393         (match_operand:HI 2 "register_operand" "a"))
15394    (set (match_operand:P 0 "register_operand" "=D")
15395         (plus:P (match_dup 1)
15396                 (const_int 2)))
15397    (unspec [(const_int 0)] UNSPEC_STOS)]
15398   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15399   "%^stosw"
15400   [(set_attr "type" "str")
15401    (set_attr "memory" "store")
15402    (set_attr "mode" "HI")])
15404 (define_insn "*strsetqi_1"
15405   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15406         (match_operand:QI 2 "register_operand" "a"))
15407    (set (match_operand:P 0 "register_operand" "=D")
15408         (plus:P (match_dup 1)
15409                 (const_int 1)))
15410    (unspec [(const_int 0)] UNSPEC_STOS)]
15411   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15412   "%^stosb"
15413   [(set_attr "type" "str")
15414    (set_attr "memory" "store")
15415    (set (attr "prefix_rex")
15416         (if_then_else
15417           (match_test "<P:MODE>mode == DImode")
15418           (const_string "0")
15419           (const_string "*")))
15420    (set_attr "mode" "QI")])
15422 (define_expand "rep_stos"
15423   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15424               (set (match_operand 0 "register_operand")
15425                    (match_operand 4))
15426               (set (match_operand 2 "memory_operand") (const_int 0))
15427               (use (match_operand 3 "register_operand"))
15428               (use (match_dup 1))])]
15429   ""
15430   "ix86_current_function_needs_cld = 1;")
15432 (define_insn "*rep_stosdi_rex64"
15433   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15434    (set (match_operand:P 0 "register_operand" "=D")
15435         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15436                           (const_int 3))
15437                  (match_operand:P 3 "register_operand" "0")))
15438    (set (mem:BLK (match_dup 3))
15439         (const_int 0))
15440    (use (match_operand:DI 2 "register_operand" "a"))
15441    (use (match_dup 4))]
15442   "TARGET_64BIT
15443    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15444   "%^rep{%;} stosq"
15445   [(set_attr "type" "str")
15446    (set_attr "prefix_rep" "1")
15447    (set_attr "memory" "store")
15448    (set_attr "mode" "DI")])
15450 (define_insn "*rep_stossi"
15451   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15452    (set (match_operand:P 0 "register_operand" "=D")
15453         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15454                           (const_int 2))
15455                  (match_operand:P 3 "register_operand" "0")))
15456    (set (mem:BLK (match_dup 3))
15457         (const_int 0))
15458    (use (match_operand:SI 2 "register_operand" "a"))
15459    (use (match_dup 4))]
15460   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15461   "%^rep{%;} stos{l|d}"
15462   [(set_attr "type" "str")
15463    (set_attr "prefix_rep" "1")
15464    (set_attr "memory" "store")
15465    (set_attr "mode" "SI")])
15467 (define_insn "*rep_stosqi"
15468   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15469    (set (match_operand:P 0 "register_operand" "=D")
15470         (plus:P (match_operand:P 3 "register_operand" "0")
15471                 (match_operand:P 4 "register_operand" "1")))
15472    (set (mem:BLK (match_dup 3))
15473         (const_int 0))
15474    (use (match_operand:QI 2 "register_operand" "a"))
15475    (use (match_dup 4))]
15476   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15477   "%^rep{%;} stosb"
15478   [(set_attr "type" "str")
15479    (set_attr "prefix_rep" "1")
15480    (set_attr "memory" "store")
15481    (set (attr "prefix_rex")
15482         (if_then_else
15483           (match_test "<P:MODE>mode == DImode")
15484           (const_string "0")
15485           (const_string "*")))
15486    (set_attr "mode" "QI")])
15488 (define_expand "cmpstrnsi"
15489   [(set (match_operand:SI 0 "register_operand")
15490         (compare:SI (match_operand:BLK 1 "general_operand")
15491                     (match_operand:BLK 2 "general_operand")))
15492    (use (match_operand 3 "general_operand"))
15493    (use (match_operand 4 "immediate_operand"))]
15494   ""
15496   rtx addr1, addr2, out, outlow, count, countreg, align;
15498   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15499     FAIL;
15501   /* Can't use this if the user has appropriated ecx, esi or edi.  */
15502   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15503     FAIL;
15505   out = operands[0];
15506   if (!REG_P (out))
15507     out = gen_reg_rtx (SImode);
15509   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15510   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15511   if (addr1 != XEXP (operands[1], 0))
15512     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15513   if (addr2 != XEXP (operands[2], 0))
15514     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15516   count = operands[3];
15517   countreg = ix86_zero_extend_to_Pmode (count);
15519   /* %%% Iff we are testing strict equality, we can use known alignment
15520      to good advantage.  This may be possible with combine, particularly
15521      once cc0 is dead.  */
15522   align = operands[4];
15524   if (CONST_INT_P (count))
15525     {
15526       if (INTVAL (count) == 0)
15527         {
15528           emit_move_insn (operands[0], const0_rtx);
15529           DONE;
15530         }
15531       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15532                                      operands[1], operands[2]));
15533     }
15534   else
15535     {
15536       rtx (*gen_cmp) (rtx, rtx);
15538       gen_cmp = (TARGET_64BIT
15539                  ? gen_cmpdi_1 : gen_cmpsi_1);
15541       emit_insn (gen_cmp (countreg, countreg));
15542       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15543                                   operands[1], operands[2]));
15544     }
15546   outlow = gen_lowpart (QImode, out);
15547   emit_insn (gen_cmpintqi (outlow));
15548   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15550   if (operands[0] != out)
15551     emit_move_insn (operands[0], out);
15553   DONE;
15556 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15558 (define_expand "cmpintqi"
15559   [(set (match_dup 1)
15560         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15561    (set (match_dup 2)
15562         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15563    (parallel [(set (match_operand:QI 0 "register_operand")
15564                    (minus:QI (match_dup 1)
15565                              (match_dup 2)))
15566               (clobber (reg:CC FLAGS_REG))])]
15567   ""
15569   operands[1] = gen_reg_rtx (QImode);
15570   operands[2] = gen_reg_rtx (QImode);
15573 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15574 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15576 (define_expand "cmpstrnqi_nz_1"
15577   [(parallel [(set (reg:CC FLAGS_REG)
15578                    (compare:CC (match_operand 4 "memory_operand")
15579                                (match_operand 5 "memory_operand")))
15580               (use (match_operand 2 "register_operand"))
15581               (use (match_operand:SI 3 "immediate_operand"))
15582               (clobber (match_operand 0 "register_operand"))
15583               (clobber (match_operand 1 "register_operand"))
15584               (clobber (match_dup 2))])]
15585   ""
15586   "ix86_current_function_needs_cld = 1;")
15588 (define_insn "*cmpstrnqi_nz_1"
15589   [(set (reg:CC FLAGS_REG)
15590         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15591                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15592    (use (match_operand:P 6 "register_operand" "2"))
15593    (use (match_operand:SI 3 "immediate_operand" "i"))
15594    (clobber (match_operand:P 0 "register_operand" "=S"))
15595    (clobber (match_operand:P 1 "register_operand" "=D"))
15596    (clobber (match_operand:P 2 "register_operand" "=c"))]
15597   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15598   "%^repz{%;} cmpsb"
15599   [(set_attr "type" "str")
15600    (set_attr "mode" "QI")
15601    (set (attr "prefix_rex")
15602         (if_then_else
15603           (match_test "<P:MODE>mode == DImode")
15604           (const_string "0")
15605           (const_string "*")))
15606    (set_attr "prefix_rep" "1")])
15608 ;; The same, but the count is not known to not be zero.
15610 (define_expand "cmpstrnqi_1"
15611   [(parallel [(set (reg:CC FLAGS_REG)
15612                 (if_then_else:CC (ne (match_operand 2 "register_operand")
15613                                      (const_int 0))
15614                   (compare:CC (match_operand 4 "memory_operand")
15615                               (match_operand 5 "memory_operand"))
15616                   (const_int 0)))
15617               (use (match_operand:SI 3 "immediate_operand"))
15618               (use (reg:CC FLAGS_REG))
15619               (clobber (match_operand 0 "register_operand"))
15620               (clobber (match_operand 1 "register_operand"))
15621               (clobber (match_dup 2))])]
15622   ""
15623   "ix86_current_function_needs_cld = 1;")
15625 (define_insn "*cmpstrnqi_1"
15626   [(set (reg:CC FLAGS_REG)
15627         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15628                              (const_int 0))
15629           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15630                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15631           (const_int 0)))
15632    (use (match_operand:SI 3 "immediate_operand" "i"))
15633    (use (reg:CC FLAGS_REG))
15634    (clobber (match_operand:P 0 "register_operand" "=S"))
15635    (clobber (match_operand:P 1 "register_operand" "=D"))
15636    (clobber (match_operand:P 2 "register_operand" "=c"))]
15637   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15638   "%^repz{%;} cmpsb"
15639   [(set_attr "type" "str")
15640    (set_attr "mode" "QI")
15641    (set (attr "prefix_rex")
15642         (if_then_else
15643           (match_test "<P:MODE>mode == DImode")
15644           (const_string "0")
15645           (const_string "*")))
15646    (set_attr "prefix_rep" "1")])
15648 (define_expand "strlen<mode>"
15649   [(set (match_operand:P 0 "register_operand")
15650         (unspec:P [(match_operand:BLK 1 "general_operand")
15651                    (match_operand:QI 2 "immediate_operand")
15652                    (match_operand 3 "immediate_operand")]
15653                   UNSPEC_SCAS))]
15654   ""
15656  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15657    DONE;
15658  else
15659    FAIL;
15662 (define_expand "strlenqi_1"
15663   [(parallel [(set (match_operand 0 "register_operand")
15664                    (match_operand 2))
15665               (clobber (match_operand 1 "register_operand"))
15666               (clobber (reg:CC FLAGS_REG))])]
15667   ""
15668   "ix86_current_function_needs_cld = 1;")
15670 (define_insn "*strlenqi_1"
15671   [(set (match_operand:P 0 "register_operand" "=&c")
15672         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15673                    (match_operand:QI 2 "register_operand" "a")
15674                    (match_operand:P 3 "immediate_operand" "i")
15675                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15676    (clobber (match_operand:P 1 "register_operand" "=D"))
15677    (clobber (reg:CC FLAGS_REG))]
15678   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15679   "%^repnz{%;} scasb"
15680   [(set_attr "type" "str")
15681    (set_attr "mode" "QI")
15682    (set (attr "prefix_rex")
15683         (if_then_else
15684           (match_test "<P:MODE>mode == DImode")
15685           (const_string "0")
15686           (const_string "*")))
15687    (set_attr "prefix_rep" "1")])
15689 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15690 ;; handled in combine, but it is not currently up to the task.
15691 ;; When used for their truth value, the cmpstrn* expanders generate
15692 ;; code like this:
15694 ;;   repz cmpsb
15695 ;;   seta       %al
15696 ;;   setb       %dl
15697 ;;   cmpb       %al, %dl
15698 ;;   jcc        label
15700 ;; The intermediate three instructions are unnecessary.
15702 ;; This one handles cmpstrn*_nz_1...
15703 (define_peephole2
15704   [(parallel[
15705      (set (reg:CC FLAGS_REG)
15706           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15707                       (mem:BLK (match_operand 5 "register_operand"))))
15708      (use (match_operand 6 "register_operand"))
15709      (use (match_operand:SI 3 "immediate_operand"))
15710      (clobber (match_operand 0 "register_operand"))
15711      (clobber (match_operand 1 "register_operand"))
15712      (clobber (match_operand 2 "register_operand"))])
15713    (set (match_operand:QI 7 "register_operand")
15714         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15715    (set (match_operand:QI 8 "register_operand")
15716         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15717    (set (reg FLAGS_REG)
15718         (compare (match_dup 7) (match_dup 8)))
15719   ]
15720   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15721   [(parallel[
15722      (set (reg:CC FLAGS_REG)
15723           (compare:CC (mem:BLK (match_dup 4))
15724                       (mem:BLK (match_dup 5))))
15725      (use (match_dup 6))
15726      (use (match_dup 3))
15727      (clobber (match_dup 0))
15728      (clobber (match_dup 1))
15729      (clobber (match_dup 2))])])
15731 ;; ...and this one handles cmpstrn*_1.
15732 (define_peephole2
15733   [(parallel[
15734      (set (reg:CC FLAGS_REG)
15735           (if_then_else:CC (ne (match_operand 6 "register_operand")
15736                                (const_int 0))
15737             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15738                         (mem:BLK (match_operand 5 "register_operand")))
15739             (const_int 0)))
15740      (use (match_operand:SI 3 "immediate_operand"))
15741      (use (reg:CC FLAGS_REG))
15742      (clobber (match_operand 0 "register_operand"))
15743      (clobber (match_operand 1 "register_operand"))
15744      (clobber (match_operand 2 "register_operand"))])
15745    (set (match_operand:QI 7 "register_operand")
15746         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15747    (set (match_operand:QI 8 "register_operand")
15748         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15749    (set (reg FLAGS_REG)
15750         (compare (match_dup 7) (match_dup 8)))
15751   ]
15752   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15753   [(parallel[
15754      (set (reg:CC FLAGS_REG)
15755           (if_then_else:CC (ne (match_dup 6)
15756                                (const_int 0))
15757             (compare:CC (mem:BLK (match_dup 4))
15758                         (mem:BLK (match_dup 5)))
15759             (const_int 0)))
15760      (use (match_dup 3))
15761      (use (reg:CC FLAGS_REG))
15762      (clobber (match_dup 0))
15763      (clobber (match_dup 1))
15764      (clobber (match_dup 2))])])
15766 ;; Conditional move instructions.
15768 (define_expand "mov<mode>cc"
15769   [(set (match_operand:SWIM 0 "register_operand")
15770         (if_then_else:SWIM (match_operand 1 "comparison_operator")
15771                            (match_operand:SWIM 2 "<general_operand>")
15772                            (match_operand:SWIM 3 "<general_operand>")))]
15773   ""
15774   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15776 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15777 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15778 ;; So just document what we're doing explicitly.
15780 (define_expand "x86_mov<mode>cc_0_m1"
15781   [(parallel
15782     [(set (match_operand:SWI48 0 "register_operand")
15783           (if_then_else:SWI48
15784             (match_operator:SWI48 2 "ix86_carry_flag_operator"
15785              [(match_operand 1 "flags_reg_operand")
15786               (const_int 0)])
15787             (const_int -1)
15788             (const_int 0)))
15789      (clobber (reg:CC FLAGS_REG))])])
15791 (define_insn "*x86_mov<mode>cc_0_m1"
15792   [(set (match_operand:SWI48 0 "register_operand" "=r")
15793         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15794                              [(reg FLAGS_REG) (const_int 0)])
15795           (const_int -1)
15796           (const_int 0)))
15797    (clobber (reg:CC FLAGS_REG))]
15798   ""
15799   "sbb{<imodesuffix>}\t%0, %0"
15800   ; Since we don't have the proper number of operands for an alu insn,
15801   ; fill in all the blanks.
15802   [(set_attr "type" "alu")
15803    (set_attr "use_carry" "1")
15804    (set_attr "pent_pair" "pu")
15805    (set_attr "memory" "none")
15806    (set_attr "imm_disp" "false")
15807    (set_attr "mode" "<MODE>")
15808    (set_attr "length_immediate" "0")])
15810 (define_insn "*x86_mov<mode>cc_0_m1_se"
15811   [(set (match_operand:SWI48 0 "register_operand" "=r")
15812         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15813                              [(reg FLAGS_REG) (const_int 0)])
15814                             (const_int 1)
15815                             (const_int 0)))
15816    (clobber (reg:CC FLAGS_REG))]
15817   ""
15818   "sbb{<imodesuffix>}\t%0, %0"
15819   [(set_attr "type" "alu")
15820    (set_attr "use_carry" "1")
15821    (set_attr "pent_pair" "pu")
15822    (set_attr "memory" "none")
15823    (set_attr "imm_disp" "false")
15824    (set_attr "mode" "<MODE>")
15825    (set_attr "length_immediate" "0")])
15827 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15828   [(set (match_operand:SWI48 0 "register_operand" "=r")
15829         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15830                     [(reg FLAGS_REG) (const_int 0)])))
15831    (clobber (reg:CC FLAGS_REG))]
15832   ""
15833   "sbb{<imodesuffix>}\t%0, %0"
15834   [(set_attr "type" "alu")
15835    (set_attr "use_carry" "1")
15836    (set_attr "pent_pair" "pu")
15837    (set_attr "memory" "none")
15838    (set_attr "imm_disp" "false")
15839    (set_attr "mode" "<MODE>")
15840    (set_attr "length_immediate" "0")])
15842 (define_insn "*mov<mode>cc_noc"
15843   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15844         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15845                                [(reg FLAGS_REG) (const_int 0)])
15846           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15847           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15848   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15849   "@
15850    cmov%O2%C1\t{%2, %0|%0, %2}
15851    cmov%O2%c1\t{%3, %0|%0, %3}"
15852   [(set_attr "type" "icmov")
15853    (set_attr "mode" "<MODE>")])
15855 ;; Don't do conditional moves with memory inputs.  This splitter helps
15856 ;; register starved x86_32 by forcing inputs into registers before reload.
15857 (define_split
15858   [(set (match_operand:SWI248 0 "register_operand")
15859         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15860                                [(reg FLAGS_REG) (const_int 0)])
15861           (match_operand:SWI248 2 "nonimmediate_operand")
15862           (match_operand:SWI248 3 "nonimmediate_operand")))]
15863   "!TARGET_64BIT && TARGET_CMOVE
15864    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15865    && (MEM_P (operands[2]) || MEM_P (operands[3]))
15866    && can_create_pseudo_p ()
15867    && optimize_insn_for_speed_p ()"
15868   [(set (match_dup 0)
15869         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
15871   if (MEM_P (operands[2]))
15872     operands[2] = force_reg (<MODE>mode, operands[2]);
15873   if (MEM_P (operands[3]))
15874     operands[3] = force_reg (<MODE>mode, operands[3]);
15877 (define_insn "*movqicc_noc"
15878   [(set (match_operand:QI 0 "register_operand" "=r,r")
15879         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15880                            [(reg FLAGS_REG) (const_int 0)])
15881                       (match_operand:QI 2 "register_operand" "r,0")
15882                       (match_operand:QI 3 "register_operand" "0,r")))]
15883   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15884   "#"
15885   [(set_attr "type" "icmov")
15886    (set_attr "mode" "QI")])
15888 (define_split
15889   [(set (match_operand:SWI12 0 "register_operand")
15890         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
15891                               [(reg FLAGS_REG) (const_int 0)])
15892                       (match_operand:SWI12 2 "register_operand")
15893                       (match_operand:SWI12 3 "register_operand")))]
15894   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
15895    && reload_completed"
15896   [(set (match_dup 0)
15897         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
15899   operands[0] = gen_lowpart (SImode, operands[0]);
15900   operands[2] = gen_lowpart (SImode, operands[2]);
15901   operands[3] = gen_lowpart (SImode, operands[3]);
15904 ;; Don't do conditional moves with memory inputs
15905 (define_peephole2
15906   [(match_scratch:SWI248 2 "r")
15907    (set (match_operand:SWI248 0 "register_operand")
15908         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15909                                [(reg FLAGS_REG) (const_int 0)])
15910           (match_dup 0)
15911           (match_operand:SWI248 3 "memory_operand")))]
15912   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15913    && optimize_insn_for_speed_p ()"
15914   [(set (match_dup 2) (match_dup 3))
15915    (set (match_dup 0)
15916         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
15918 (define_peephole2
15919   [(match_scratch:SWI248 2 "r")
15920    (set (match_operand:SWI248 0 "register_operand")
15921         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15922                                [(reg FLAGS_REG) (const_int 0)])
15923           (match_operand:SWI248 3 "memory_operand")
15924           (match_dup 0)))]
15925   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15926    && optimize_insn_for_speed_p ()"
15927   [(set (match_dup 2) (match_dup 3))
15928    (set (match_dup 0)
15929         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
15931 (define_expand "mov<mode>cc"
15932   [(set (match_operand:X87MODEF 0 "register_operand")
15933         (if_then_else:X87MODEF
15934           (match_operand 1 "comparison_operator")
15935           (match_operand:X87MODEF 2 "register_operand")
15936           (match_operand:X87MODEF 3 "register_operand")))]
15937   "(TARGET_80387 && TARGET_CMOVE)
15938    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15939   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15941 (define_insn "*movxfcc_1"
15942   [(set (match_operand:XF 0 "register_operand" "=f,f")
15943         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15944                                 [(reg FLAGS_REG) (const_int 0)])
15945                       (match_operand:XF 2 "register_operand" "f,0")
15946                       (match_operand:XF 3 "register_operand" "0,f")))]
15947   "TARGET_80387 && TARGET_CMOVE"
15948   "@
15949    fcmov%F1\t{%2, %0|%0, %2}
15950    fcmov%f1\t{%3, %0|%0, %3}"
15951   [(set_attr "type" "fcmov")
15952    (set_attr "mode" "XF")])
15954 (define_insn "*movdfcc_1_rex64"
15955   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
15956         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15957                                 [(reg FLAGS_REG) (const_int 0)])
15958                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15959                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15960   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15961    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15962   "@
15963    fcmov%F1\t{%2, %0|%0, %2}
15964    fcmov%f1\t{%3, %0|%0, %3}
15965    cmov%O2%C1\t{%2, %0|%0, %2}
15966    cmov%O2%c1\t{%3, %0|%0, %3}"
15967   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15968    (set_attr "mode" "DF,DF,DI,DI")])
15970 (define_insn "*movdfcc_1"
15971   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15972         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15973                                 [(reg FLAGS_REG) (const_int 0)])
15974                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15975                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15976   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15977    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15978   "@
15979    fcmov%F1\t{%2, %0|%0, %2}
15980    fcmov%f1\t{%3, %0|%0, %3}
15981    #
15982    #"
15983   [(set_attr "type" "fcmov,fcmov,multi,multi")
15984    (set_attr "mode" "DF,DF,DI,DI")])
15986 (define_split
15987   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
15988         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15989                                 [(reg FLAGS_REG) (const_int 0)])
15990                       (match_operand:DF 2 "nonimmediate_operand")
15991                       (match_operand:DF 3 "nonimmediate_operand")))]
15992   "!TARGET_64BIT && reload_completed"
15993   [(set (match_dup 2)
15994         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
15995    (set (match_dup 3)
15996         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
15998   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
15999   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16002 (define_insn "*movsfcc_1_387"
16003   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16004         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16005                                 [(reg FLAGS_REG) (const_int 0)])
16006                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16007                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16008   "TARGET_80387 && TARGET_CMOVE
16009    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16010   "@
16011    fcmov%F1\t{%2, %0|%0, %2}
16012    fcmov%f1\t{%3, %0|%0, %3}
16013    cmov%O2%C1\t{%2, %0|%0, %2}
16014    cmov%O2%c1\t{%3, %0|%0, %3}"
16015   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16016    (set_attr "mode" "SF,SF,SI,SI")])
16018 ;; Don't do conditional moves with memory inputs.  This splitter helps
16019 ;; register starved x86_32 by forcing inputs into registers before reload.
16020 (define_split
16021   [(set (match_operand:MODEF 0 "register_operand")
16022         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16023                               [(reg FLAGS_REG) (const_int 0)])
16024           (match_operand:MODEF 2 "nonimmediate_operand")
16025           (match_operand:MODEF 3 "nonimmediate_operand")))]
16026   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16027    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16028    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16029    && can_create_pseudo_p ()
16030    && optimize_insn_for_speed_p ()"
16031   [(set (match_dup 0)
16032         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16034   if (MEM_P (operands[2]))
16035     operands[2] = force_reg (<MODE>mode, operands[2]);
16036   if (MEM_P (operands[3]))
16037     operands[3] = force_reg (<MODE>mode, operands[3]);
16040 ;; Don't do conditional moves with memory inputs
16041 (define_peephole2
16042   [(match_scratch:MODEF 2 "r")
16043    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16044         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16045                               [(reg FLAGS_REG) (const_int 0)])
16046           (match_dup 0)
16047           (match_operand:MODEF 3 "memory_operand")))]
16048   "(<MODE>mode != DFmode || TARGET_64BIT)
16049    && TARGET_80387 && TARGET_CMOVE
16050    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16051    && optimize_insn_for_speed_p ()"
16052   [(set (match_dup 2) (match_dup 3))
16053    (set (match_dup 0)
16054         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16056 (define_peephole2
16057   [(match_scratch:MODEF 2 "r")
16058    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16059         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16060                               [(reg FLAGS_REG) (const_int 0)])
16061           (match_operand:MODEF 3 "memory_operand")
16062           (match_dup 0)))]
16063   "(<MODE>mode != DFmode || TARGET_64BIT)
16064    && TARGET_80387 && TARGET_CMOVE
16065    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16066    && optimize_insn_for_speed_p ()"
16067   [(set (match_dup 2) (match_dup 3))
16068    (set (match_dup 0)
16069         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16071 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16072 ;; the scalar versions to have only XMM registers as operands.
16074 ;; XOP conditional move
16075 (define_insn "*xop_pcmov_<mode>"
16076   [(set (match_operand:MODEF 0 "register_operand" "=x")
16077         (if_then_else:MODEF
16078           (match_operand:MODEF 1 "register_operand" "x")
16079           (match_operand:MODEF 2 "register_operand" "x")
16080           (match_operand:MODEF 3 "register_operand" "x")))]
16081   "TARGET_XOP"
16082   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16083   [(set_attr "type" "sse4arg")])
16085 ;; These versions of the min/max patterns are intentionally ignorant of
16086 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16087 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16088 ;; are undefined in this condition, we're certain this is correct.
16090 (define_insn "<code><mode>3"
16091   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16092         (smaxmin:MODEF
16093           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16094           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16095   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16096   "@
16097    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16098    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16099   [(set_attr "isa" "noavx,avx")
16100    (set_attr "prefix" "orig,vex")
16101    (set_attr "type" "sseadd")
16102    (set_attr "mode" "<MODE>")])
16104 ;; These versions of the min/max patterns implement exactly the operations
16105 ;;   min = (op1 < op2 ? op1 : op2)
16106 ;;   max = (!(op1 < op2) ? op1 : op2)
16107 ;; Their operands are not commutative, and thus they may be used in the
16108 ;; presence of -0.0 and NaN.
16110 (define_int_iterator IEEE_MAXMIN
16111         [UNSPEC_IEEE_MAX
16112          UNSPEC_IEEE_MIN])
16114 (define_int_attr ieee_maxmin
16115         [(UNSPEC_IEEE_MAX "max")
16116          (UNSPEC_IEEE_MIN "min")])
16118 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16119   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16120         (unspec:MODEF
16121           [(match_operand:MODEF 1 "register_operand" "0,x")
16122            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16123           IEEE_MAXMIN))]
16124   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16125   "@
16126    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16127    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16128   [(set_attr "isa" "noavx,avx")
16129    (set_attr "prefix" "orig,vex")
16130    (set_attr "type" "sseadd")
16131    (set_attr "mode" "<MODE>")])
16133 ;; Make two stack loads independent:
16134 ;;   fld aa              fld aa
16135 ;;   fld %st(0)     ->   fld bb
16136 ;;   fmul bb             fmul %st(1), %st
16138 ;; Actually we only match the last two instructions for simplicity.
16139 (define_peephole2
16140   [(set (match_operand 0 "fp_register_operand")
16141         (match_operand 1 "fp_register_operand"))
16142    (set (match_dup 0)
16143         (match_operator 2 "binary_fp_operator"
16144            [(match_dup 0)
16145             (match_operand 3 "memory_operand")]))]
16146   "REGNO (operands[0]) != REGNO (operands[1])"
16147   [(set (match_dup 0) (match_dup 3))
16148    (set (match_dup 0) (match_dup 4))]
16150   ;; The % modifier is not operational anymore in peephole2's, so we have to
16151   ;; swap the operands manually in the case of addition and multiplication.
16153   rtx op0, op1;
16155   if (COMMUTATIVE_ARITH_P (operands[2]))
16156     op0 = operands[0], op1 = operands[1];
16157   else
16158     op0 = operands[1], op1 = operands[0];
16160   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16161                                 GET_MODE (operands[2]),
16162                                 op0, op1);
16165 ;; Conditional addition patterns
16166 (define_expand "add<mode>cc"
16167   [(match_operand:SWI 0 "register_operand")
16168    (match_operand 1 "ordered_comparison_operator")
16169    (match_operand:SWI 2 "register_operand")
16170    (match_operand:SWI 3 "const_int_operand")]
16171   ""
16172   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16174 ;; Misc patterns (?)
16176 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16177 ;; Otherwise there will be nothing to keep
16179 ;; [(set (reg ebp) (reg esp))]
16180 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16181 ;;  (clobber (eflags)]
16182 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16184 ;; in proper program order.
16186 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16187   [(set (match_operand:P 0 "register_operand" "=r,r")
16188         (plus:P (match_operand:P 1 "register_operand" "0,r")
16189                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16190    (clobber (reg:CC FLAGS_REG))
16191    (clobber (mem:BLK (scratch)))]
16192   ""
16194   switch (get_attr_type (insn))
16195     {
16196     case TYPE_IMOV:
16197       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16199     case TYPE_ALU:
16200       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16201       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16202         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16204       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16206     default:
16207       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16208       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16209     }
16211   [(set (attr "type")
16212         (cond [(and (eq_attr "alternative" "0")
16213                     (not (match_test "TARGET_OPT_AGU")))
16214                  (const_string "alu")
16215                (match_operand:<MODE> 2 "const0_operand")
16216                  (const_string "imov")
16217               ]
16218               (const_string "lea")))
16219    (set (attr "length_immediate")
16220         (cond [(eq_attr "type" "imov")
16221                  (const_string "0")
16222                (and (eq_attr "type" "alu")
16223                     (match_operand 2 "const128_operand"))
16224                  (const_string "1")
16225               ]
16226               (const_string "*")))
16227    (set_attr "mode" "<MODE>")])
16229 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16230   [(set (match_operand:P 0 "register_operand" "=r")
16231         (minus:P (match_operand:P 1 "register_operand" "0")
16232                  (match_operand:P 2 "register_operand" "r")))
16233    (clobber (reg:CC FLAGS_REG))
16234    (clobber (mem:BLK (scratch)))]
16235   ""
16236   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16237   [(set_attr "type" "alu")
16238    (set_attr "mode" "<MODE>")])
16240 (define_insn "allocate_stack_worker_probe_<mode>"
16241   [(set (match_operand:P 0 "register_operand" "=a")
16242         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16243                             UNSPECV_STACK_PROBE))
16244    (clobber (reg:CC FLAGS_REG))]
16245   "ix86_target_stack_probe ()"
16246   "call\t___chkstk_ms"
16247   [(set_attr "type" "multi")
16248    (set_attr "length" "5")])
16250 (define_expand "allocate_stack"
16251   [(match_operand 0 "register_operand")
16252    (match_operand 1 "general_operand")]
16253   "ix86_target_stack_probe ()"
16255   rtx x;
16257 #ifndef CHECK_STACK_LIMIT
16258 #define CHECK_STACK_LIMIT 0
16259 #endif
16261   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16262       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16263     x = operands[1];
16264   else
16265     {
16266       rtx (*insn) (rtx, rtx);
16268       x = copy_to_mode_reg (Pmode, operands[1]);
16270       insn = (TARGET_64BIT
16271               ? gen_allocate_stack_worker_probe_di
16272               : gen_allocate_stack_worker_probe_si);
16274       emit_insn (insn (x, x));
16275     }
16277   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16278                            stack_pointer_rtx, 0, OPTAB_DIRECT);
16280   if (x != stack_pointer_rtx)
16281     emit_move_insn (stack_pointer_rtx, x);
16283   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16284   DONE;
16287 ;; Use IOR for stack probes, this is shorter.
16288 (define_expand "probe_stack"
16289   [(match_operand 0 "memory_operand")]
16290   ""
16292   rtx (*gen_ior3) (rtx, rtx, rtx);
16294   gen_ior3 = (GET_MODE (operands[0]) == DImode
16295               ? gen_iordi3 : gen_iorsi3);
16297   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16298   DONE;
16301 (define_insn "adjust_stack_and_probe<mode>"
16302   [(set (match_operand:P 0 "register_operand" "=r")
16303         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16304                             UNSPECV_PROBE_STACK_RANGE))
16305    (set (reg:P SP_REG)
16306         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16307    (clobber (reg:CC FLAGS_REG))
16308    (clobber (mem:BLK (scratch)))]
16309   ""
16310   "* return output_adjust_stack_and_probe (operands[0]);"
16311   [(set_attr "type" "multi")])
16313 (define_insn "probe_stack_range<mode>"
16314   [(set (match_operand:P 0 "register_operand" "=r")
16315         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16316                             (match_operand:P 2 "const_int_operand" "n")]
16317                             UNSPECV_PROBE_STACK_RANGE))
16318    (clobber (reg:CC FLAGS_REG))]
16319   ""
16320   "* return output_probe_stack_range (operands[0], operands[2]);"
16321   [(set_attr "type" "multi")])
16323 (define_expand "builtin_setjmp_receiver"
16324   [(label_ref (match_operand 0))]
16325   "!TARGET_64BIT && flag_pic"
16327 #if TARGET_MACHO
16328   if (TARGET_MACHO)
16329     {
16330       rtx xops[3];
16331       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16332       rtx label_rtx = gen_label_rtx ();
16333       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16334       xops[0] = xops[1] = picreg;
16335       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16336       ix86_expand_binary_operator (MINUS, SImode, xops);
16337     }
16338   else
16339 #endif
16340     emit_insn (gen_set_got (pic_offset_table_rtx));
16341   DONE;
16344 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16346 (define_split
16347   [(set (match_operand 0 "register_operand")
16348         (match_operator 3 "promotable_binary_operator"
16349            [(match_operand 1 "register_operand")
16350             (match_operand 2 "aligned_operand")]))
16351    (clobber (reg:CC FLAGS_REG))]
16352   "! TARGET_PARTIAL_REG_STALL && reload_completed
16353    && ((GET_MODE (operands[0]) == HImode
16354         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16355             /* ??? next two lines just !satisfies_constraint_K (...) */
16356             || !CONST_INT_P (operands[2])
16357             || satisfies_constraint_K (operands[2])))
16358        || (GET_MODE (operands[0]) == QImode
16359            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16360   [(parallel [(set (match_dup 0)
16361                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16362               (clobber (reg:CC FLAGS_REG))])]
16364   operands[0] = gen_lowpart (SImode, operands[0]);
16365   operands[1] = gen_lowpart (SImode, operands[1]);
16366   if (GET_CODE (operands[3]) != ASHIFT)
16367     operands[2] = gen_lowpart (SImode, operands[2]);
16368   PUT_MODE (operands[3], SImode);
16371 ; Promote the QImode tests, as i386 has encoding of the AND
16372 ; instruction with 32-bit sign-extended immediate and thus the
16373 ; instruction size is unchanged, except in the %eax case for
16374 ; which it is increased by one byte, hence the ! optimize_size.
16375 (define_split
16376   [(set (match_operand 0 "flags_reg_operand")
16377         (match_operator 2 "compare_operator"
16378           [(and (match_operand 3 "aligned_operand")
16379                 (match_operand 4 "const_int_operand"))
16380            (const_int 0)]))
16381    (set (match_operand 1 "register_operand")
16382         (and (match_dup 3) (match_dup 4)))]
16383   "! TARGET_PARTIAL_REG_STALL && reload_completed
16384    && optimize_insn_for_speed_p ()
16385    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16386        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16387    /* Ensure that the operand will remain sign-extended immediate.  */
16388    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16389   [(parallel [(set (match_dup 0)
16390                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16391                                     (const_int 0)]))
16392               (set (match_dup 1)
16393                    (and:SI (match_dup 3) (match_dup 4)))])]
16395   operands[4]
16396     = gen_int_mode (INTVAL (operands[4])
16397                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16398   operands[1] = gen_lowpart (SImode, operands[1]);
16399   operands[3] = gen_lowpart (SImode, operands[3]);
16402 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16403 ; the TEST instruction with 32-bit sign-extended immediate and thus
16404 ; the instruction size would at least double, which is not what we
16405 ; want even with ! optimize_size.
16406 (define_split
16407   [(set (match_operand 0 "flags_reg_operand")
16408         (match_operator 1 "compare_operator"
16409           [(and (match_operand:HI 2 "aligned_operand")
16410                 (match_operand:HI 3 "const_int_operand"))
16411            (const_int 0)]))]
16412   "! TARGET_PARTIAL_REG_STALL && reload_completed
16413    && ! TARGET_FAST_PREFIX
16414    && optimize_insn_for_speed_p ()
16415    /* Ensure that the operand will remain sign-extended immediate.  */
16416    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16417   [(set (match_dup 0)
16418         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16419                          (const_int 0)]))]
16421   operands[3]
16422     = gen_int_mode (INTVAL (operands[3])
16423                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16424   operands[2] = gen_lowpart (SImode, operands[2]);
16427 (define_split
16428   [(set (match_operand 0 "register_operand")
16429         (neg (match_operand 1 "register_operand")))
16430    (clobber (reg:CC FLAGS_REG))]
16431   "! TARGET_PARTIAL_REG_STALL && reload_completed
16432    && (GET_MODE (operands[0]) == HImode
16433        || (GET_MODE (operands[0]) == QImode
16434            && (TARGET_PROMOTE_QImode
16435                || optimize_insn_for_size_p ())))"
16436   [(parallel [(set (match_dup 0)
16437                    (neg:SI (match_dup 1)))
16438               (clobber (reg:CC FLAGS_REG))])]
16440   operands[0] = gen_lowpart (SImode, operands[0]);
16441   operands[1] = gen_lowpart (SImode, operands[1]);
16444 (define_split
16445   [(set (match_operand 0 "register_operand")
16446         (not (match_operand 1 "register_operand")))]
16447   "! TARGET_PARTIAL_REG_STALL && reload_completed
16448    && (GET_MODE (operands[0]) == HImode
16449        || (GET_MODE (operands[0]) == QImode
16450            && (TARGET_PROMOTE_QImode
16451                || optimize_insn_for_size_p ())))"
16452   [(set (match_dup 0)
16453         (not:SI (match_dup 1)))]
16455   operands[0] = gen_lowpart (SImode, operands[0]);
16456   operands[1] = gen_lowpart (SImode, operands[1]);
16459 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16460 ;; transform a complex memory operation into two memory to register operations.
16462 ;; Don't push memory operands
16463 (define_peephole2
16464   [(set (match_operand:SWI 0 "push_operand")
16465         (match_operand:SWI 1 "memory_operand"))
16466    (match_scratch:SWI 2 "<r>")]
16467   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16468    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16469   [(set (match_dup 2) (match_dup 1))
16470    (set (match_dup 0) (match_dup 2))])
16472 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16473 ;; SImode pushes.
16474 (define_peephole2
16475   [(set (match_operand:SF 0 "push_operand")
16476         (match_operand:SF 1 "memory_operand"))
16477    (match_scratch:SF 2 "r")]
16478   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16479    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16480   [(set (match_dup 2) (match_dup 1))
16481    (set (match_dup 0) (match_dup 2))])
16483 ;; Don't move an immediate directly to memory when the instruction
16484 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16485 (define_peephole2
16486   [(match_scratch:SWI124 1 "<r>")
16487    (set (match_operand:SWI124 0 "memory_operand")
16488         (const_int 0))]
16489   "optimize_insn_for_speed_p ()
16490    && ((<MODE>mode == HImode
16491        && TARGET_LCP_STALL)
16492        || (!TARGET_USE_MOV0
16493           && TARGET_SPLIT_LONG_MOVES
16494           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16495    && peep2_regno_dead_p (0, FLAGS_REG)"
16496   [(parallel [(set (match_dup 2) (const_int 0))
16497               (clobber (reg:CC FLAGS_REG))])
16498    (set (match_dup 0) (match_dup 1))]
16499   "operands[2] = gen_lowpart (SImode, operands[1]);")
16501 (define_peephole2
16502   [(match_scratch:SWI124 2 "<r>")
16503    (set (match_operand:SWI124 0 "memory_operand")
16504         (match_operand:SWI124 1 "immediate_operand"))]
16505   "optimize_insn_for_speed_p ()
16506    && ((<MODE>mode == HImode
16507        && TARGET_LCP_STALL)
16508        || (TARGET_SPLIT_LONG_MOVES
16509           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16510   [(set (match_dup 2) (match_dup 1))
16511    (set (match_dup 0) (match_dup 2))])
16513 ;; Don't compare memory with zero, load and use a test instead.
16514 (define_peephole2
16515   [(set (match_operand 0 "flags_reg_operand")
16516         (match_operator 1 "compare_operator"
16517           [(match_operand:SI 2 "memory_operand")
16518            (const_int 0)]))
16519    (match_scratch:SI 3 "r")]
16520   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16521   [(set (match_dup 3) (match_dup 2))
16522    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16524 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16525 ;; Don't split NOTs with a displacement operand, because resulting XOR
16526 ;; will not be pairable anyway.
16528 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16529 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16530 ;; so this split helps here as well.
16532 ;; Note: Can't do this as a regular split because we can't get proper
16533 ;; lifetime information then.
16535 (define_peephole2
16536   [(set (match_operand:SWI124 0 "nonimmediate_operand")
16537         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16538   "optimize_insn_for_speed_p ()
16539    && ((TARGET_NOT_UNPAIRABLE
16540         && (!MEM_P (operands[0])
16541             || !memory_displacement_operand (operands[0], <MODE>mode)))
16542        || (TARGET_NOT_VECTORMODE
16543            && long_memory_operand (operands[0], <MODE>mode)))
16544    && peep2_regno_dead_p (0, FLAGS_REG)"
16545   [(parallel [(set (match_dup 0)
16546                    (xor:SWI124 (match_dup 1) (const_int -1)))
16547               (clobber (reg:CC FLAGS_REG))])])
16549 ;; Non pairable "test imm, reg" instructions can be translated to
16550 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16551 ;; byte opcode instead of two, have a short form for byte operands),
16552 ;; so do it for other CPUs as well.  Given that the value was dead,
16553 ;; this should not create any new dependencies.  Pass on the sub-word
16554 ;; versions if we're concerned about partial register stalls.
16556 (define_peephole2
16557   [(set (match_operand 0 "flags_reg_operand")
16558         (match_operator 1 "compare_operator"
16559           [(and:SI (match_operand:SI 2 "register_operand")
16560                    (match_operand:SI 3 "immediate_operand"))
16561            (const_int 0)]))]
16562   "ix86_match_ccmode (insn, CCNOmode)
16563    && (true_regnum (operands[2]) != AX_REG
16564        || satisfies_constraint_K (operands[3]))
16565    && peep2_reg_dead_p (1, operands[2])"
16566   [(parallel
16567      [(set (match_dup 0)
16568            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16569                             (const_int 0)]))
16570       (set (match_dup 2)
16571            (and:SI (match_dup 2) (match_dup 3)))])])
16573 ;; We don't need to handle HImode case, because it will be promoted to SImode
16574 ;; on ! TARGET_PARTIAL_REG_STALL
16576 (define_peephole2
16577   [(set (match_operand 0 "flags_reg_operand")
16578         (match_operator 1 "compare_operator"
16579           [(and:QI (match_operand:QI 2 "register_operand")
16580                    (match_operand:QI 3 "immediate_operand"))
16581            (const_int 0)]))]
16582   "! TARGET_PARTIAL_REG_STALL
16583    && ix86_match_ccmode (insn, CCNOmode)
16584    && true_regnum (operands[2]) != AX_REG
16585    && peep2_reg_dead_p (1, operands[2])"
16586   [(parallel
16587      [(set (match_dup 0)
16588            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16589                             (const_int 0)]))
16590       (set (match_dup 2)
16591            (and:QI (match_dup 2) (match_dup 3)))])])
16593 (define_peephole2
16594   [(set (match_operand 0 "flags_reg_operand")
16595         (match_operator 1 "compare_operator"
16596           [(and:SI
16597              (zero_extract:SI
16598                (match_operand 2 "ext_register_operand")
16599                (const_int 8)
16600                (const_int 8))
16601              (match_operand 3 "const_int_operand"))
16602            (const_int 0)]))]
16603   "! TARGET_PARTIAL_REG_STALL
16604    && ix86_match_ccmode (insn, CCNOmode)
16605    && true_regnum (operands[2]) != AX_REG
16606    && peep2_reg_dead_p (1, operands[2])"
16607   [(parallel [(set (match_dup 0)
16608                    (match_op_dup 1
16609                      [(and:SI
16610                         (zero_extract:SI
16611                           (match_dup 2)
16612                           (const_int 8)
16613                           (const_int 8))
16614                         (match_dup 3))
16615                       (const_int 0)]))
16616               (set (zero_extract:SI (match_dup 2)
16617                                     (const_int 8)
16618                                     (const_int 8))
16619                    (and:SI
16620                      (zero_extract:SI
16621                        (match_dup 2)
16622                        (const_int 8)
16623                        (const_int 8))
16624                      (match_dup 3)))])])
16626 ;; Don't do logical operations with memory inputs.
16627 (define_peephole2
16628   [(match_scratch:SI 2 "r")
16629    (parallel [(set (match_operand:SI 0 "register_operand")
16630                    (match_operator:SI 3 "arith_or_logical_operator"
16631                      [(match_dup 0)
16632                       (match_operand:SI 1 "memory_operand")]))
16633               (clobber (reg:CC FLAGS_REG))])]
16634   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16635   [(set (match_dup 2) (match_dup 1))
16636    (parallel [(set (match_dup 0)
16637                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16638               (clobber (reg:CC FLAGS_REG))])])
16640 (define_peephole2
16641   [(match_scratch:SI 2 "r")
16642    (parallel [(set (match_operand:SI 0 "register_operand")
16643                    (match_operator:SI 3 "arith_or_logical_operator"
16644                      [(match_operand:SI 1 "memory_operand")
16645                       (match_dup 0)]))
16646               (clobber (reg:CC FLAGS_REG))])]
16647   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16648   [(set (match_dup 2) (match_dup 1))
16649    (parallel [(set (match_dup 0)
16650                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16651               (clobber (reg:CC FLAGS_REG))])])
16653 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16654 ;; refers to the destination of the load!
16656 (define_peephole2
16657   [(set (match_operand:SI 0 "register_operand")
16658         (match_operand:SI 1 "register_operand"))
16659    (parallel [(set (match_dup 0)
16660                    (match_operator:SI 3 "commutative_operator"
16661                      [(match_dup 0)
16662                       (match_operand:SI 2 "memory_operand")]))
16663               (clobber (reg:CC FLAGS_REG))])]
16664   "REGNO (operands[0]) != REGNO (operands[1])
16665    && GENERAL_REGNO_P (REGNO (operands[0]))
16666    && GENERAL_REGNO_P (REGNO (operands[1]))"
16667   [(set (match_dup 0) (match_dup 4))
16668    (parallel [(set (match_dup 0)
16669                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16670               (clobber (reg:CC FLAGS_REG))])]
16671   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16673 (define_peephole2
16674   [(set (match_operand 0 "register_operand")
16675         (match_operand 1 "register_operand"))
16676    (set (match_dup 0)
16677                    (match_operator 3 "commutative_operator"
16678                      [(match_dup 0)
16679                       (match_operand 2 "memory_operand")]))]
16680   "REGNO (operands[0]) != REGNO (operands[1])
16681    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16682        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16683   [(set (match_dup 0) (match_dup 2))
16684    (set (match_dup 0)
16685         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16687 ; Don't do logical operations with memory outputs
16689 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16690 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16691 ; the same decoder scheduling characteristics as the original.
16693 (define_peephole2
16694   [(match_scratch:SI 2 "r")
16695    (parallel [(set (match_operand:SI 0 "memory_operand")
16696                    (match_operator:SI 3 "arith_or_logical_operator"
16697                      [(match_dup 0)
16698                       (match_operand:SI 1 "nonmemory_operand")]))
16699               (clobber (reg:CC FLAGS_REG))])]
16700   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16701    /* Do not split stack checking probes.  */
16702    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16703   [(set (match_dup 2) (match_dup 0))
16704    (parallel [(set (match_dup 2)
16705                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16706               (clobber (reg:CC FLAGS_REG))])
16707    (set (match_dup 0) (match_dup 2))])
16709 (define_peephole2
16710   [(match_scratch:SI 2 "r")
16711    (parallel [(set (match_operand:SI 0 "memory_operand")
16712                    (match_operator:SI 3 "arith_or_logical_operator"
16713                      [(match_operand:SI 1 "nonmemory_operand")
16714                       (match_dup 0)]))
16715               (clobber (reg:CC FLAGS_REG))])]
16716   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16717    /* Do not split stack checking probes.  */
16718    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16719   [(set (match_dup 2) (match_dup 0))
16720    (parallel [(set (match_dup 2)
16721                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16722               (clobber (reg:CC FLAGS_REG))])
16723    (set (match_dup 0) (match_dup 2))])
16725 ;; Attempt to use arith or logical operations with memory outputs with
16726 ;; setting of flags.
16727 (define_peephole2
16728   [(set (match_operand:SWI 0 "register_operand")
16729         (match_operand:SWI 1 "memory_operand"))
16730    (parallel [(set (match_dup 0)
16731                    (match_operator:SWI 3 "plusminuslogic_operator"
16732                      [(match_dup 0)
16733                       (match_operand:SWI 2 "<nonmemory_operand>")]))
16734               (clobber (reg:CC FLAGS_REG))])
16735    (set (match_dup 1) (match_dup 0))
16736    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16737   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16738    && peep2_reg_dead_p (4, operands[0])
16739    && !reg_overlap_mentioned_p (operands[0], operands[1])
16740    && (<MODE>mode != QImode
16741        || immediate_operand (operands[2], QImode)
16742        || q_regs_operand (operands[2], QImode))
16743    && ix86_match_ccmode (peep2_next_insn (3),
16744                          (GET_CODE (operands[3]) == PLUS
16745                           || GET_CODE (operands[3]) == MINUS)
16746                          ? CCGOCmode : CCNOmode)"
16747   [(parallel [(set (match_dup 4) (match_dup 5))
16748               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16749                                                   (match_dup 2)]))])]
16751   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16752   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16753                                 copy_rtx (operands[1]),
16754                                 copy_rtx (operands[2]));
16755   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16756                                  operands[5], const0_rtx);
16759 (define_peephole2
16760   [(parallel [(set (match_operand:SWI 0 "register_operand")
16761                    (match_operator:SWI 2 "plusminuslogic_operator"
16762                      [(match_dup 0)
16763                       (match_operand:SWI 1 "memory_operand")]))
16764               (clobber (reg:CC FLAGS_REG))])
16765    (set (match_dup 1) (match_dup 0))
16766    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16767   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16768    && GET_CODE (operands[2]) != MINUS
16769    && peep2_reg_dead_p (3, operands[0])
16770    && !reg_overlap_mentioned_p (operands[0], operands[1])
16771    && ix86_match_ccmode (peep2_next_insn (2),
16772                          GET_CODE (operands[2]) == PLUS
16773                          ? CCGOCmode : CCNOmode)"
16774   [(parallel [(set (match_dup 3) (match_dup 4))
16775               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16776                                                   (match_dup 0)]))])]
16778   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16779   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16780                                 copy_rtx (operands[1]),
16781                                 copy_rtx (operands[0]));
16782   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16783                                  operands[4], const0_rtx);
16786 (define_peephole2
16787   [(set (match_operand:SWI12 0 "register_operand")
16788         (match_operand:SWI12 1 "memory_operand"))
16789    (parallel [(set (match_operand:SI 4 "register_operand")
16790                    (match_operator:SI 3 "plusminuslogic_operator"
16791                      [(match_dup 4)
16792                       (match_operand:SI 2 "nonmemory_operand")]))
16793               (clobber (reg:CC FLAGS_REG))])
16794    (set (match_dup 1) (match_dup 0))
16795    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16796   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16797    && REG_P (operands[0]) && REG_P (operands[4])
16798    && REGNO (operands[0]) == REGNO (operands[4])
16799    && peep2_reg_dead_p (4, operands[0])
16800    && (<MODE>mode != QImode
16801        || immediate_operand (operands[2], SImode)
16802        || q_regs_operand (operands[2], SImode))
16803    && !reg_overlap_mentioned_p (operands[0], operands[1])
16804    && ix86_match_ccmode (peep2_next_insn (3),
16805                          (GET_CODE (operands[3]) == PLUS
16806                           || GET_CODE (operands[3]) == MINUS)
16807                          ? CCGOCmode : CCNOmode)"
16808   [(parallel [(set (match_dup 4) (match_dup 5))
16809               (set (match_dup 1) (match_dup 6))])]
16811   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16812   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16813   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16814                                 copy_rtx (operands[1]), operands[2]);
16815   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16816                                  operands[5], const0_rtx);
16817   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16818                                 copy_rtx (operands[1]),
16819                                 copy_rtx (operands[2]));
16822 ;; Attempt to always use XOR for zeroing registers.
16823 (define_peephole2
16824   [(set (match_operand 0 "register_operand")
16825         (match_operand 1 "const0_operand"))]
16826   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16827    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16828    && GENERAL_REG_P (operands[0])
16829    && peep2_regno_dead_p (0, FLAGS_REG)"
16830   [(parallel [(set (match_dup 0) (const_int 0))
16831               (clobber (reg:CC FLAGS_REG))])]
16832   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16834 (define_peephole2
16835   [(set (strict_low_part (match_operand 0 "register_operand"))
16836         (const_int 0))]
16837   "(GET_MODE (operands[0]) == QImode
16838     || GET_MODE (operands[0]) == HImode)
16839    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16840    && peep2_regno_dead_p (0, FLAGS_REG)"
16841   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16842               (clobber (reg:CC FLAGS_REG))])])
16844 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16845 (define_peephole2
16846   [(set (match_operand:SWI248 0 "register_operand")
16847         (const_int -1))]
16848   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16849    && peep2_regno_dead_p (0, FLAGS_REG)"
16850   [(parallel [(set (match_dup 0) (const_int -1))
16851               (clobber (reg:CC FLAGS_REG))])]
16853   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16854     operands[0] = gen_lowpart (SImode, operands[0]);
16857 ;; Attempt to convert simple lea to add/shift.
16858 ;; These can be created by move expanders.
16859 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
16860 ;; relevant lea instructions were already split.
16862 (define_peephole2
16863   [(set (match_operand:SWI48 0 "register_operand")
16864         (plus:SWI48 (match_dup 0)
16865                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
16866   "!TARGET_OPT_AGU
16867    && peep2_regno_dead_p (0, FLAGS_REG)"
16868   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16869               (clobber (reg:CC FLAGS_REG))])])
16871 (define_peephole2
16872   [(set (match_operand:SWI48 0 "register_operand")
16873         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
16874                     (match_dup 0)))]
16875   "!TARGET_OPT_AGU
16876    && peep2_regno_dead_p (0, FLAGS_REG)"
16877   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16878               (clobber (reg:CC FLAGS_REG))])])
16880 (define_peephole2
16881   [(set (match_operand:DI 0 "register_operand")
16882         (zero_extend:DI
16883           (plus:SI (match_operand:SI 1 "register_operand")
16884                    (match_operand:SI 2 "nonmemory_operand"))))]
16885   "TARGET_64BIT && !TARGET_OPT_AGU
16886    && REGNO (operands[0]) == REGNO (operands[1])
16887    && peep2_regno_dead_p (0, FLAGS_REG)"
16888   [(parallel [(set (match_dup 0)
16889                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
16890               (clobber (reg:CC FLAGS_REG))])])
16892 (define_peephole2
16893   [(set (match_operand:DI 0 "register_operand")
16894         (zero_extend:DI
16895           (plus:SI (match_operand:SI 1 "nonmemory_operand")
16896                    (match_operand:SI 2 "register_operand"))))]
16897   "TARGET_64BIT && !TARGET_OPT_AGU
16898    && REGNO (operands[0]) == REGNO (operands[2])
16899    && peep2_regno_dead_p (0, FLAGS_REG)"
16900   [(parallel [(set (match_dup 0)
16901                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
16902               (clobber (reg:CC FLAGS_REG))])])
16904 (define_peephole2
16905   [(set (match_operand:SWI48 0 "register_operand")
16906         (mult:SWI48 (match_dup 0)
16907                     (match_operand:SWI48 1 "const_int_operand")))]
16908   "exact_log2 (INTVAL (operands[1])) >= 0
16909    && peep2_regno_dead_p (0, FLAGS_REG)"
16910   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
16911               (clobber (reg:CC FLAGS_REG))])]
16912   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16914 (define_peephole2
16915   [(set (match_operand:DI 0 "register_operand")
16916         (zero_extend:DI
16917           (mult:SI (match_operand:SI 1 "register_operand")
16918                    (match_operand:SI 2 "const_int_operand"))))]
16919   "TARGET_64BIT
16920    && exact_log2 (INTVAL (operands[2])) >= 0
16921    && REGNO (operands[0]) == REGNO (operands[1])
16922    && peep2_regno_dead_p (0, FLAGS_REG)"
16923   [(parallel [(set (match_dup 0)
16924                    (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
16925               (clobber (reg:CC FLAGS_REG))])]
16926   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16928 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16929 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16930 ;; On many CPUs it is also faster, since special hardware to avoid esp
16931 ;; dependencies is present.
16933 ;; While some of these conversions may be done using splitters, we use
16934 ;; peepholes in order to allow combine_stack_adjustments pass to see
16935 ;; nonobfuscated RTL.
16937 ;; Convert prologue esp subtractions to push.
16938 ;; We need register to push.  In order to keep verify_flow_info happy we have
16939 ;; two choices
16940 ;; - use scratch and clobber it in order to avoid dependencies
16941 ;; - use already live register
16942 ;; We can't use the second way right now, since there is no reliable way how to
16943 ;; verify that given register is live.  First choice will also most likely in
16944 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16945 ;; call clobbered registers are dead.  We may want to use base pointer as an
16946 ;; alternative when no register is available later.
16948 (define_peephole2
16949   [(match_scratch:W 1 "r")
16950    (parallel [(set (reg:P SP_REG)
16951                    (plus:P (reg:P SP_REG)
16952                            (match_operand:P 0 "const_int_operand")))
16953               (clobber (reg:CC FLAGS_REG))
16954               (clobber (mem:BLK (scratch)))])]
16955   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16956    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16957   [(clobber (match_dup 1))
16958    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16959               (clobber (mem:BLK (scratch)))])])
16961 (define_peephole2
16962   [(match_scratch:W 1 "r")
16963    (parallel [(set (reg:P SP_REG)
16964                    (plus:P (reg:P SP_REG)
16965                            (match_operand:P 0 "const_int_operand")))
16966               (clobber (reg:CC FLAGS_REG))
16967               (clobber (mem:BLK (scratch)))])]
16968   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16969    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16970   [(clobber (match_dup 1))
16971    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16972    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16973               (clobber (mem:BLK (scratch)))])])
16975 ;; Convert esp subtractions to push.
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   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16983    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16984   [(clobber (match_dup 1))
16985    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16987 (define_peephole2
16988   [(match_scratch:W 1 "r")
16989    (parallel [(set (reg:P SP_REG)
16990                    (plus:P (reg:P SP_REG)
16991                            (match_operand:P 0 "const_int_operand")))
16992               (clobber (reg:CC FLAGS_REG))])]
16993   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16994    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16995   [(clobber (match_dup 1))
16996    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16997    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16999 ;; Convert epilogue deallocator to pop.
17000 (define_peephole2
17001   [(match_scratch:W 1 "r")
17002    (parallel [(set (reg:P SP_REG)
17003                    (plus:P (reg:P SP_REG)
17004                            (match_operand:P 0 "const_int_operand")))
17005               (clobber (reg:CC FLAGS_REG))
17006               (clobber (mem:BLK (scratch)))])]
17007   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17008    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17009   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17010               (clobber (mem:BLK (scratch)))])])
17012 ;; Two pops case is tricky, since pop causes dependency
17013 ;; on destination register.  We use two registers if available.
17014 (define_peephole2
17015   [(match_scratch:W 1 "r")
17016    (match_scratch:W 2 "r")
17017    (parallel [(set (reg:P SP_REG)
17018                    (plus:P (reg:P SP_REG)
17019                            (match_operand:P 0 "const_int_operand")))
17020               (clobber (reg:CC FLAGS_REG))
17021               (clobber (mem:BLK (scratch)))])]
17022   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17023    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17024   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17025               (clobber (mem:BLK (scratch)))])
17026    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17028 (define_peephole2
17029   [(match_scratch:W 1 "r")
17030    (parallel [(set (reg:P SP_REG)
17031                    (plus:P (reg:P SP_REG)
17032                            (match_operand:P 0 "const_int_operand")))
17033               (clobber (reg:CC FLAGS_REG))
17034               (clobber (mem:BLK (scratch)))])]
17035   "optimize_insn_for_size_p ()
17036    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17037   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17038               (clobber (mem:BLK (scratch)))])
17039    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17041 ;; Convert esp additions to pop.
17042 (define_peephole2
17043   [(match_scratch:W 1 "r")
17044    (parallel [(set (reg:P SP_REG)
17045                    (plus:P (reg:P SP_REG)
17046                            (match_operand:P 0 "const_int_operand")))
17047               (clobber (reg:CC FLAGS_REG))])]
17048   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17049   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17051 ;; Two pops case is tricky, since pop causes dependency
17052 ;; on destination register.  We use two registers if available.
17053 (define_peephole2
17054   [(match_scratch:W 1 "r")
17055    (match_scratch:W 2 "r")
17056    (parallel [(set (reg:P SP_REG)
17057                    (plus:P (reg:P SP_REG)
17058                            (match_operand:P 0 "const_int_operand")))
17059               (clobber (reg:CC FLAGS_REG))])]
17060   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17061   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17062    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17064 (define_peephole2
17065   [(match_scratch:W 1 "r")
17066    (parallel [(set (reg:P SP_REG)
17067                    (plus:P (reg:P SP_REG)
17068                            (match_operand:P 0 "const_int_operand")))
17069               (clobber (reg:CC FLAGS_REG))])]
17070   "optimize_insn_for_size_p ()
17071    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17072   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17073    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17075 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17076 ;; required and register dies.  Similarly for 128 to -128.
17077 (define_peephole2
17078   [(set (match_operand 0 "flags_reg_operand")
17079         (match_operator 1 "compare_operator"
17080           [(match_operand 2 "register_operand")
17081            (match_operand 3 "const_int_operand")]))]
17082   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17083      && incdec_operand (operands[3], GET_MODE (operands[3])))
17084     || (!TARGET_FUSE_CMP_AND_BRANCH
17085         && INTVAL (operands[3]) == 128))
17086    && ix86_match_ccmode (insn, CCGCmode)
17087    && peep2_reg_dead_p (1, operands[2])"
17088   [(parallel [(set (match_dup 0)
17089                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17090               (clobber (match_dup 2))])])
17092 ;; Convert imul by three, five and nine into lea
17093 (define_peephole2
17094   [(parallel
17095     [(set (match_operand:SWI48 0 "register_operand")
17096           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17097                       (match_operand:SWI48 2 "const359_operand")))
17098      (clobber (reg:CC FLAGS_REG))])]
17099   "!TARGET_PARTIAL_REG_STALL
17100    || <MODE>mode == SImode
17101    || optimize_function_for_size_p (cfun)"
17102   [(set (match_dup 0)
17103         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17104                     (match_dup 1)))]
17105   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17107 (define_peephole2
17108   [(parallel
17109     [(set (match_operand:SWI48 0 "register_operand")
17110           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17111                       (match_operand:SWI48 2 "const359_operand")))
17112      (clobber (reg:CC FLAGS_REG))])]
17113   "optimize_insn_for_speed_p ()
17114    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17115   [(set (match_dup 0) (match_dup 1))
17116    (set (match_dup 0)
17117         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17118                     (match_dup 0)))]
17119   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17121 ;; imul $32bit_imm, mem, reg is vector decoded, while
17122 ;; imul $32bit_imm, reg, reg is direct decoded.
17123 (define_peephole2
17124   [(match_scratch:SWI48 3 "r")
17125    (parallel [(set (match_operand:SWI48 0 "register_operand")
17126                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17127                                (match_operand:SWI48 2 "immediate_operand")))
17128               (clobber (reg:CC FLAGS_REG))])]
17129   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17130    && !satisfies_constraint_K (operands[2])"
17131   [(set (match_dup 3) (match_dup 1))
17132    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17133               (clobber (reg:CC FLAGS_REG))])])
17135 (define_peephole2
17136   [(match_scratch:SI 3 "r")
17137    (parallel [(set (match_operand:DI 0 "register_operand")
17138                    (zero_extend:DI
17139                      (mult:SI (match_operand:SI 1 "memory_operand")
17140                               (match_operand:SI 2 "immediate_operand"))))
17141               (clobber (reg:CC FLAGS_REG))])]
17142   "TARGET_64BIT
17143    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17144    && !satisfies_constraint_K (operands[2])"
17145   [(set (match_dup 3) (match_dup 1))
17146    (parallel [(set (match_dup 0)
17147                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17148               (clobber (reg:CC FLAGS_REG))])])
17150 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17151 ;; Convert it into imul reg, reg
17152 ;; It would be better to force assembler to encode instruction using long
17153 ;; immediate, but there is apparently no way to do so.
17154 (define_peephole2
17155   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17156                    (mult:SWI248
17157                     (match_operand:SWI248 1 "nonimmediate_operand")
17158                     (match_operand:SWI248 2 "const_int_operand")))
17159               (clobber (reg:CC FLAGS_REG))])
17160    (match_scratch:SWI248 3 "r")]
17161   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17162    && satisfies_constraint_K (operands[2])"
17163   [(set (match_dup 3) (match_dup 2))
17164    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17165               (clobber (reg:CC FLAGS_REG))])]
17167   if (!rtx_equal_p (operands[0], operands[1]))
17168     emit_move_insn (operands[0], operands[1]);
17171 ;; After splitting up read-modify operations, array accesses with memory
17172 ;; operands might end up in form:
17173 ;;  sall    $2, %eax
17174 ;;  movl    4(%esp), %edx
17175 ;;  addl    %edx, %eax
17176 ;; instead of pre-splitting:
17177 ;;  sall    $2, %eax
17178 ;;  addl    4(%esp), %eax
17179 ;; Turn it into:
17180 ;;  movl    4(%esp), %edx
17181 ;;  leal    (%edx,%eax,4), %eax
17183 (define_peephole2
17184   [(match_scratch:W 5 "r")
17185    (parallel [(set (match_operand 0 "register_operand")
17186                    (ashift (match_operand 1 "register_operand")
17187                            (match_operand 2 "const_int_operand")))
17188                (clobber (reg:CC FLAGS_REG))])
17189    (parallel [(set (match_operand 3 "register_operand")
17190                    (plus (match_dup 0)
17191                          (match_operand 4 "x86_64_general_operand")))
17192                    (clobber (reg:CC FLAGS_REG))])]
17193   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17194    /* Validate MODE for lea.  */
17195    && ((!TARGET_PARTIAL_REG_STALL
17196         && (GET_MODE (operands[0]) == QImode
17197             || GET_MODE (operands[0]) == HImode))
17198        || GET_MODE (operands[0]) == SImode
17199        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17200    && (rtx_equal_p (operands[0], operands[3])
17201        || peep2_reg_dead_p (2, operands[0]))
17202    /* We reorder load and the shift.  */
17203    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17204   [(set (match_dup 5) (match_dup 4))
17205    (set (match_dup 0) (match_dup 1))]
17207   enum machine_mode op1mode = GET_MODE (operands[1]);
17208   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17209   int scale = 1 << INTVAL (operands[2]);
17210   rtx index = gen_lowpart (word_mode, operands[1]);
17211   rtx base = gen_lowpart (word_mode, operands[5]);
17212   rtx dest = gen_lowpart (mode, operands[3]);
17214   operands[1] = gen_rtx_PLUS (word_mode, base,
17215                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17216   operands[5] = base;
17217   if (mode != word_mode)
17218     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17219   if (op1mode != word_mode)
17220     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17221   operands[0] = dest;
17224 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17225 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17226 ;; caught for use by garbage collectors and the like.  Using an insn that
17227 ;; maps to SIGILL makes it more likely the program will rightfully die.
17228 ;; Keeping with tradition, "6" is in honor of #UD.
17229 (define_insn "trap"
17230   [(trap_if (const_int 1) (const_int 6))]
17231   ""
17232   { return ASM_SHORT "0x0b0f"; }
17233   [(set_attr "length" "2")])
17235 (define_expand "prefetch"
17236   [(prefetch (match_operand 0 "address_operand")
17237              (match_operand:SI 1 "const_int_operand")
17238              (match_operand:SI 2 "const_int_operand"))]
17239   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17241   int rw = INTVAL (operands[1]);
17242   int locality = INTVAL (operands[2]);
17244   gcc_assert (rw == 0 || rw == 1);
17245   gcc_assert (IN_RANGE (locality, 0, 3));
17247   if (TARGET_PRFCHW && rw)
17248     operands[2] = GEN_INT (3);
17249   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17250      supported by SSE counterpart or the SSE prefetch is not available
17251      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17252      of locality.  */
17253   else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17254     operands[2] = GEN_INT (3);
17255   else
17256     operands[1] = const0_rtx;
17259 (define_insn "*prefetch_sse"
17260   [(prefetch (match_operand 0 "address_operand" "p")
17261              (const_int 0)
17262              (match_operand:SI 1 "const_int_operand"))]
17263   "TARGET_PREFETCH_SSE"
17265   static const char * const patterns[4] = {
17266    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17267   };
17269   int locality = INTVAL (operands[1]);
17270   gcc_assert (IN_RANGE (locality, 0, 3));
17272   return patterns[locality];
17274   [(set_attr "type" "sse")
17275    (set_attr "atom_sse_attr" "prefetch")
17276    (set (attr "length_address")
17277         (symbol_ref "memory_address_length (operands[0], false)"))
17278    (set_attr "memory" "none")])
17280 (define_insn "*prefetch_3dnow"
17281   [(prefetch (match_operand 0 "address_operand" "p")
17282              (match_operand:SI 1 "const_int_operand" "n")
17283              (const_int 3))]
17284   "TARGET_3DNOW || TARGET_PRFCHW"
17286   if (INTVAL (operands[1]) == 0)
17287     return "prefetch\t%a0";
17288   else
17289     return "prefetchw\t%a0";
17291   [(set_attr "type" "mmx")
17292    (set (attr "length_address")
17293         (symbol_ref "memory_address_length (operands[0], false)"))
17294    (set_attr "memory" "none")])
17296 (define_expand "stack_protect_set"
17297   [(match_operand 0 "memory_operand")
17298    (match_operand 1 "memory_operand")]
17299   "!TARGET_HAS_BIONIC"
17301   rtx (*insn)(rtx, rtx);
17303 #ifdef TARGET_THREAD_SSP_OFFSET
17304   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17305   insn = (TARGET_LP64
17306           ? gen_stack_tls_protect_set_di
17307           : gen_stack_tls_protect_set_si);
17308 #else
17309   insn = (TARGET_LP64
17310           ? gen_stack_protect_set_di
17311           : gen_stack_protect_set_si);
17312 #endif
17314   emit_insn (insn (operands[0], operands[1]));
17315   DONE;
17318 (define_insn "stack_protect_set_<mode>"
17319   [(set (match_operand:PTR 0 "memory_operand" "=m")
17320         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17321                     UNSPEC_SP_SET))
17322    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17323    (clobber (reg:CC FLAGS_REG))]
17324   "!TARGET_HAS_BIONIC"
17325   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17326   [(set_attr "type" "multi")])
17328 (define_insn "stack_tls_protect_set_<mode>"
17329   [(set (match_operand:PTR 0 "memory_operand" "=m")
17330         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17331                     UNSPEC_SP_TLS_SET))
17332    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17333    (clobber (reg:CC FLAGS_REG))]
17334   ""
17335   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17336   [(set_attr "type" "multi")])
17338 (define_expand "stack_protect_test"
17339   [(match_operand 0 "memory_operand")
17340    (match_operand 1 "memory_operand")
17341    (match_operand 2)]
17342   "!TARGET_HAS_BIONIC"
17344   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17346   rtx (*insn)(rtx, rtx, rtx);
17348 #ifdef TARGET_THREAD_SSP_OFFSET
17349   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17350   insn = (TARGET_LP64
17351           ? gen_stack_tls_protect_test_di
17352           : gen_stack_tls_protect_test_si);
17353 #else
17354   insn = (TARGET_LP64
17355           ? gen_stack_protect_test_di
17356           : gen_stack_protect_test_si);
17357 #endif
17359   emit_insn (insn (flags, operands[0], operands[1]));
17361   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17362                                   flags, const0_rtx, operands[2]));
17363   DONE;
17366 (define_insn "stack_protect_test_<mode>"
17367   [(set (match_operand:CCZ 0 "flags_reg_operand")
17368         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17369                      (match_operand:PTR 2 "memory_operand" "m")]
17370                     UNSPEC_SP_TEST))
17371    (clobber (match_scratch:PTR 3 "=&r"))]
17372   "!TARGET_HAS_BIONIC"
17373   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17374   [(set_attr "type" "multi")])
17376 (define_insn "stack_tls_protect_test_<mode>"
17377   [(set (match_operand:CCZ 0 "flags_reg_operand")
17378         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17379                      (match_operand:PTR 2 "const_int_operand" "i")]
17380                     UNSPEC_SP_TLS_TEST))
17381    (clobber (match_scratch:PTR 3 "=r"))]
17382   ""
17383   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17384   [(set_attr "type" "multi")])
17386 (define_insn "sse4_2_crc32<mode>"
17387   [(set (match_operand:SI 0 "register_operand" "=r")
17388         (unspec:SI
17389           [(match_operand:SI 1 "register_operand" "0")
17390            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17391           UNSPEC_CRC32))]
17392   "TARGET_SSE4_2 || TARGET_CRC32"
17393   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17394   [(set_attr "type" "sselog1")
17395    (set_attr "prefix_rep" "1")
17396    (set_attr "prefix_extra" "1")
17397    (set (attr "prefix_data16")
17398      (if_then_else (match_operand:HI 2)
17399        (const_string "1")
17400        (const_string "*")))
17401    (set (attr "prefix_rex")
17402      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17403        (const_string "1")
17404        (const_string "*")))
17405    (set_attr "mode" "SI")])
17407 (define_insn "sse4_2_crc32di"
17408   [(set (match_operand:DI 0 "register_operand" "=r")
17409         (unspec:DI
17410           [(match_operand:DI 1 "register_operand" "0")
17411            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17412           UNSPEC_CRC32))]
17413   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17414   "crc32{q}\t{%2, %0|%0, %2}"
17415   [(set_attr "type" "sselog1")
17416    (set_attr "prefix_rep" "1")
17417    (set_attr "prefix_extra" "1")
17418    (set_attr "mode" "DI")])
17420 (define_insn "rdpmc"
17421   [(set (match_operand:DI 0 "register_operand" "=A")
17422         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17423                             UNSPECV_RDPMC))]
17424   "!TARGET_64BIT"
17425   "rdpmc"
17426   [(set_attr "type" "other")
17427    (set_attr "length" "2")])
17429 (define_insn "rdpmc_rex64"
17430   [(set (match_operand:DI 0 "register_operand" "=a")
17431         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17432                             UNSPECV_RDPMC))
17433    (set (match_operand:DI 1 "register_operand" "=d")
17434         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17435   "TARGET_64BIT"
17436   "rdpmc"
17437   [(set_attr "type" "other")
17438    (set_attr "length" "2")])
17440 (define_insn "rdtsc"
17441   [(set (match_operand:DI 0 "register_operand" "=A")
17442         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17443   "!TARGET_64BIT"
17444   "rdtsc"
17445   [(set_attr "type" "other")
17446    (set_attr "length" "2")])
17448 (define_insn "rdtsc_rex64"
17449   [(set (match_operand:DI 0 "register_operand" "=a")
17450         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17451    (set (match_operand:DI 1 "register_operand" "=d")
17452         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17453   "TARGET_64BIT"
17454   "rdtsc"
17455   [(set_attr "type" "other")
17456    (set_attr "length" "2")])
17458 (define_insn "rdtscp"
17459   [(set (match_operand:DI 0 "register_operand" "=A")
17460         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17461    (set (match_operand:SI 1 "register_operand" "=c")
17462         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17463   "!TARGET_64BIT"
17464   "rdtscp"
17465   [(set_attr "type" "other")
17466    (set_attr "length" "3")])
17468 (define_insn "rdtscp_rex64"
17469   [(set (match_operand:DI 0 "register_operand" "=a")
17470         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17471    (set (match_operand:DI 1 "register_operand" "=d")
17472         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17473    (set (match_operand:SI 2 "register_operand" "=c")
17474         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17475   "TARGET_64BIT"
17476   "rdtscp"
17477   [(set_attr "type" "other")
17478    (set_attr "length" "3")])
17480 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17482 ;; FXSR, XSAVE and XSAVEOPT instructions
17484 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17486 (define_insn "fxsave"
17487   [(set (match_operand:BLK 0 "memory_operand" "=m")
17488         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17489   "TARGET_FXSR"
17490   "fxsave\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 "fxsave64"
17497   [(set (match_operand:BLK 0 "memory_operand" "=m")
17498         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17499   "TARGET_64BIT && TARGET_FXSR"
17500   "fxsave64\t%0"
17501   [(set_attr "type" "other")
17502    (set_attr "memory" "store")
17503    (set (attr "length")
17504         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17506 (define_insn "fxrstor"
17507   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17508                     UNSPECV_FXRSTOR)]
17509   "TARGET_FXSR"
17510   "fxrstor\t%0"
17511   [(set_attr "type" "other")
17512    (set_attr "memory" "load")
17513    (set (attr "length")
17514         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17516 (define_insn "fxrstor64"
17517   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17518                     UNSPECV_FXRSTOR64)]
17519   "TARGET_64BIT && TARGET_FXSR"
17520   "fxrstor64\t%0"
17521   [(set_attr "type" "other")
17522    (set_attr "memory" "load")
17523    (set (attr "length")
17524         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17526 (define_int_iterator ANY_XSAVE
17527         [UNSPECV_XSAVE
17528          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17530 (define_int_iterator ANY_XSAVE64
17531         [UNSPECV_XSAVE64
17532          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17534 (define_int_attr xsave
17535         [(UNSPECV_XSAVE "xsave")
17536          (UNSPECV_XSAVE64 "xsave64")
17537          (UNSPECV_XSAVEOPT "xsaveopt")
17538          (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17540 (define_insn "<xsave>"
17541   [(set (match_operand:BLK 0 "memory_operand" "=m")
17542         (unspec_volatile:BLK
17543          [(match_operand:DI 1 "register_operand" "A")]
17544          ANY_XSAVE))]
17545   "!TARGET_64BIT && TARGET_XSAVE"
17546   "<xsave>\t%0"
17547   [(set_attr "type" "other")
17548    (set_attr "memory" "store")
17549    (set (attr "length")
17550         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17552 (define_insn "<xsave>_rex64"
17553   [(set (match_operand:BLK 0 "memory_operand" "=m")
17554         (unspec_volatile:BLK
17555          [(match_operand:SI 1 "register_operand" "a")
17556           (match_operand:SI 2 "register_operand" "d")]
17557          ANY_XSAVE))]
17558   "TARGET_64BIT && TARGET_XSAVE"
17559   "<xsave>\t%0"
17560   [(set_attr "type" "other")
17561    (set_attr "memory" "store")
17562    (set (attr "length")
17563         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17565 (define_insn "<xsave>"
17566   [(set (match_operand:BLK 0 "memory_operand" "=m")
17567         (unspec_volatile:BLK
17568          [(match_operand:SI 1 "register_operand" "a")
17569           (match_operand:SI 2 "register_operand" "d")]
17570          ANY_XSAVE64))]
17571   "TARGET_64BIT && TARGET_XSAVE"
17572   "<xsave>\t%0"
17573   [(set_attr "type" "other")
17574    (set_attr "memory" "store")
17575    (set (attr "length")
17576         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17578 (define_insn "xrstor"
17579    [(unspec_volatile:BLK
17580      [(match_operand:BLK 0 "memory_operand" "m")
17581       (match_operand:DI 1 "register_operand" "A")]
17582      UNSPECV_XRSTOR)]
17583   "!TARGET_64BIT && TARGET_XSAVE"
17584   "xrstor\t%0"
17585   [(set_attr "type" "other")
17586    (set_attr "memory" "load")
17587    (set (attr "length")
17588         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17590 (define_insn "xrstor_rex64"
17591    [(unspec_volatile:BLK
17592      [(match_operand:BLK 0 "memory_operand" "m")
17593       (match_operand:SI 1 "register_operand" "a")
17594       (match_operand:SI 2 "register_operand" "d")]
17595      UNSPECV_XRSTOR)]
17596   "TARGET_64BIT && TARGET_XSAVE"
17597   "xrstor\t%0"
17598   [(set_attr "type" "other")
17599    (set_attr "memory" "load")
17600    (set (attr "length")
17601         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17603 (define_insn "xrstor64"
17604    [(unspec_volatile:BLK
17605      [(match_operand:BLK 0 "memory_operand" "m")
17606       (match_operand:SI 1 "register_operand" "a")
17607       (match_operand:SI 2 "register_operand" "d")]
17608      UNSPECV_XRSTOR64)]
17609   "TARGET_64BIT && TARGET_XSAVE"
17610   "xrstor64\t%0"
17611   [(set_attr "type" "other")
17612    (set_attr "memory" "load")
17613    (set (attr "length")
17614         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17616 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17618 ;; LWP instructions
17620 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17622 (define_expand "lwp_llwpcb"
17623   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17624                     UNSPECV_LLWP_INTRINSIC)]
17625   "TARGET_LWP")
17627 (define_insn "*lwp_llwpcb<mode>1"
17628   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17629                     UNSPECV_LLWP_INTRINSIC)]
17630   "TARGET_LWP"
17631   "llwpcb\t%0"
17632   [(set_attr "type" "lwp")
17633    (set_attr "mode" "<MODE>")
17634    (set_attr "length" "5")])
17636 (define_expand "lwp_slwpcb"
17637   [(set (match_operand 0 "register_operand" "=r")
17638         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17639   "TARGET_LWP"
17641   rtx (*insn)(rtx);
17643   insn = (Pmode == DImode
17644           ? gen_lwp_slwpcbdi
17645           : gen_lwp_slwpcbsi);
17647   emit_insn (insn (operands[0]));
17648   DONE;
17651 (define_insn "lwp_slwpcb<mode>"
17652   [(set (match_operand:P 0 "register_operand" "=r")
17653         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17654   "TARGET_LWP"
17655   "slwpcb\t%0"
17656   [(set_attr "type" "lwp")
17657    (set_attr "mode" "<MODE>")
17658    (set_attr "length" "5")])
17660 (define_expand "lwp_lwpval<mode>3"
17661   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17662                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17663                      (match_operand:SI 3 "const_int_operand" "i")]
17664                     UNSPECV_LWPVAL_INTRINSIC)]
17665   "TARGET_LWP"
17666   ;; Avoid unused variable warning.
17667   "(void) operands[0];")
17669 (define_insn "*lwp_lwpval<mode>3_1"
17670   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17671                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17672                      (match_operand:SI 2 "const_int_operand" "i")]
17673                     UNSPECV_LWPVAL_INTRINSIC)]
17674   "TARGET_LWP"
17675   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17676   [(set_attr "type" "lwp")
17677    (set_attr "mode" "<MODE>")
17678    (set (attr "length")
17679         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17681 (define_expand "lwp_lwpins<mode>3"
17682   [(set (reg:CCC FLAGS_REG)
17683         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17684                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17685                               (match_operand:SI 3 "const_int_operand" "i")]
17686                              UNSPECV_LWPINS_INTRINSIC))
17687    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17688         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17689   "TARGET_LWP")
17691 (define_insn "*lwp_lwpins<mode>3_1"
17692   [(set (reg:CCC FLAGS_REG)
17693         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17694                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17695                               (match_operand:SI 2 "const_int_operand" "i")]
17696                              UNSPECV_LWPINS_INTRINSIC))]
17697   "TARGET_LWP"
17698   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17699   [(set_attr "type" "lwp")
17700    (set_attr "mode" "<MODE>")
17701    (set (attr "length")
17702         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17704 (define_int_iterator RDFSGSBASE
17705         [UNSPECV_RDFSBASE
17706          UNSPECV_RDGSBASE])
17708 (define_int_iterator WRFSGSBASE
17709         [UNSPECV_WRFSBASE
17710          UNSPECV_WRGSBASE])
17712 (define_int_attr fsgs
17713         [(UNSPECV_RDFSBASE "fs")
17714          (UNSPECV_RDGSBASE "gs")
17715          (UNSPECV_WRFSBASE "fs")
17716          (UNSPECV_WRGSBASE "gs")])
17718 (define_insn "rd<fsgs>base<mode>"
17719   [(set (match_operand:SWI48 0 "register_operand" "=r")
17720         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
17721   "TARGET_64BIT && TARGET_FSGSBASE"
17722   "rd<fsgs>base\t%0"
17723   [(set_attr "type" "other")
17724    (set_attr "prefix_extra" "2")])
17726 (define_insn "wr<fsgs>base<mode>"
17727   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17728                     WRFSGSBASE)]
17729   "TARGET_64BIT && TARGET_FSGSBASE"
17730   "wr<fsgs>base\t%0"
17731   [(set_attr "type" "other")
17732    (set_attr "prefix_extra" "2")])
17734 (define_insn "rdrand<mode>_1"
17735   [(set (match_operand:SWI248 0 "register_operand" "=r")
17736         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
17737    (set (reg:CCC FLAGS_REG)
17738         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
17739   "TARGET_RDRND"
17740   "rdrand\t%0"
17741   [(set_attr "type" "other")
17742    (set_attr "prefix_extra" "1")])
17744 (define_insn "rdseed<mode>_1"
17745   [(set (match_operand:SWI248 0 "register_operand" "=r")
17746         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
17747    (set (reg:CCC FLAGS_REG)
17748         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
17749   "TARGET_RDSEED"
17750   "rdseed\t%0"
17751   [(set_attr "type" "other")
17752    (set_attr "prefix_extra" "1")])
17754 (define_expand "pause"
17755   [(set (match_dup 0)
17756         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17757   ""
17759   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17760   MEM_VOLATILE_P (operands[0]) = 1;
17763 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17764 ;; They have the same encoding.
17765 (define_insn "*pause"
17766   [(set (match_operand:BLK 0)
17767         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17768   ""
17769   "rep%; nop"
17770   [(set_attr "length" "2")
17771    (set_attr "memory" "unknown")])
17773 (define_expand "xbegin"
17774   [(set (match_operand:SI 0 "register_operand")
17775         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
17776   "TARGET_RTM"
17778   rtx label = gen_label_rtx ();
17780   /* xbegin is emitted as jump_insn, so reload won't be able
17781      to reload its operand.  Force the value into AX hard register.  */
17782   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
17783   emit_move_insn (ax_reg, constm1_rtx);
17785   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
17787   emit_label (label);
17788   LABEL_NUSES (label) = 1;
17790   emit_move_insn (operands[0], ax_reg);
17792   DONE;
17795 (define_insn "xbegin_1"
17796   [(set (pc)
17797         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
17798                           (const_int 0))
17799                       (label_ref (match_operand 1))
17800                       (pc)))
17801    (set (match_operand:SI 0 "register_operand" "+a")
17802         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
17803   "TARGET_RTM"
17804   "xbegin\t%l1"
17805   [(set_attr "type" "other")
17806    (set_attr "length" "6")])
17808 (define_insn "xend"
17809   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
17810   "TARGET_RTM"
17811   "xend"
17812   [(set_attr "type" "other")
17813    (set_attr "length" "3")])
17815 (define_insn "xabort"
17816   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
17817                     UNSPECV_XABORT)]
17818   "TARGET_RTM"
17819   "xabort\t%0"
17820   [(set_attr "type" "other")
17821    (set_attr "length" "3")])
17823 (define_expand "xtest"
17824   [(set (match_operand:QI 0 "register_operand")
17825         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
17826   "TARGET_RTM"
17828   emit_insn (gen_xtest_1 ());
17830   ix86_expand_setcc (operands[0], NE,
17831                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17832   DONE;
17835 (define_insn "xtest_1"
17836   [(set (reg:CCZ FLAGS_REG)
17837         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
17838   "TARGET_RTM"
17839   "xtest"
17840   [(set_attr "type" "other")
17841    (set_attr "length" "3")])
17843 (include "mmx.md")
17844 (include "sse.md")
17845 (include "sync.md")