gcc50/csu: Skip depends step to avoid possible race
[dragonfly.git] / contrib / gcc-4.4 / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;;     operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
39 ;;
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;;     %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
46
47 ;; UNSPEC usage:
48
49 (define_constants
50   [; Relocation specifiers
51    (UNSPEC_GOT                  0)
52    (UNSPEC_GOTOFF               1)
53    (UNSPEC_GOTPCREL             2)
54    (UNSPEC_GOTTPOFF             3)
55    (UNSPEC_TPOFF                4)
56    (UNSPEC_NTPOFF               5)
57    (UNSPEC_DTPOFF               6)
58    (UNSPEC_GOTNTPOFF            7)
59    (UNSPEC_INDNTPOFF            8)
60    (UNSPEC_PLTOFF               9)
61    (UNSPEC_MACHOPIC_OFFSET      10)
62
63    ; Prologue support
64    (UNSPEC_STACK_ALLOC          11)
65    (UNSPEC_SET_GOT              12)
66    (UNSPEC_SSE_PROLOGUE_SAVE    13)
67    (UNSPEC_REG_SAVE             14)
68    (UNSPEC_DEF_CFA              15)
69    (UNSPEC_SET_RIP              16)
70    (UNSPEC_SET_GOT_OFFSET       17)
71    (UNSPEC_MEMORY_BLOCKAGE      18)
72
73    ; TLS support
74    (UNSPEC_TP                   20)
75    (UNSPEC_TLS_GD               21)
76    (UNSPEC_TLS_LD_BASE          22)
77    (UNSPEC_TLSDESC              23)
78    (UNSPEC_TLS_IE_SUN           24)
79
80    ; Other random patterns
81    (UNSPEC_EH_RETURN            29)
82    (UNSPEC_SCAS                 30)
83    (UNSPEC_FNSTSW               31)
84    (UNSPEC_SAHF                 32)
85    (UNSPEC_PARITY               33)
86    (UNSPEC_FSTCW                34)
87    (UNSPEC_ADD_CARRY            35)
88    (UNSPEC_FLDCW                36)
89    (UNSPEC_REP                  37)
90    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
91    (UNSPEC_TRUNC_NOOP           39)
92
93    ; For SSE/MMX support:
94    (UNSPEC_FIX_NOTRUNC          40)
95    (UNSPEC_MASKMOV              41)
96    (UNSPEC_MOVMSK               42)
97    (UNSPEC_MOVNT                43)
98    (UNSPEC_MOVU                 44)
99    (UNSPEC_RCP                  45)
100    (UNSPEC_RSQRT                46)
101    (UNSPEC_SFENCE               47)
102    (UNSPEC_PFRCP                49)
103    (UNSPEC_PFRCPIT1             40)
104    (UNSPEC_PFRCPIT2             41)
105    (UNSPEC_PFRSQRT              42)
106    (UNSPEC_PFRSQIT1             43)
107    (UNSPEC_MFENCE               44)
108    (UNSPEC_LFENCE               45)
109    (UNSPEC_PSADBW               46)
110    (UNSPEC_LDDQU                47)
111    (UNSPEC_MS_TO_SYSV_CALL      48)
112
113    ; Generic math support
114    (UNSPEC_COPYSIGN             50)
115    (UNSPEC_IEEE_MIN             51)     ; not commutative
116    (UNSPEC_IEEE_MAX             52)     ; not commutative
117
118    ; x87 Floating point
119    (UNSPEC_SIN                  60)
120    (UNSPEC_COS                  61)
121    (UNSPEC_FPATAN               62)
122    (UNSPEC_FYL2X                63)
123    (UNSPEC_FYL2XP1              64)
124    (UNSPEC_FRNDINT              65)
125    (UNSPEC_FIST                 66)
126    (UNSPEC_F2XM1                67)
127    (UNSPEC_TAN                  68)
128    (UNSPEC_FXAM                 69)
129
130    ; x87 Rounding
131    (UNSPEC_FRNDINT_FLOOR        70)
132    (UNSPEC_FRNDINT_CEIL         71)
133    (UNSPEC_FRNDINT_TRUNC        72)
134    (UNSPEC_FRNDINT_MASK_PM      73)
135    (UNSPEC_FIST_FLOOR           74)
136    (UNSPEC_FIST_CEIL            75)
137
138    ; x87 Double output FP
139    (UNSPEC_SINCOS_COS           80)
140    (UNSPEC_SINCOS_SIN           81)
141    (UNSPEC_XTRACT_FRACT         84)
142    (UNSPEC_XTRACT_EXP           85)
143    (UNSPEC_FSCALE_FRACT         86)
144    (UNSPEC_FSCALE_EXP           87)
145    (UNSPEC_FPREM_F              88)
146    (UNSPEC_FPREM_U              89)
147    (UNSPEC_FPREM1_F             90)
148    (UNSPEC_FPREM1_U             91)
149
150    (UNSPEC_C2_FLAG              95)
151    (UNSPEC_FXAM_MEM             96)
152
153    ; SSP patterns
154    (UNSPEC_SP_SET               100)
155    (UNSPEC_SP_TEST              101)
156    (UNSPEC_SP_TLS_SET           102)
157    (UNSPEC_SP_TLS_TEST          103)
158
159    ; SSSE3
160    (UNSPEC_PSHUFB               120)
161    (UNSPEC_PSIGN                121)
162    (UNSPEC_PALIGNR              122)
163
164    ; For SSE4A support
165    (UNSPEC_EXTRQI               130)
166    (UNSPEC_EXTRQ                131)
167    (UNSPEC_INSERTQI             132)
168    (UNSPEC_INSERTQ              133)
169
170    ; For SSE4.1 support
171    (UNSPEC_BLENDV               134)
172    (UNSPEC_INSERTPS             135)
173    (UNSPEC_DP                   136)
174    (UNSPEC_MOVNTDQA             137)
175    (UNSPEC_MPSADBW              138)
176    (UNSPEC_PHMINPOSUW           139)
177    (UNSPEC_PTEST                140)
178    (UNSPEC_ROUND                141)
179
180    ; For SSE4.2 support
181    (UNSPEC_CRC32                143)
182    (UNSPEC_PCMPESTR             144)
183    (UNSPEC_PCMPISTR             145)
184
185    ;; For SSE5
186    (UNSPEC_SSE5_INTRINSIC       150)
187    (UNSPEC_SSE5_UNSIGNED_CMP    151)
188    (UNSPEC_SSE5_TRUEFALSE       152)
189    (UNSPEC_SSE5_PERMUTE         153)
190    (UNSPEC_FRCZ                 154)
191    (UNSPEC_CVTPH2PS             155)
192    (UNSPEC_CVTPS2PH             156)
193
194    ; For AES support
195    (UNSPEC_AESENC               159)
196    (UNSPEC_AESENCLAST           160)
197    (UNSPEC_AESDEC               161)
198    (UNSPEC_AESDECLAST           162)
199    (UNSPEC_AESIMC               163)
200    (UNSPEC_AESKEYGENASSIST      164)
201
202    ; For PCLMUL support
203    (UNSPEC_PCLMUL               165)
204
205    ; For AVX support
206    (UNSPEC_PCMP                 166)
207    (UNSPEC_VPERMIL              167)
208    (UNSPEC_VPERMIL2F128         168)
209    (UNSPEC_MASKLOAD             169)
210    (UNSPEC_MASKSTORE            170)
211    (UNSPEC_CAST                 171)
212    (UNSPEC_VTESTP               172)
213   ])
214
215 (define_constants
216   [(UNSPECV_BLOCKAGE            0)
217    (UNSPECV_STACK_PROBE         1)
218    (UNSPECV_EMMS                2)
219    (UNSPECV_LDMXCSR             3)
220    (UNSPECV_STMXCSR             4)
221    (UNSPECV_FEMMS               5)
222    (UNSPECV_CLFLUSH             6)
223    (UNSPECV_ALIGN               7)
224    (UNSPECV_MONITOR             8)
225    (UNSPECV_MWAIT               9)
226    (UNSPECV_CMPXCHG             10)
227    (UNSPECV_XCHG                12)
228    (UNSPECV_LOCK                13)
229    (UNSPECV_PROLOGUE_USE        14)
230    (UNSPECV_CLD                 15)
231    (UNSPECV_VZEROALL            16)
232    (UNSPECV_VZEROUPPER          17)
233   ])
234
235 ;; Constants to represent pcomtrue/pcomfalse variants
236 (define_constants
237   [(PCOM_FALSE                  0)
238    (PCOM_TRUE                   1)
239    (COM_FALSE_S                 2)
240    (COM_FALSE_P                 3)
241    (COM_TRUE_S                  4)
242    (COM_TRUE_P                  5)
243   ])
244
245 ;; Constants used in the SSE5 pperm instruction
246 (define_constants
247   [(PPERM_SRC                   0x00)   /* copy source */
248    (PPERM_INVERT                0x20)   /* invert source */
249    (PPERM_REVERSE               0x40)   /* bit reverse source */
250    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
251    (PPERM_ZERO                  0x80)   /* all 0's */
252    (PPERM_ONES                  0xa0)   /* all 1's */
253    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
254    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
255    (PPERM_SRC1                  0x00)   /* use first source byte */
256    (PPERM_SRC2                  0x10)   /* use second source byte */
257    ])
258
259 ;; Registers by name.
260 (define_constants
261   [(AX_REG                       0)
262    (DX_REG                       1)
263    (CX_REG                       2)
264    (BX_REG                       3)
265    (SI_REG                       4)
266    (DI_REG                       5)
267    (BP_REG                       6)
268    (SP_REG                       7)
269    (ST0_REG                      8)
270    (ST1_REG                      9)
271    (ST2_REG                     10)
272    (ST3_REG                     11)
273    (ST4_REG                     12)
274    (ST5_REG                     13)
275    (ST6_REG                     14)
276    (ST7_REG                     15)
277    (FLAGS_REG                   17)
278    (FPSR_REG                    18)
279    (FPCR_REG                    19)
280    (XMM0_REG                    21)
281    (XMM1_REG                    22)
282    (XMM2_REG                    23)
283    (XMM3_REG                    24)
284    (XMM4_REG                    25)
285    (XMM5_REG                    26)
286    (XMM6_REG                    27)
287    (XMM7_REG                    28)
288    (MM0_REG                     29)
289    (MM1_REG                     30)
290    (MM2_REG                     31)
291    (MM3_REG                     32)
292    (MM4_REG                     33)
293    (MM5_REG                     34)
294    (MM6_REG                     35)
295    (MM7_REG                     36)
296    (R8_REG                      37)
297    (R9_REG                      38)
298    (R10_REG                     39)
299    (R11_REG                     40)
300    (R13_REG                     42)
301    (XMM8_REG                    45)
302    (XMM9_REG                    46)
303    (XMM10_REG                   47)
304    (XMM11_REG                   48)
305    (XMM12_REG                   49)
306    (XMM13_REG                   50)
307    (XMM14_REG                   51)
308    (XMM15_REG                   52)
309   ])
310
311 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
312 ;; from i386.c.
313
314 ;; In C guard expressions, put expressions which may be compile-time
315 ;; constants first.  This allows for better optimization.  For
316 ;; example, write "TARGET_64BIT && reload_completed", not
317 ;; "reload_completed && TARGET_64BIT".
318
319 \f
320 ;; Processor type.
321 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
322                     generic64,amdfam10"
323   (const (symbol_ref "ix86_schedule")))
324
325 ;; A basic instruction type.  Refinements due to arguments to be
326 ;; provided in other attributes.
327 (define_attr "type"
328   "other,multi,
329    alu,alu1,negnot,imov,imovx,lea,
330    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
331    icmp,test,ibr,setcc,icmov,
332    push,pop,call,callv,leave,
333    str,bitmanip,
334    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
335    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
336    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
337    ssemuladd,sse4arg,
338    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
339   (const_string "other"))
340
341 ;; Main data type used by the insn
342 (define_attr "mode"
343   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
344   (const_string "unknown"))
345
346 ;; The CPU unit operations uses.
347 (define_attr "unit" "integer,i387,sse,mmx,unknown"
348   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
349            (const_string "i387")
350          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
351                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
352                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
353            (const_string "sse")
354          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
355            (const_string "mmx")
356          (eq_attr "type" "other")
357            (const_string "unknown")]
358          (const_string "integer")))
359
360 ;; The (bounding maximum) length of an instruction immediate.
361 (define_attr "length_immediate" ""
362   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
363                           bitmanip")
364            (const_int 0)
365          (eq_attr "unit" "i387,sse,mmx")
366            (const_int 0)
367          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
368                           imul,icmp,push,pop")
369            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
370          (eq_attr "type" "imov,test")
371            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
372          (eq_attr "type" "call")
373            (if_then_else (match_operand 0 "constant_call_address_operand" "")
374              (const_int 4)
375              (const_int 0))
376          (eq_attr "type" "callv")
377            (if_then_else (match_operand 1 "constant_call_address_operand" "")
378              (const_int 4)
379              (const_int 0))
380          ;; We don't know the size before shorten_branches.  Expect
381          ;; the instruction to fit for better scheduling.
382          (eq_attr "type" "ibr")
383            (const_int 1)
384          ]
385          (symbol_ref "/* Update immediate_length and other attributes! */
386                       gcc_unreachable (),1")))
387
388 ;; The (bounding maximum) length of an instruction address.
389 (define_attr "length_address" ""
390   (cond [(eq_attr "type" "str,other,multi,fxch")
391            (const_int 0)
392          (and (eq_attr "type" "call")
393               (match_operand 0 "constant_call_address_operand" ""))
394              (const_int 0)
395          (and (eq_attr "type" "callv")
396               (match_operand 1 "constant_call_address_operand" ""))
397              (const_int 0)
398          ]
399          (symbol_ref "ix86_attr_length_address_default (insn)")))
400
401 ;; Set when length prefix is used.
402 (define_attr "prefix_data16" ""
403   (if_then_else (ior (eq_attr "mode" "HI")
404                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
405     (const_int 1)
406     (const_int 0)))
407
408 ;; Set when string REP prefix is used.
409 (define_attr "prefix_rep" ""
410   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
411     (const_int 1)
412     (const_int 0)))
413
414 ;; Set when 0f opcode prefix is used.
415 (define_attr "prefix_0f" ""
416   (if_then_else
417     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
418          (eq_attr "unit" "sse,mmx"))
419     (const_int 1)
420     (const_int 0)))
421
422 ;; Set when REX opcode prefix is used.
423 (define_attr "prefix_rex" ""
424   (cond [(and (eq_attr "mode" "DI")
425               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
426            (const_int 1)
427          (and (eq_attr "mode" "QI")
428               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
429                   (const_int 0)))
430            (const_int 1)
431          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
432              (const_int 0))
433            (const_int 1)
434         ]
435         (const_int 0)))
436
437 ;; There are also additional prefixes in SSSE3.
438 (define_attr "prefix_extra" "" (const_int 0))
439
440 ;; Prefix used: original, VEX or maybe VEX.
441 (define_attr "prefix" "orig,vex,maybe_vex"
442   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
443     (const_string "vex")
444     (const_string "orig")))
445
446 ;; There is a 8bit immediate for VEX.
447 (define_attr "prefix_vex_imm8" "" (const_int 0))
448
449 ;; VEX W bit is used.
450 (define_attr "prefix_vex_w" "" (const_int 0))
451
452 ;; The length of VEX prefix
453 (define_attr "length_vex" ""
454   (if_then_else (eq_attr "prefix_0f" "1")
455     (if_then_else (eq_attr "prefix_vex_w" "1")
456       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
457       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
458     (if_then_else (eq_attr "prefix_vex_w" "1")
459       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
460       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
461
462 ;; Set when modrm byte is used.
463 (define_attr "modrm" ""
464   (cond [(eq_attr "type" "str,leave")
465            (const_int 0)
466          (eq_attr "unit" "i387")
467            (const_int 0)
468          (and (eq_attr "type" "incdec")
469               (ior (match_operand:SI 1 "register_operand" "")
470                    (match_operand:HI 1 "register_operand" "")))
471            (const_int 0)
472          (and (eq_attr "type" "push")
473               (not (match_operand 1 "memory_operand" "")))
474            (const_int 0)
475          (and (eq_attr "type" "pop")
476               (not (match_operand 0 "memory_operand" "")))
477            (const_int 0)
478          (and (eq_attr "type" "imov")
479               (ior (and (match_operand 0 "register_operand" "")
480                         (match_operand 1 "immediate_operand" ""))
481                    (ior (and (match_operand 0 "ax_reg_operand" "")
482                              (match_operand 1 "memory_displacement_only_operand" ""))
483                         (and (match_operand 0 "memory_displacement_only_operand" "")
484                              (match_operand 1 "ax_reg_operand" "")))))
485            (const_int 0)
486          (and (eq_attr "type" "call")
487               (match_operand 0 "constant_call_address_operand" ""))
488              (const_int 0)
489          (and (eq_attr "type" "callv")
490               (match_operand 1 "constant_call_address_operand" ""))
491              (const_int 0)
492          ]
493          (const_int 1)))
494
495 ;; The (bounding maximum) length of an instruction in bytes.
496 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
497 ;; Later we may want to split them and compute proper length as for
498 ;; other insns.
499 (define_attr "length" ""
500   (cond [(eq_attr "type" "other,multi,fistp,frndint")
501            (const_int 16)
502          (eq_attr "type" "fcmp")
503            (const_int 4)
504          (eq_attr "unit" "i387")
505            (plus (const_int 2)
506                  (plus (attr "prefix_data16")
507                        (attr "length_address")))
508          (ior (eq_attr "prefix" "vex")
509               (and (eq_attr "prefix" "maybe_vex")
510                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
511            (plus (attr "length_vex")
512                  (plus (attr "prefix_vex_imm8")
513                        (plus (attr "modrm")
514                              (attr "length_address"))))]
515          (plus (plus (attr "modrm")
516                      (plus (attr "prefix_0f")
517                            (plus (attr "prefix_rex")
518                                  (plus (attr "prefix_extra")
519                                        (const_int 1)))))
520                (plus (attr "prefix_rep")
521                      (plus (attr "prefix_data16")
522                            (plus (attr "length_immediate")
523                                  (attr "length_address")))))))
524
525 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
526 ;; `store' if there is a simple memory reference therein, or `unknown'
527 ;; if the instruction is complex.
528
529 (define_attr "memory" "none,load,store,both,unknown"
530   (cond [(eq_attr "type" "other,multi,str")
531            (const_string "unknown")
532          (eq_attr "type" "lea,fcmov,fpspc")
533            (const_string "none")
534          (eq_attr "type" "fistp,leave")
535            (const_string "both")
536          (eq_attr "type" "frndint")
537            (const_string "load")
538          (eq_attr "type" "push")
539            (if_then_else (match_operand 1 "memory_operand" "")
540              (const_string "both")
541              (const_string "store"))
542          (eq_attr "type" "pop")
543            (if_then_else (match_operand 0 "memory_operand" "")
544              (const_string "both")
545              (const_string "load"))
546          (eq_attr "type" "setcc")
547            (if_then_else (match_operand 0 "memory_operand" "")
548              (const_string "store")
549              (const_string "none"))
550          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
551            (if_then_else (ior (match_operand 0 "memory_operand" "")
552                               (match_operand 1 "memory_operand" ""))
553              (const_string "load")
554              (const_string "none"))
555          (eq_attr "type" "ibr")
556            (if_then_else (match_operand 0 "memory_operand" "")
557              (const_string "load")
558              (const_string "none"))
559          (eq_attr "type" "call")
560            (if_then_else (match_operand 0 "constant_call_address_operand" "")
561              (const_string "none")
562              (const_string "load"))
563          (eq_attr "type" "callv")
564            (if_then_else (match_operand 1 "constant_call_address_operand" "")
565              (const_string "none")
566              (const_string "load"))
567          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
568               (match_operand 1 "memory_operand" ""))
569            (const_string "both")
570          (and (match_operand 0 "memory_operand" "")
571               (match_operand 1 "memory_operand" ""))
572            (const_string "both")
573          (match_operand 0 "memory_operand" "")
574            (const_string "store")
575          (match_operand 1 "memory_operand" "")
576            (const_string "load")
577          (and (eq_attr "type"
578                  "!alu1,negnot,ishift1,
579                    imov,imovx,icmp,test,bitmanip,
580                    fmov,fcmp,fsgn,
581                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
582                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
583               (match_operand 2 "memory_operand" ""))
584            (const_string "load")
585          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
586               (match_operand 3 "memory_operand" ""))
587            (const_string "load")
588         ]
589         (const_string "none")))
590
591 ;; Indicates if an instruction has both an immediate and a displacement.
592
593 (define_attr "imm_disp" "false,true,unknown"
594   (cond [(eq_attr "type" "other,multi")
595            (const_string "unknown")
596          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
597               (and (match_operand 0 "memory_displacement_operand" "")
598                    (match_operand 1 "immediate_operand" "")))
599            (const_string "true")
600          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
601               (and (match_operand 0 "memory_displacement_operand" "")
602                    (match_operand 2 "immediate_operand" "")))
603            (const_string "true")
604         ]
605         (const_string "false")))
606
607 ;; Indicates if an FP operation has an integer source.
608
609 (define_attr "fp_int_src" "false,true"
610   (const_string "false"))
611
612 ;; Defines rounding mode of an FP operation.
613
614 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
615   (const_string "any"))
616
617 ;; Describe a user's asm statement.
618 (define_asm_attributes
619   [(set_attr "length" "128")
620    (set_attr "type" "multi")])
621
622 ;; All integer comparison codes.
623 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
624
625 ;; All floating-point comparison codes.
626 (define_code_iterator fp_cond [unordered ordered
627                                uneq unge ungt unle unlt ltgt ])
628
629 (define_code_iterator plusminus [plus minus])
630
631 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
632
633 ;; Base name for define_insn
634 (define_code_attr plusminus_insn
635   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
636    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
637
638 ;; Base name for insn mnemonic.
639 (define_code_attr plusminus_mnemonic
640   [(plus "add") (ss_plus "adds") (us_plus "addus")
641    (minus "sub") (ss_minus "subs") (us_minus "subus")])
642
643 ;; Mark commutative operators as such in constraints.
644 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
645                         (minus "") (ss_minus "") (us_minus "")])
646
647 ;; Mapping of signed max and min
648 (define_code_iterator smaxmin [smax smin])
649
650 ;; Mapping of unsigned max and min
651 (define_code_iterator umaxmin [umax umin])
652
653 ;; Mapping of signed/unsigned max and min
654 (define_code_iterator maxmin [smax smin umax umin])
655
656 ;; Base name for integer and FP insn mnemonic
657 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
658                                  (umax "maxu") (umin "minu")])
659 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
660
661 ;; Mapping of parallel logic operators
662 (define_code_iterator plogic [and ior xor])
663
664 ;; Base name for insn mnemonic.
665 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
666
667 ;; Mapping of abs neg operators
668 (define_code_iterator absneg [abs neg])
669
670 ;; Base name for x87 insn mnemonic.
671 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
672
673 ;; All single word integer modes.
674 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
675
676 ;; Single word integer modes without QImode.
677 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
678
679 ;; Instruction suffix for integer modes.
680 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
681
682 ;; Register class for integer modes.
683 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
684
685 ;; Immediate operand constraint for integer modes.
686 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
687
688 ;; General operand predicate for integer modes.
689 (define_mode_attr general_operand
690         [(QI "general_operand")
691          (HI "general_operand")
692          (SI "general_operand")
693          (DI "x86_64_general_operand")])
694
695 ;; SSE and x87 SFmode and DFmode floating point modes
696 (define_mode_iterator MODEF [SF DF])
697
698 ;; All x87 floating point modes
699 (define_mode_iterator X87MODEF [SF DF XF])
700
701 ;; All integer modes handled by x87 fisttp operator.
702 (define_mode_iterator X87MODEI [HI SI DI])
703
704 ;; All integer modes handled by integer x87 operators.
705 (define_mode_iterator X87MODEI12 [HI SI])
706
707 ;; All integer modes handled by SSE cvtts?2si* operators.
708 (define_mode_iterator SSEMODEI24 [SI DI])
709
710 ;; SSE asm suffix for floating point modes
711 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
712
713 ;; SSE vector mode corresponding to a scalar mode
714 (define_mode_attr ssevecmode
715   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
716
717 ;; Instruction suffix for REX 64bit operators.
718 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
719
720 ;; This mode iterator allows :P to be used for patterns that operate on
721 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
722 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
723
724 \f
725 ;; Scheduling descriptions
726
727 (include "pentium.md")
728 (include "ppro.md")
729 (include "k6.md")
730 (include "athlon.md")
731 (include "geode.md")
732
733 \f
734 ;; Operand and operator predicates and constraints
735
736 (include "predicates.md")
737 (include "constraints.md")
738
739 \f
740 ;; Compare instructions.
741
742 ;; All compare insns have expanders that save the operands away without
743 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
744 ;; after the cmp) will actually emit the cmpM.
745
746 (define_expand "cmpti"
747   [(set (reg:CC FLAGS_REG)
748         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
749                     (match_operand:TI 1 "x86_64_general_operand" "")))]
750   "TARGET_64BIT"
751 {
752   if (MEM_P (operands[0]) && MEM_P (operands[1]))
753     operands[0] = force_reg (TImode, operands[0]);
754   ix86_compare_op0 = operands[0];
755   ix86_compare_op1 = operands[1];
756   DONE;
757 })
758
759 (define_expand "cmpdi"
760   [(set (reg:CC FLAGS_REG)
761         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
762                     (match_operand:DI 1 "x86_64_general_operand" "")))]
763   ""
764 {
765   if (MEM_P (operands[0]) && MEM_P (operands[1]))
766     operands[0] = force_reg (DImode, operands[0]);
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpsi"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
775                     (match_operand:SI 1 "general_operand" "")))]
776   ""
777 {
778   if (MEM_P (operands[0]) && MEM_P (operands[1]))
779     operands[0] = force_reg (SImode, operands[0]);
780   ix86_compare_op0 = operands[0];
781   ix86_compare_op1 = operands[1];
782   DONE;
783 })
784
785 (define_expand "cmphi"
786   [(set (reg:CC FLAGS_REG)
787         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
788                     (match_operand:HI 1 "general_operand" "")))]
789   ""
790 {
791   if (MEM_P (operands[0]) && MEM_P (operands[1]))
792     operands[0] = force_reg (HImode, operands[0]);
793   ix86_compare_op0 = operands[0];
794   ix86_compare_op1 = operands[1];
795   DONE;
796 })
797
798 (define_expand "cmpqi"
799   [(set (reg:CC FLAGS_REG)
800         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
801                     (match_operand:QI 1 "general_operand" "")))]
802   "TARGET_QIMODE_MATH"
803 {
804   if (MEM_P (operands[0]) && MEM_P (operands[1]))
805     operands[0] = force_reg (QImode, operands[0]);
806   ix86_compare_op0 = operands[0];
807   ix86_compare_op1 = operands[1];
808   DONE;
809 })
810
811 (define_insn "cmpdi_ccno_1_rex64"
812   [(set (reg FLAGS_REG)
813         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
814                  (match_operand:DI 1 "const0_operand" "")))]
815   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
816   "@
817    test{q}\t%0, %0
818    cmp{q}\t{%1, %0|%0, %1}"
819   [(set_attr "type" "test,icmp")
820    (set_attr "length_immediate" "0,1")
821    (set_attr "mode" "DI")])
822
823 (define_insn "*cmpdi_minus_1_rex64"
824   [(set (reg FLAGS_REG)
825         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
826                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
827                  (const_int 0)))]
828   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
829   "cmp{q}\t{%1, %0|%0, %1}"
830   [(set_attr "type" "icmp")
831    (set_attr "mode" "DI")])
832
833 (define_expand "cmpdi_1_rex64"
834   [(set (reg:CC FLAGS_REG)
835         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
836                     (match_operand:DI 1 "general_operand" "")))]
837   "TARGET_64BIT"
838   "")
839
840 (define_insn "cmpdi_1_insn_rex64"
841   [(set (reg FLAGS_REG)
842         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
843                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
844   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
845   "cmp{q}\t{%1, %0|%0, %1}"
846   [(set_attr "type" "icmp")
847    (set_attr "mode" "DI")])
848
849
850 (define_insn "*cmpsi_ccno_1"
851   [(set (reg FLAGS_REG)
852         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
853                  (match_operand:SI 1 "const0_operand" "")))]
854   "ix86_match_ccmode (insn, CCNOmode)"
855   "@
856    test{l}\t%0, %0
857    cmp{l}\t{%1, %0|%0, %1}"
858   [(set_attr "type" "test,icmp")
859    (set_attr "length_immediate" "0,1")
860    (set_attr "mode" "SI")])
861
862 (define_insn "*cmpsi_minus_1"
863   [(set (reg FLAGS_REG)
864         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
865                            (match_operand:SI 1 "general_operand" "ri,mr"))
866                  (const_int 0)))]
867   "ix86_match_ccmode (insn, CCGOCmode)"
868   "cmp{l}\t{%1, %0|%0, %1}"
869   [(set_attr "type" "icmp")
870    (set_attr "mode" "SI")])
871
872 (define_expand "cmpsi_1"
873   [(set (reg:CC FLAGS_REG)
874         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
875                     (match_operand:SI 1 "general_operand" "")))]
876   ""
877   "")
878
879 (define_insn "*cmpsi_1_insn"
880   [(set (reg FLAGS_REG)
881         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
882                  (match_operand:SI 1 "general_operand" "ri,mr")))]
883   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
884     && ix86_match_ccmode (insn, CCmode)"
885   "cmp{l}\t{%1, %0|%0, %1}"
886   [(set_attr "type" "icmp")
887    (set_attr "mode" "SI")])
888
889 (define_insn "*cmphi_ccno_1"
890   [(set (reg FLAGS_REG)
891         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
892                  (match_operand:HI 1 "const0_operand" "")))]
893   "ix86_match_ccmode (insn, CCNOmode)"
894   "@
895    test{w}\t%0, %0
896    cmp{w}\t{%1, %0|%0, %1}"
897   [(set_attr "type" "test,icmp")
898    (set_attr "length_immediate" "0,1")
899    (set_attr "mode" "HI")])
900
901 (define_insn "*cmphi_minus_1"
902   [(set (reg FLAGS_REG)
903         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
904                            (match_operand:HI 1 "general_operand" "rn,mr"))
905                  (const_int 0)))]
906   "ix86_match_ccmode (insn, CCGOCmode)"
907   "cmp{w}\t{%1, %0|%0, %1}"
908   [(set_attr "type" "icmp")
909    (set_attr "mode" "HI")])
910
911 (define_insn "*cmphi_1"
912   [(set (reg FLAGS_REG)
913         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
914                  (match_operand:HI 1 "general_operand" "rn,mr")))]
915   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
916    && ix86_match_ccmode (insn, CCmode)"
917   "cmp{w}\t{%1, %0|%0, %1}"
918   [(set_attr "type" "icmp")
919    (set_attr "mode" "HI")])
920
921 (define_insn "*cmpqi_ccno_1"
922   [(set (reg FLAGS_REG)
923         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
924                  (match_operand:QI 1 "const0_operand" "")))]
925   "ix86_match_ccmode (insn, CCNOmode)"
926   "@
927    test{b}\t%0, %0
928    cmp{b}\t{$0, %0|%0, 0}"
929   [(set_attr "type" "test,icmp")
930    (set_attr "length_immediate" "0,1")
931    (set_attr "mode" "QI")])
932
933 (define_insn "*cmpqi_1"
934   [(set (reg FLAGS_REG)
935         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
936                  (match_operand:QI 1 "general_operand" "qn,mq")))]
937   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
938     && ix86_match_ccmode (insn, CCmode)"
939   "cmp{b}\t{%1, %0|%0, %1}"
940   [(set_attr "type" "icmp")
941    (set_attr "mode" "QI")])
942
943 (define_insn "*cmpqi_minus_1"
944   [(set (reg FLAGS_REG)
945         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
946                            (match_operand:QI 1 "general_operand" "qn,mq"))
947                  (const_int 0)))]
948   "ix86_match_ccmode (insn, CCGOCmode)"
949   "cmp{b}\t{%1, %0|%0, %1}"
950   [(set_attr "type" "icmp")
951    (set_attr "mode" "QI")])
952
953 (define_insn "*cmpqi_ext_1"
954   [(set (reg FLAGS_REG)
955         (compare
956           (match_operand:QI 0 "general_operand" "Qm")
957           (subreg:QI
958             (zero_extract:SI
959               (match_operand 1 "ext_register_operand" "Q")
960               (const_int 8)
961               (const_int 8)) 0)))]
962   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
963   "cmp{b}\t{%h1, %0|%0, %h1}"
964   [(set_attr "type" "icmp")
965    (set_attr "mode" "QI")])
966
967 (define_insn "*cmpqi_ext_1_rex64"
968   [(set (reg FLAGS_REG)
969         (compare
970           (match_operand:QI 0 "register_operand" "Q")
971           (subreg:QI
972             (zero_extract:SI
973               (match_operand 1 "ext_register_operand" "Q")
974               (const_int 8)
975               (const_int 8)) 0)))]
976   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
977   "cmp{b}\t{%h1, %0|%0, %h1}"
978   [(set_attr "type" "icmp")
979    (set_attr "mode" "QI")])
980
981 (define_insn "*cmpqi_ext_2"
982   [(set (reg FLAGS_REG)
983         (compare
984           (subreg:QI
985             (zero_extract:SI
986               (match_operand 0 "ext_register_operand" "Q")
987               (const_int 8)
988               (const_int 8)) 0)
989           (match_operand:QI 1 "const0_operand" "")))]
990   "ix86_match_ccmode (insn, CCNOmode)"
991   "test{b}\t%h0, %h0"
992   [(set_attr "type" "test")
993    (set_attr "length_immediate" "0")
994    (set_attr "mode" "QI")])
995
996 (define_expand "cmpqi_ext_3"
997   [(set (reg:CC FLAGS_REG)
998         (compare:CC
999           (subreg:QI
1000             (zero_extract:SI
1001               (match_operand 0 "ext_register_operand" "")
1002               (const_int 8)
1003               (const_int 8)) 0)
1004           (match_operand:QI 1 "general_operand" "")))]
1005   ""
1006   "")
1007
1008 (define_insn "cmpqi_ext_3_insn"
1009   [(set (reg FLAGS_REG)
1010         (compare
1011           (subreg:QI
1012             (zero_extract:SI
1013               (match_operand 0 "ext_register_operand" "Q")
1014               (const_int 8)
1015               (const_int 8)) 0)
1016           (match_operand:QI 1 "general_operand" "Qmn")))]
1017   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1018   "cmp{b}\t{%1, %h0|%h0, %1}"
1019   [(set_attr "type" "icmp")
1020    (set_attr "mode" "QI")])
1021
1022 (define_insn "cmpqi_ext_3_insn_rex64"
1023   [(set (reg FLAGS_REG)
1024         (compare
1025           (subreg:QI
1026             (zero_extract:SI
1027               (match_operand 0 "ext_register_operand" "Q")
1028               (const_int 8)
1029               (const_int 8)) 0)
1030           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1031   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1032   "cmp{b}\t{%1, %h0|%h0, %1}"
1033   [(set_attr "type" "icmp")
1034    (set_attr "mode" "QI")])
1035
1036 (define_insn "*cmpqi_ext_4"
1037   [(set (reg FLAGS_REG)
1038         (compare
1039           (subreg:QI
1040             (zero_extract:SI
1041               (match_operand 0 "ext_register_operand" "Q")
1042               (const_int 8)
1043               (const_int 8)) 0)
1044           (subreg:QI
1045             (zero_extract:SI
1046               (match_operand 1 "ext_register_operand" "Q")
1047               (const_int 8)
1048               (const_int 8)) 0)))]
1049   "ix86_match_ccmode (insn, CCmode)"
1050   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1051   [(set_attr "type" "icmp")
1052    (set_attr "mode" "QI")])
1053
1054 ;; These implement float point compares.
1055 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1056 ;; which would allow mix and match FP modes on the compares.  Which is what
1057 ;; the old patterns did, but with many more of them.
1058
1059 (define_expand "cmpxf"
1060   [(set (reg:CC FLAGS_REG)
1061         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1062                     (match_operand:XF 1 "nonmemory_operand" "")))]
1063   "TARGET_80387"
1064 {
1065   ix86_compare_op0 = operands[0];
1066   ix86_compare_op1 = operands[1];
1067   DONE;
1068 })
1069
1070 (define_expand "cmp<mode>"
1071   [(set (reg:CC FLAGS_REG)
1072         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1073                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1074   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1075 {
1076   ix86_compare_op0 = operands[0];
1077   ix86_compare_op1 = operands[1];
1078   DONE;
1079 })
1080
1081 ;; FP compares, step 1:
1082 ;; Set the FP condition codes.
1083 ;;
1084 ;; CCFPmode     compare with exceptions
1085 ;; CCFPUmode    compare with no exceptions
1086
1087 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1088 ;; used to manage the reg stack popping would not be preserved.
1089
1090 (define_insn "*cmpfp_0"
1091   [(set (match_operand:HI 0 "register_operand" "=a")
1092         (unspec:HI
1093           [(compare:CCFP
1094              (match_operand 1 "register_operand" "f")
1095              (match_operand 2 "const0_operand" ""))]
1096         UNSPEC_FNSTSW))]
1097   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1098    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1099   "* return output_fp_compare (insn, operands, 0, 0);"
1100   [(set_attr "type" "multi")
1101    (set_attr "unit" "i387")
1102    (set (attr "mode")
1103      (cond [(match_operand:SF 1 "" "")
1104               (const_string "SF")
1105             (match_operand:DF 1 "" "")
1106               (const_string "DF")
1107            ]
1108            (const_string "XF")))])
1109
1110 (define_insn_and_split "*cmpfp_0_cc"
1111   [(set (reg:CCFP FLAGS_REG)
1112         (compare:CCFP
1113           (match_operand 1 "register_operand" "f")
1114           (match_operand 2 "const0_operand" "")))
1115    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1116   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1117    && TARGET_SAHF && !TARGET_CMOVE
1118    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1119   "#"
1120   "&& reload_completed"
1121   [(set (match_dup 0)
1122         (unspec:HI
1123           [(compare:CCFP (match_dup 1)(match_dup 2))]
1124         UNSPEC_FNSTSW))
1125    (set (reg:CC FLAGS_REG)
1126         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1127   ""
1128   [(set_attr "type" "multi")
1129    (set_attr "unit" "i387")
1130    (set (attr "mode")
1131      (cond [(match_operand:SF 1 "" "")
1132               (const_string "SF")
1133             (match_operand:DF 1 "" "")
1134               (const_string "DF")
1135            ]
1136            (const_string "XF")))])
1137
1138 (define_insn "*cmpfp_xf"
1139   [(set (match_operand:HI 0 "register_operand" "=a")
1140         (unspec:HI
1141           [(compare:CCFP
1142              (match_operand:XF 1 "register_operand" "f")
1143              (match_operand:XF 2 "register_operand" "f"))]
1144           UNSPEC_FNSTSW))]
1145   "TARGET_80387"
1146   "* return output_fp_compare (insn, operands, 0, 0);"
1147   [(set_attr "type" "multi")
1148    (set_attr "unit" "i387")
1149    (set_attr "mode" "XF")])
1150
1151 (define_insn_and_split "*cmpfp_xf_cc"
1152   [(set (reg:CCFP FLAGS_REG)
1153         (compare:CCFP
1154           (match_operand:XF 1 "register_operand" "f")
1155           (match_operand:XF 2 "register_operand" "f")))
1156    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1157   "TARGET_80387
1158    && TARGET_SAHF && !TARGET_CMOVE"
1159   "#"
1160   "&& reload_completed"
1161   [(set (match_dup 0)
1162         (unspec:HI
1163           [(compare:CCFP (match_dup 1)(match_dup 2))]
1164         UNSPEC_FNSTSW))
1165    (set (reg:CC FLAGS_REG)
1166         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1167   ""
1168   [(set_attr "type" "multi")
1169    (set_attr "unit" "i387")
1170    (set_attr "mode" "XF")])
1171
1172 (define_insn "*cmpfp_<mode>"
1173   [(set (match_operand:HI 0 "register_operand" "=a")
1174         (unspec:HI
1175           [(compare:CCFP
1176              (match_operand:MODEF 1 "register_operand" "f")
1177              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1178           UNSPEC_FNSTSW))]
1179   "TARGET_80387"
1180   "* return output_fp_compare (insn, operands, 0, 0);"
1181   [(set_attr "type" "multi")
1182    (set_attr "unit" "i387")
1183    (set_attr "mode" "<MODE>")])
1184
1185 (define_insn_and_split "*cmpfp_<mode>_cc"
1186   [(set (reg:CCFP FLAGS_REG)
1187         (compare:CCFP
1188           (match_operand:MODEF 1 "register_operand" "f")
1189           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1190    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1191   "TARGET_80387
1192    && TARGET_SAHF && !TARGET_CMOVE"
1193   "#"
1194   "&& reload_completed"
1195   [(set (match_dup 0)
1196         (unspec:HI
1197           [(compare:CCFP (match_dup 1)(match_dup 2))]
1198         UNSPEC_FNSTSW))
1199    (set (reg:CC FLAGS_REG)
1200         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1201   ""
1202   [(set_attr "type" "multi")
1203    (set_attr "unit" "i387")
1204    (set_attr "mode" "<MODE>")])
1205
1206 (define_insn "*cmpfp_u"
1207   [(set (match_operand:HI 0 "register_operand" "=a")
1208         (unspec:HI
1209           [(compare:CCFPU
1210              (match_operand 1 "register_operand" "f")
1211              (match_operand 2 "register_operand" "f"))]
1212           UNSPEC_FNSTSW))]
1213   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1214    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1215   "* return output_fp_compare (insn, operands, 0, 1);"
1216   [(set_attr "type" "multi")
1217    (set_attr "unit" "i387")
1218    (set (attr "mode")
1219      (cond [(match_operand:SF 1 "" "")
1220               (const_string "SF")
1221             (match_operand:DF 1 "" "")
1222               (const_string "DF")
1223            ]
1224            (const_string "XF")))])
1225
1226 (define_insn_and_split "*cmpfp_u_cc"
1227   [(set (reg:CCFPU FLAGS_REG)
1228         (compare:CCFPU
1229           (match_operand 1 "register_operand" "f")
1230           (match_operand 2 "register_operand" "f")))
1231    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1232   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1233    && TARGET_SAHF && !TARGET_CMOVE
1234    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1235   "#"
1236   "&& reload_completed"
1237   [(set (match_dup 0)
1238         (unspec:HI
1239           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1240         UNSPEC_FNSTSW))
1241    (set (reg:CC FLAGS_REG)
1242         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1243   ""
1244   [(set_attr "type" "multi")
1245    (set_attr "unit" "i387")
1246    (set (attr "mode")
1247      (cond [(match_operand:SF 1 "" "")
1248               (const_string "SF")
1249             (match_operand:DF 1 "" "")
1250               (const_string "DF")
1251            ]
1252            (const_string "XF")))])
1253
1254 (define_insn "*cmpfp_<mode>"
1255   [(set (match_operand:HI 0 "register_operand" "=a")
1256         (unspec:HI
1257           [(compare:CCFP
1258              (match_operand 1 "register_operand" "f")
1259              (match_operator 3 "float_operator"
1260                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1261           UNSPEC_FNSTSW))]
1262   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1263    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1264    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1265   "* return output_fp_compare (insn, operands, 0, 0);"
1266   [(set_attr "type" "multi")
1267    (set_attr "unit" "i387")
1268    (set_attr "fp_int_src" "true")
1269    (set_attr "mode" "<MODE>")])
1270
1271 (define_insn_and_split "*cmpfp_<mode>_cc"
1272   [(set (reg:CCFP FLAGS_REG)
1273         (compare:CCFP
1274           (match_operand 1 "register_operand" "f")
1275           (match_operator 3 "float_operator"
1276             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1277    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279    && TARGET_SAHF && !TARGET_CMOVE
1280    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1281    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1282   "#"
1283   "&& reload_completed"
1284   [(set (match_dup 0)
1285         (unspec:HI
1286           [(compare:CCFP
1287              (match_dup 1)
1288              (match_op_dup 3 [(match_dup 2)]))]
1289         UNSPEC_FNSTSW))
1290    (set (reg:CC FLAGS_REG)
1291         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1292   ""
1293   [(set_attr "type" "multi")
1294    (set_attr "unit" "i387")
1295    (set_attr "fp_int_src" "true")
1296    (set_attr "mode" "<MODE>")])
1297
1298 ;; FP compares, step 2
1299 ;; Move the fpsw to ax.
1300
1301 (define_insn "x86_fnstsw_1"
1302   [(set (match_operand:HI 0 "register_operand" "=a")
1303         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1304   "TARGET_80387"
1305   "fnstsw\t%0"
1306   [(set_attr "length" "2")
1307    (set_attr "mode" "SI")
1308    (set_attr "unit" "i387")])
1309
1310 ;; FP compares, step 3
1311 ;; Get ax into flags, general case.
1312
1313 (define_insn "x86_sahf_1"
1314   [(set (reg:CC FLAGS_REG)
1315         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1316                    UNSPEC_SAHF))]
1317   "TARGET_SAHF"
1318 {
1319 #ifndef HAVE_AS_IX86_SAHF
1320   if (TARGET_64BIT)
1321     return ".byte\t0x9e";
1322   else
1323 #endif
1324   return "sahf";
1325 }
1326   [(set_attr "length" "1")
1327    (set_attr "athlon_decode" "vector")
1328    (set_attr "amdfam10_decode" "direct")
1329    (set_attr "mode" "SI")])
1330
1331 ;; Pentium Pro can do steps 1 through 3 in one go.
1332 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1333 (define_insn "*cmpfp_i_mixed"
1334   [(set (reg:CCFP FLAGS_REG)
1335         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1336                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1337   "TARGET_MIX_SSE_I387
1338    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1339    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1340   "* return output_fp_compare (insn, operands, 1, 0);"
1341   [(set_attr "type" "fcmp,ssecomi")
1342    (set_attr "prefix" "orig,maybe_vex")
1343    (set (attr "mode")
1344      (if_then_else (match_operand:SF 1 "" "")
1345         (const_string "SF")
1346         (const_string "DF")))
1347    (set_attr "athlon_decode" "vector")
1348    (set_attr "amdfam10_decode" "direct")])
1349
1350 (define_insn "*cmpfp_i_sse"
1351   [(set (reg:CCFP FLAGS_REG)
1352         (compare:CCFP (match_operand 0 "register_operand" "x")
1353                       (match_operand 1 "nonimmediate_operand" "xm")))]
1354   "TARGET_SSE_MATH
1355    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1356    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1357   "* return output_fp_compare (insn, operands, 1, 0);"
1358   [(set_attr "type" "ssecomi")
1359    (set_attr "prefix" "maybe_vex")
1360    (set (attr "mode")
1361      (if_then_else (match_operand:SF 1 "" "")
1362         (const_string "SF")
1363         (const_string "DF")))
1364    (set_attr "athlon_decode" "vector")
1365    (set_attr "amdfam10_decode" "direct")])
1366
1367 (define_insn "*cmpfp_i_i387"
1368   [(set (reg:CCFP FLAGS_REG)
1369         (compare:CCFP (match_operand 0 "register_operand" "f")
1370                       (match_operand 1 "register_operand" "f")))]
1371   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1372    && TARGET_CMOVE
1373    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1374    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1375   "* return output_fp_compare (insn, operands, 1, 0);"
1376   [(set_attr "type" "fcmp")
1377    (set (attr "mode")
1378      (cond [(match_operand:SF 1 "" "")
1379               (const_string "SF")
1380             (match_operand:DF 1 "" "")
1381               (const_string "DF")
1382            ]
1383            (const_string "XF")))
1384    (set_attr "athlon_decode" "vector")
1385    (set_attr "amdfam10_decode" "direct")])
1386
1387 (define_insn "*cmpfp_iu_mixed"
1388   [(set (reg:CCFPU FLAGS_REG)
1389         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1390                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1391   "TARGET_MIX_SSE_I387
1392    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1393    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1394   "* return output_fp_compare (insn, operands, 1, 1);"
1395   [(set_attr "type" "fcmp,ssecomi")
1396    (set_attr "prefix" "orig,maybe_vex")
1397    (set (attr "mode")
1398      (if_then_else (match_operand:SF 1 "" "")
1399         (const_string "SF")
1400         (const_string "DF")))
1401    (set_attr "athlon_decode" "vector")
1402    (set_attr "amdfam10_decode" "direct")])
1403
1404 (define_insn "*cmpfp_iu_sse"
1405   [(set (reg:CCFPU FLAGS_REG)
1406         (compare:CCFPU (match_operand 0 "register_operand" "x")
1407                        (match_operand 1 "nonimmediate_operand" "xm")))]
1408   "TARGET_SSE_MATH
1409    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1410    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1411   "* return output_fp_compare (insn, operands, 1, 1);"
1412   [(set_attr "type" "ssecomi")
1413    (set_attr "prefix" "maybe_vex")
1414    (set (attr "mode")
1415      (if_then_else (match_operand:SF 1 "" "")
1416         (const_string "SF")
1417         (const_string "DF")))
1418    (set_attr "athlon_decode" "vector")
1419    (set_attr "amdfam10_decode" "direct")])
1420
1421 (define_insn "*cmpfp_iu_387"
1422   [(set (reg:CCFPU FLAGS_REG)
1423         (compare:CCFPU (match_operand 0 "register_operand" "f")
1424                        (match_operand 1 "register_operand" "f")))]
1425   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1426    && TARGET_CMOVE
1427    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1428    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1429   "* return output_fp_compare (insn, operands, 1, 1);"
1430   [(set_attr "type" "fcmp")
1431    (set (attr "mode")
1432      (cond [(match_operand:SF 1 "" "")
1433               (const_string "SF")
1434             (match_operand:DF 1 "" "")
1435               (const_string "DF")
1436            ]
1437            (const_string "XF")))
1438    (set_attr "athlon_decode" "vector")
1439    (set_attr "amdfam10_decode" "direct")])
1440 \f
1441 ;; Move instructions.
1442
1443 ;; General case of fullword move.
1444
1445 (define_expand "movsi"
1446   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1447         (match_operand:SI 1 "general_operand" ""))]
1448   ""
1449   "ix86_expand_move (SImode, operands); DONE;")
1450
1451 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1452 ;; general_operand.
1453 ;;
1454 ;; %%% We don't use a post-inc memory reference because x86 is not a
1455 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1456 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1457 ;; targets without our curiosities, and it is just as easy to represent
1458 ;; this differently.
1459
1460 (define_insn "*pushsi2"
1461   [(set (match_operand:SI 0 "push_operand" "=<")
1462         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1463   "!TARGET_64BIT"
1464   "push{l}\t%1"
1465   [(set_attr "type" "push")
1466    (set_attr "mode" "SI")])
1467
1468 ;; For 64BIT abi we always round up to 8 bytes.
1469 (define_insn "*pushsi2_rex64"
1470   [(set (match_operand:SI 0 "push_operand" "=X")
1471         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1472   "TARGET_64BIT"
1473   "push{q}\t%q1"
1474   [(set_attr "type" "push")
1475    (set_attr "mode" "SI")])
1476
1477 (define_insn "*pushsi2_prologue"
1478   [(set (match_operand:SI 0 "push_operand" "=<")
1479         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1480    (clobber (mem:BLK (scratch)))]
1481   "!TARGET_64BIT"
1482   "push{l}\t%1"
1483   [(set_attr "type" "push")
1484    (set_attr "mode" "SI")])
1485
1486 (define_insn "*popsi1_epilogue"
1487   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1488         (mem:SI (reg:SI SP_REG)))
1489    (set (reg:SI SP_REG)
1490         (plus:SI (reg:SI SP_REG) (const_int 4)))
1491    (clobber (mem:BLK (scratch)))]
1492   "!TARGET_64BIT"
1493   "pop{l}\t%0"
1494   [(set_attr "type" "pop")
1495    (set_attr "mode" "SI")])
1496
1497 (define_insn "popsi1"
1498   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1499         (mem:SI (reg:SI SP_REG)))
1500    (set (reg:SI SP_REG)
1501         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1502   "!TARGET_64BIT"
1503   "pop{l}\t%0"
1504   [(set_attr "type" "pop")
1505    (set_attr "mode" "SI")])
1506
1507 (define_insn "*movsi_xor"
1508   [(set (match_operand:SI 0 "register_operand" "=r")
1509         (match_operand:SI 1 "const0_operand" ""))
1510    (clobber (reg:CC FLAGS_REG))]
1511   "reload_completed"
1512   "xor{l}\t%0, %0"
1513   [(set_attr "type" "alu1")
1514    (set_attr "mode" "SI")
1515    (set_attr "length_immediate" "0")])
1516
1517 (define_insn "*movsi_or"
1518   [(set (match_operand:SI 0 "register_operand" "=r")
1519         (match_operand:SI 1 "immediate_operand" "i"))
1520    (clobber (reg:CC FLAGS_REG))]
1521   "reload_completed
1522    && operands[1] == constm1_rtx"
1523 {
1524   operands[1] = constm1_rtx;
1525   return "or{l}\t{%1, %0|%0, %1}";
1526 }
1527   [(set_attr "type" "alu1")
1528    (set_attr "mode" "SI")
1529    (set_attr "length_immediate" "1")])
1530
1531 (define_insn "*movsi_1"
1532   [(set (match_operand:SI 0 "nonimmediate_operand"
1533                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1534         (match_operand:SI 1 "general_operand"
1535                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1536   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1537 {
1538   switch (get_attr_type (insn))
1539     {
1540     case TYPE_SSELOG1:
1541       if (get_attr_mode (insn) == MODE_TI)
1542         return "%vpxor\t%0, %d0";
1543       return "%vxorps\t%0, %d0";
1544
1545     case TYPE_SSEMOV:
1546       switch (get_attr_mode (insn))
1547         {
1548         case MODE_TI:
1549           return "%vmovdqa\t{%1, %0|%0, %1}";
1550         case MODE_V4SF:
1551           return "%vmovaps\t{%1, %0|%0, %1}";
1552         case MODE_SI:
1553           return "%vmovd\t{%1, %0|%0, %1}";
1554         case MODE_SF:
1555           return "%vmovss\t{%1, %0|%0, %1}";
1556         default:
1557           gcc_unreachable ();
1558         }
1559
1560     case TYPE_MMX:
1561       return "pxor\t%0, %0";
1562
1563     case TYPE_MMXMOV:
1564       if (get_attr_mode (insn) == MODE_DI)
1565         return "movq\t{%1, %0|%0, %1}";
1566       return "movd\t{%1, %0|%0, %1}";
1567
1568     case TYPE_LEA:
1569       return "lea{l}\t{%a1, %0|%0, %a1}";
1570
1571     default:
1572       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1573       return "mov{l}\t{%1, %0|%0, %1}";
1574     }
1575 }
1576   [(set (attr "type")
1577      (cond [(eq_attr "alternative" "2")
1578               (const_string "mmx")
1579             (eq_attr "alternative" "3,4,5")
1580               (const_string "mmxmov")
1581             (eq_attr "alternative" "6")
1582               (const_string "sselog1")
1583             (eq_attr "alternative" "7,8,9,10,11")
1584               (const_string "ssemov")
1585             (match_operand:DI 1 "pic_32bit_operand" "")
1586               (const_string "lea")
1587            ]
1588            (const_string "imov")))
1589    (set (attr "prefix")
1590      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1591        (const_string "orig")
1592        (const_string "maybe_vex")))
1593    (set (attr "mode")
1594      (cond [(eq_attr "alternative" "2,3")
1595               (const_string "DI")
1596             (eq_attr "alternative" "6,7")
1597               (if_then_else
1598                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1599                 (const_string "V4SF")
1600                 (const_string "TI"))
1601             (and (eq_attr "alternative" "8,9,10,11")
1602                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1603               (const_string "SF")
1604            ]
1605            (const_string "SI")))])
1606
1607 ;; Stores and loads of ax to arbitrary constant address.
1608 ;; We fake an second form of instruction to force reload to load address
1609 ;; into register when rax is not available
1610 (define_insn "*movabssi_1_rex64"
1611   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1612         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1613   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1614   "@
1615    movabs{l}\t{%1, %P0|%P0, %1}
1616    mov{l}\t{%1, %a0|%a0, %1}"
1617   [(set_attr "type" "imov")
1618    (set_attr "modrm" "0,*")
1619    (set_attr "length_address" "8,0")
1620    (set_attr "length_immediate" "0,*")
1621    (set_attr "memory" "store")
1622    (set_attr "mode" "SI")])
1623
1624 (define_insn "*movabssi_2_rex64"
1625   [(set (match_operand:SI 0 "register_operand" "=a,r")
1626         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1627   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1628   "@
1629    movabs{l}\t{%P1, %0|%0, %P1}
1630    mov{l}\t{%a1, %0|%0, %a1}"
1631   [(set_attr "type" "imov")
1632    (set_attr "modrm" "0,*")
1633    (set_attr "length_address" "8,0")
1634    (set_attr "length_immediate" "0")
1635    (set_attr "memory" "load")
1636    (set_attr "mode" "SI")])
1637
1638 (define_insn "*swapsi"
1639   [(set (match_operand:SI 0 "register_operand" "+r")
1640         (match_operand:SI 1 "register_operand" "+r"))
1641    (set (match_dup 1)
1642         (match_dup 0))]
1643   ""
1644   "xchg{l}\t%1, %0"
1645   [(set_attr "type" "imov")
1646    (set_attr "mode" "SI")
1647    (set_attr "pent_pair" "np")
1648    (set_attr "athlon_decode" "vector")
1649    (set_attr "amdfam10_decode" "double")])
1650
1651 (define_expand "movhi"
1652   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1653         (match_operand:HI 1 "general_operand" ""))]
1654   ""
1655   "ix86_expand_move (HImode, operands); DONE;")
1656
1657 (define_insn "*pushhi2"
1658   [(set (match_operand:HI 0 "push_operand" "=X")
1659         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1660   "!TARGET_64BIT"
1661   "push{l}\t%k1"
1662   [(set_attr "type" "push")
1663    (set_attr "mode" "SI")])
1664
1665 ;; For 64BIT abi we always round up to 8 bytes.
1666 (define_insn "*pushhi2_rex64"
1667   [(set (match_operand:HI 0 "push_operand" "=X")
1668         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1669   "TARGET_64BIT"
1670   "push{q}\t%q1"
1671   [(set_attr "type" "push")
1672    (set_attr "mode" "DI")])
1673
1674 (define_insn "*movhi_1"
1675   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1676         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1677   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1678 {
1679   switch (get_attr_type (insn))
1680     {
1681     case TYPE_IMOVX:
1682       /* movzwl is faster than movw on p2 due to partial word stalls,
1683          though not as fast as an aligned movl.  */
1684       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1685     default:
1686       if (get_attr_mode (insn) == MODE_SI)
1687         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1688       else
1689         return "mov{w}\t{%1, %0|%0, %1}";
1690     }
1691 }
1692   [(set (attr "type")
1693      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1694               (const_string "imov")
1695             (and (eq_attr "alternative" "0")
1696                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1697                           (const_int 0))
1698                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1699                           (const_int 0))))
1700               (const_string "imov")
1701             (and (eq_attr "alternative" "1,2")
1702                  (match_operand:HI 1 "aligned_operand" ""))
1703               (const_string "imov")
1704             (and (ne (symbol_ref "TARGET_MOVX")
1705                      (const_int 0))
1706                  (eq_attr "alternative" "0,2"))
1707               (const_string "imovx")
1708            ]
1709            (const_string "imov")))
1710     (set (attr "mode")
1711       (cond [(eq_attr "type" "imovx")
1712                (const_string "SI")
1713              (and (eq_attr "alternative" "1,2")
1714                   (match_operand:HI 1 "aligned_operand" ""))
1715                (const_string "SI")
1716              (and (eq_attr "alternative" "0")
1717                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1718                            (const_int 0))
1719                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1720                            (const_int 0))))
1721                (const_string "SI")
1722             ]
1723             (const_string "HI")))])
1724
1725 ;; Stores and loads of ax to arbitrary constant address.
1726 ;; We fake an second form of instruction to force reload to load address
1727 ;; into register when rax is not available
1728 (define_insn "*movabshi_1_rex64"
1729   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1730         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1731   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1732   "@
1733    movabs{w}\t{%1, %P0|%P0, %1}
1734    mov{w}\t{%1, %a0|%a0, %1}"
1735   [(set_attr "type" "imov")
1736    (set_attr "modrm" "0,*")
1737    (set_attr "length_address" "8,0")
1738    (set_attr "length_immediate" "0,*")
1739    (set_attr "memory" "store")
1740    (set_attr "mode" "HI")])
1741
1742 (define_insn "*movabshi_2_rex64"
1743   [(set (match_operand:HI 0 "register_operand" "=a,r")
1744         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1745   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1746   "@
1747    movabs{w}\t{%P1, %0|%0, %P1}
1748    mov{w}\t{%a1, %0|%0, %a1}"
1749   [(set_attr "type" "imov")
1750    (set_attr "modrm" "0,*")
1751    (set_attr "length_address" "8,0")
1752    (set_attr "length_immediate" "0")
1753    (set_attr "memory" "load")
1754    (set_attr "mode" "HI")])
1755
1756 (define_insn "*swaphi_1"
1757   [(set (match_operand:HI 0 "register_operand" "+r")
1758         (match_operand:HI 1 "register_operand" "+r"))
1759    (set (match_dup 1)
1760         (match_dup 0))]
1761   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1762   "xchg{l}\t%k1, %k0"
1763   [(set_attr "type" "imov")
1764    (set_attr "mode" "SI")
1765    (set_attr "pent_pair" "np")
1766    (set_attr "athlon_decode" "vector")
1767    (set_attr "amdfam10_decode" "double")])
1768
1769 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1770 (define_insn "*swaphi_2"
1771   [(set (match_operand:HI 0 "register_operand" "+r")
1772         (match_operand:HI 1 "register_operand" "+r"))
1773    (set (match_dup 1)
1774         (match_dup 0))]
1775   "TARGET_PARTIAL_REG_STALL"
1776   "xchg{w}\t%1, %0"
1777   [(set_attr "type" "imov")
1778    (set_attr "mode" "HI")
1779    (set_attr "pent_pair" "np")
1780    (set_attr "athlon_decode" "vector")])
1781
1782 (define_expand "movstricthi"
1783   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1784         (match_operand:HI 1 "general_operand" ""))]
1785   ""
1786 {
1787   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1788     FAIL;
1789   /* Don't generate memory->memory moves, go through a register */
1790   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1791     operands[1] = force_reg (HImode, operands[1]);
1792 })
1793
1794 (define_insn "*movstricthi_1"
1795   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1796         (match_operand:HI 1 "general_operand" "rn,m"))]
1797   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1798    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1799   "mov{w}\t{%1, %0|%0, %1}"
1800   [(set_attr "type" "imov")
1801    (set_attr "mode" "HI")])
1802
1803 (define_insn "*movstricthi_xor"
1804   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1805         (match_operand:HI 1 "const0_operand" ""))
1806    (clobber (reg:CC FLAGS_REG))]
1807   "reload_completed"
1808   "xor{w}\t%0, %0"
1809   [(set_attr "type" "alu1")
1810    (set_attr "mode" "HI")
1811    (set_attr "length_immediate" "0")])
1812
1813 (define_expand "movqi"
1814   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1815         (match_operand:QI 1 "general_operand" ""))]
1816   ""
1817   "ix86_expand_move (QImode, operands); DONE;")
1818
1819 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1820 ;; "push a byte".  But actually we use pushl, which has the effect
1821 ;; of rounding the amount pushed up to a word.
1822
1823 (define_insn "*pushqi2"
1824   [(set (match_operand:QI 0 "push_operand" "=X")
1825         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1826   "!TARGET_64BIT"
1827   "push{l}\t%k1"
1828   [(set_attr "type" "push")
1829    (set_attr "mode" "SI")])
1830
1831 ;; For 64BIT abi we always round up to 8 bytes.
1832 (define_insn "*pushqi2_rex64"
1833   [(set (match_operand:QI 0 "push_operand" "=X")
1834         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1835   "TARGET_64BIT"
1836   "push{q}\t%q1"
1837   [(set_attr "type" "push")
1838    (set_attr "mode" "DI")])
1839
1840 ;; Situation is quite tricky about when to choose full sized (SImode) move
1841 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1842 ;; partial register dependency machines (such as AMD Athlon), where QImode
1843 ;; moves issue extra dependency and for partial register stalls machines
1844 ;; that don't use QImode patterns (and QImode move cause stall on the next
1845 ;; instruction).
1846 ;;
1847 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1848 ;; register stall machines with, where we use QImode instructions, since
1849 ;; partial register stall can be caused there.  Then we use movzx.
1850 (define_insn "*movqi_1"
1851   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1852         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1853   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1854 {
1855   switch (get_attr_type (insn))
1856     {
1857     case TYPE_IMOVX:
1858       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1859       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1860     default:
1861       if (get_attr_mode (insn) == MODE_SI)
1862         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1863       else
1864         return "mov{b}\t{%1, %0|%0, %1}";
1865     }
1866 }
1867   [(set (attr "type")
1868      (cond [(and (eq_attr "alternative" "5")
1869                  (not (match_operand:QI 1 "aligned_operand" "")))
1870               (const_string "imovx")
1871             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1872               (const_string "imov")
1873             (and (eq_attr "alternative" "3")
1874                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1875                           (const_int 0))
1876                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1877                           (const_int 0))))
1878               (const_string "imov")
1879             (eq_attr "alternative" "3,5")
1880               (const_string "imovx")
1881             (and (ne (symbol_ref "TARGET_MOVX")
1882                      (const_int 0))
1883                  (eq_attr "alternative" "2"))
1884               (const_string "imovx")
1885            ]
1886            (const_string "imov")))
1887    (set (attr "mode")
1888       (cond [(eq_attr "alternative" "3,4,5")
1889                (const_string "SI")
1890              (eq_attr "alternative" "6")
1891                (const_string "QI")
1892              (eq_attr "type" "imovx")
1893                (const_string "SI")
1894              (and (eq_attr "type" "imov")
1895                   (and (eq_attr "alternative" "0,1")
1896                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1897                                 (const_int 0))
1898                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1899                                      (const_int 0))
1900                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1901                                      (const_int 0))))))
1902                (const_string "SI")
1903              ;; Avoid partial register stalls when not using QImode arithmetic
1904              (and (eq_attr "type" "imov")
1905                   (and (eq_attr "alternative" "0,1")
1906                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1907                                 (const_int 0))
1908                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1909                                 (const_int 0)))))
1910                (const_string "SI")
1911            ]
1912            (const_string "QI")))])
1913
1914 (define_insn "*swapqi_1"
1915   [(set (match_operand:QI 0 "register_operand" "+r")
1916         (match_operand:QI 1 "register_operand" "+r"))
1917    (set (match_dup 1)
1918         (match_dup 0))]
1919   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1920   "xchg{l}\t%k1, %k0"
1921   [(set_attr "type" "imov")
1922    (set_attr "mode" "SI")
1923    (set_attr "pent_pair" "np")
1924    (set_attr "athlon_decode" "vector")
1925    (set_attr "amdfam10_decode" "vector")])
1926
1927 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1928 (define_insn "*swapqi_2"
1929   [(set (match_operand:QI 0 "register_operand" "+q")
1930         (match_operand:QI 1 "register_operand" "+q"))
1931    (set (match_dup 1)
1932         (match_dup 0))]
1933   "TARGET_PARTIAL_REG_STALL"
1934   "xchg{b}\t%1, %0"
1935   [(set_attr "type" "imov")
1936    (set_attr "mode" "QI")
1937    (set_attr "pent_pair" "np")
1938    (set_attr "athlon_decode" "vector")])
1939
1940 (define_expand "movstrictqi"
1941   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1942         (match_operand:QI 1 "general_operand" ""))]
1943   ""
1944 {
1945   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1946     FAIL;
1947   /* Don't generate memory->memory moves, go through a register.  */
1948   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1949     operands[1] = force_reg (QImode, operands[1]);
1950 })
1951
1952 (define_insn "*movstrictqi_1"
1953   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1954         (match_operand:QI 1 "general_operand" "*qn,m"))]
1955   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1956    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1957   "mov{b}\t{%1, %0|%0, %1}"
1958   [(set_attr "type" "imov")
1959    (set_attr "mode" "QI")])
1960
1961 (define_insn "*movstrictqi_xor"
1962   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1963         (match_operand:QI 1 "const0_operand" ""))
1964    (clobber (reg:CC FLAGS_REG))]
1965   "reload_completed"
1966   "xor{b}\t%0, %0"
1967   [(set_attr "type" "alu1")
1968    (set_attr "mode" "QI")
1969    (set_attr "length_immediate" "0")])
1970
1971 (define_insn "*movsi_extv_1"
1972   [(set (match_operand:SI 0 "register_operand" "=R")
1973         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1974                          (const_int 8)
1975                          (const_int 8)))]
1976   ""
1977   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1978   [(set_attr "type" "imovx")
1979    (set_attr "mode" "SI")])
1980
1981 (define_insn "*movhi_extv_1"
1982   [(set (match_operand:HI 0 "register_operand" "=R")
1983         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1984                          (const_int 8)
1985                          (const_int 8)))]
1986   ""
1987   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1988   [(set_attr "type" "imovx")
1989    (set_attr "mode" "SI")])
1990
1991 (define_insn "*movqi_extv_1"
1992   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1993         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1994                          (const_int 8)
1995                          (const_int 8)))]
1996   "!TARGET_64BIT"
1997 {
1998   switch (get_attr_type (insn))
1999     {
2000     case TYPE_IMOVX:
2001       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2002     default:
2003       return "mov{b}\t{%h1, %0|%0, %h1}";
2004     }
2005 }
2006   [(set (attr "type")
2007      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2008                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2009                              (ne (symbol_ref "TARGET_MOVX")
2010                                  (const_int 0))))
2011         (const_string "imovx")
2012         (const_string "imov")))
2013    (set (attr "mode")
2014      (if_then_else (eq_attr "type" "imovx")
2015         (const_string "SI")
2016         (const_string "QI")))])
2017
2018 (define_insn "*movqi_extv_1_rex64"
2019   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2020         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2021                          (const_int 8)
2022                          (const_int 8)))]
2023   "TARGET_64BIT"
2024 {
2025   switch (get_attr_type (insn))
2026     {
2027     case TYPE_IMOVX:
2028       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2029     default:
2030       return "mov{b}\t{%h1, %0|%0, %h1}";
2031     }
2032 }
2033   [(set (attr "type")
2034      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2035                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2036                              (ne (symbol_ref "TARGET_MOVX")
2037                                  (const_int 0))))
2038         (const_string "imovx")
2039         (const_string "imov")))
2040    (set (attr "mode")
2041      (if_then_else (eq_attr "type" "imovx")
2042         (const_string "SI")
2043         (const_string "QI")))])
2044
2045 ;; Stores and loads of ax to arbitrary constant address.
2046 ;; We fake an second form of instruction to force reload to load address
2047 ;; into register when rax is not available
2048 (define_insn "*movabsqi_1_rex64"
2049   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2050         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2051   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2052   "@
2053    movabs{b}\t{%1, %P0|%P0, %1}
2054    mov{b}\t{%1, %a0|%a0, %1}"
2055   [(set_attr "type" "imov")
2056    (set_attr "modrm" "0,*")
2057    (set_attr "length_address" "8,0")
2058    (set_attr "length_immediate" "0,*")
2059    (set_attr "memory" "store")
2060    (set_attr "mode" "QI")])
2061
2062 (define_insn "*movabsqi_2_rex64"
2063   [(set (match_operand:QI 0 "register_operand" "=a,r")
2064         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2065   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2066   "@
2067    movabs{b}\t{%P1, %0|%0, %P1}
2068    mov{b}\t{%a1, %0|%0, %a1}"
2069   [(set_attr "type" "imov")
2070    (set_attr "modrm" "0,*")
2071    (set_attr "length_address" "8,0")
2072    (set_attr "length_immediate" "0")
2073    (set_attr "memory" "load")
2074    (set_attr "mode" "QI")])
2075
2076 (define_insn "*movdi_extzv_1"
2077   [(set (match_operand:DI 0 "register_operand" "=R")
2078         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2079                          (const_int 8)
2080                          (const_int 8)))]
2081   "TARGET_64BIT"
2082   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2083   [(set_attr "type" "imovx")
2084    (set_attr "mode" "DI")])
2085
2086 (define_insn "*movsi_extzv_1"
2087   [(set (match_operand:SI 0 "register_operand" "=R")
2088         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2089                          (const_int 8)
2090                          (const_int 8)))]
2091   ""
2092   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2093   [(set_attr "type" "imovx")
2094    (set_attr "mode" "SI")])
2095
2096 (define_insn "*movqi_extzv_2"
2097   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2098         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2099                                     (const_int 8)
2100                                     (const_int 8)) 0))]
2101   "!TARGET_64BIT"
2102 {
2103   switch (get_attr_type (insn))
2104     {
2105     case TYPE_IMOVX:
2106       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2107     default:
2108       return "mov{b}\t{%h1, %0|%0, %h1}";
2109     }
2110 }
2111   [(set (attr "type")
2112      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2113                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2114                              (ne (symbol_ref "TARGET_MOVX")
2115                                  (const_int 0))))
2116         (const_string "imovx")
2117         (const_string "imov")))
2118    (set (attr "mode")
2119      (if_then_else (eq_attr "type" "imovx")
2120         (const_string "SI")
2121         (const_string "QI")))])
2122
2123 (define_insn "*movqi_extzv_2_rex64"
2124   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2125         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2126                                     (const_int 8)
2127                                     (const_int 8)) 0))]
2128   "TARGET_64BIT"
2129 {
2130   switch (get_attr_type (insn))
2131     {
2132     case TYPE_IMOVX:
2133       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2134     default:
2135       return "mov{b}\t{%h1, %0|%0, %h1}";
2136     }
2137 }
2138   [(set (attr "type")
2139      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2140                         (ne (symbol_ref "TARGET_MOVX")
2141                             (const_int 0)))
2142         (const_string "imovx")
2143         (const_string "imov")))
2144    (set (attr "mode")
2145      (if_then_else (eq_attr "type" "imovx")
2146         (const_string "SI")
2147         (const_string "QI")))])
2148
2149 (define_insn "movsi_insv_1"
2150   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2151                          (const_int 8)
2152                          (const_int 8))
2153         (match_operand:SI 1 "general_operand" "Qmn"))]
2154   "!TARGET_64BIT"
2155   "mov{b}\t{%b1, %h0|%h0, %b1}"
2156   [(set_attr "type" "imov")
2157    (set_attr "mode" "QI")])
2158
2159 (define_insn "*movsi_insv_1_rex64"
2160   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2161                          (const_int 8)
2162                          (const_int 8))
2163         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2164   "TARGET_64BIT"
2165   "mov{b}\t{%b1, %h0|%h0, %b1}"
2166   [(set_attr "type" "imov")
2167    (set_attr "mode" "QI")])
2168
2169 (define_insn "movdi_insv_1_rex64"
2170   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2171                          (const_int 8)
2172                          (const_int 8))
2173         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2174   "TARGET_64BIT"
2175   "mov{b}\t{%b1, %h0|%h0, %b1}"
2176   [(set_attr "type" "imov")
2177    (set_attr "mode" "QI")])
2178
2179 (define_insn "*movqi_insv_2"
2180   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2181                          (const_int 8)
2182                          (const_int 8))
2183         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2184                      (const_int 8)))]
2185   ""
2186   "mov{b}\t{%h1, %h0|%h0, %h1}"
2187   [(set_attr "type" "imov")
2188    (set_attr "mode" "QI")])
2189
2190 (define_expand "movdi"
2191   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2192         (match_operand:DI 1 "general_operand" ""))]
2193   ""
2194   "ix86_expand_move (DImode, operands); DONE;")
2195
2196 (define_insn "*pushdi"
2197   [(set (match_operand:DI 0 "push_operand" "=<")
2198         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2199   "!TARGET_64BIT"
2200   "#")
2201
2202 (define_insn "*pushdi2_rex64"
2203   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2204         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2205   "TARGET_64BIT"
2206   "@
2207    push{q}\t%1
2208    #"
2209   [(set_attr "type" "push,multi")
2210    (set_attr "mode" "DI")])
2211
2212 ;; Convert impossible pushes of immediate to existing instructions.
2213 ;; First try to get scratch register and go through it.  In case this
2214 ;; fails, push sign extended lower part first and then overwrite
2215 ;; upper part by 32bit move.
2216 (define_peephole2
2217   [(match_scratch:DI 2 "r")
2218    (set (match_operand:DI 0 "push_operand" "")
2219         (match_operand:DI 1 "immediate_operand" ""))]
2220   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2221    && !x86_64_immediate_operand (operands[1], DImode)"
2222   [(set (match_dup 2) (match_dup 1))
2223    (set (match_dup 0) (match_dup 2))]
2224   "")
2225
2226 ;; We need to define this as both peepholer and splitter for case
2227 ;; peephole2 pass is not run.
2228 ;; "&& 1" is needed to keep it from matching the previous pattern.
2229 (define_peephole2
2230   [(set (match_operand:DI 0 "push_operand" "")
2231         (match_operand:DI 1 "immediate_operand" ""))]
2232   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2233    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2234   [(set (match_dup 0) (match_dup 1))
2235    (set (match_dup 2) (match_dup 3))]
2236   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2237    operands[1] = gen_lowpart (DImode, operands[2]);
2238    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2239                                                     GEN_INT (4)));
2240   ")
2241
2242 (define_split
2243   [(set (match_operand:DI 0 "push_operand" "")
2244         (match_operand:DI 1 "immediate_operand" ""))]
2245   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2246                     ? epilogue_completed : reload_completed)
2247    && !symbolic_operand (operands[1], DImode)
2248    && !x86_64_immediate_operand (operands[1], DImode)"
2249   [(set (match_dup 0) (match_dup 1))
2250    (set (match_dup 2) (match_dup 3))]
2251   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2252    operands[1] = gen_lowpart (DImode, operands[2]);
2253    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2254                                                     GEN_INT (4)));
2255   ")
2256
2257 (define_insn "*pushdi2_prologue_rex64"
2258   [(set (match_operand:DI 0 "push_operand" "=<")
2259         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2260    (clobber (mem:BLK (scratch)))]
2261   "TARGET_64BIT"
2262   "push{q}\t%1"
2263   [(set_attr "type" "push")
2264    (set_attr "mode" "DI")])
2265
2266 (define_insn "*popdi1_epilogue_rex64"
2267   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2268         (mem:DI (reg:DI SP_REG)))
2269    (set (reg:DI SP_REG)
2270         (plus:DI (reg:DI SP_REG) (const_int 8)))
2271    (clobber (mem:BLK (scratch)))]
2272   "TARGET_64BIT"
2273   "pop{q}\t%0"
2274   [(set_attr "type" "pop")
2275    (set_attr "mode" "DI")])
2276
2277 (define_insn "popdi1"
2278   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2279         (mem:DI (reg:DI SP_REG)))
2280    (set (reg:DI SP_REG)
2281         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2282   "TARGET_64BIT"
2283   "pop{q}\t%0"
2284   [(set_attr "type" "pop")
2285    (set_attr "mode" "DI")])
2286
2287 (define_insn "*movdi_xor_rex64"
2288   [(set (match_operand:DI 0 "register_operand" "=r")
2289         (match_operand:DI 1 "const0_operand" ""))
2290    (clobber (reg:CC FLAGS_REG))]
2291   "TARGET_64BIT
2292    && reload_completed"
2293   "xor{l}\t%k0, %k0";
2294   [(set_attr "type" "alu1")
2295    (set_attr "mode" "SI")
2296    (set_attr "length_immediate" "0")])
2297
2298 (define_insn "*movdi_or_rex64"
2299   [(set (match_operand:DI 0 "register_operand" "=r")
2300         (match_operand:DI 1 "const_int_operand" "i"))
2301    (clobber (reg:CC FLAGS_REG))]
2302   "TARGET_64BIT
2303    && reload_completed
2304    && operands[1] == constm1_rtx"
2305 {
2306   operands[1] = constm1_rtx;
2307   return "or{q}\t{%1, %0|%0, %1}";
2308 }
2309   [(set_attr "type" "alu1")
2310    (set_attr "mode" "DI")
2311    (set_attr "length_immediate" "1")])
2312
2313 (define_insn "*movdi_2"
2314   [(set (match_operand:DI 0 "nonimmediate_operand"
2315                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2316         (match_operand:DI 1 "general_operand"
2317                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2318   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2319   "@
2320    #
2321    #
2322    pxor\t%0, %0
2323    movq\t{%1, %0|%0, %1}
2324    movq\t{%1, %0|%0, %1}
2325    %vpxor\t%0, %d0
2326    %vmovq\t{%1, %0|%0, %1}
2327    %vmovdqa\t{%1, %0|%0, %1}
2328    %vmovq\t{%1, %0|%0, %1}
2329    xorps\t%0, %0
2330    movlps\t{%1, %0|%0, %1}
2331    movaps\t{%1, %0|%0, %1}
2332    movlps\t{%1, %0|%0, %1}"
2333   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2334    (set (attr "prefix")
2335      (if_then_else (eq_attr "alternative" "5,6,7,8")
2336        (const_string "vex")
2337        (const_string "orig")))
2338    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2339
2340 (define_split
2341   [(set (match_operand:DI 0 "push_operand" "")
2342         (match_operand:DI 1 "general_operand" ""))]
2343   "!TARGET_64BIT && reload_completed
2344    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2345   [(const_int 0)]
2346   "ix86_split_long_move (operands); DONE;")
2347
2348 ;; %%% This multiword shite has got to go.
2349 (define_split
2350   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2351         (match_operand:DI 1 "general_operand" ""))]
2352   "!TARGET_64BIT && reload_completed
2353    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2354    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2355   [(const_int 0)]
2356   "ix86_split_long_move (operands); DONE;")
2357
2358 (define_insn "*movdi_1_rex64"
2359   [(set (match_operand:DI 0 "nonimmediate_operand"
2360           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2361         (match_operand:DI 1 "general_operand"
2362           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2363   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2364 {
2365   switch (get_attr_type (insn))
2366     {
2367     case TYPE_SSECVT:
2368       if (SSE_REG_P (operands[0]))
2369         return "movq2dq\t{%1, %0|%0, %1}";
2370       else
2371         return "movdq2q\t{%1, %0|%0, %1}";
2372
2373     case TYPE_SSEMOV:
2374       if (TARGET_AVX)
2375         {
2376           if (get_attr_mode (insn) == MODE_TI)
2377             return "vmovdqa\t{%1, %0|%0, %1}";
2378           else
2379             return "vmovq\t{%1, %0|%0, %1}";
2380         }
2381
2382       if (get_attr_mode (insn) == MODE_TI)
2383         return "movdqa\t{%1, %0|%0, %1}";
2384       /* FALLTHRU */
2385
2386     case TYPE_MMXMOV:
2387       /* Moves from and into integer register is done using movd
2388          opcode with REX prefix.  */
2389       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2390         return "movd\t{%1, %0|%0, %1}";
2391       return "movq\t{%1, %0|%0, %1}";
2392
2393     case TYPE_SSELOG1:
2394       return "%vpxor\t%0, %d0";
2395
2396     case TYPE_MMX:
2397       return "pxor\t%0, %0";
2398
2399     case TYPE_MULTI:
2400       return "#";
2401
2402     case TYPE_LEA:
2403       return "lea{q}\t{%a1, %0|%0, %a1}";
2404
2405     default:
2406       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2407       if (get_attr_mode (insn) == MODE_SI)
2408         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2409       else if (which_alternative == 2)
2410         return "movabs{q}\t{%1, %0|%0, %1}";
2411       else
2412         return "mov{q}\t{%1, %0|%0, %1}";
2413     }
2414 }
2415   [(set (attr "type")
2416      (cond [(eq_attr "alternative" "5")
2417               (const_string "mmx")
2418             (eq_attr "alternative" "6,7,8,9,10")
2419               (const_string "mmxmov")
2420             (eq_attr "alternative" "11")
2421               (const_string "sselog1")
2422             (eq_attr "alternative" "12,13,14,15,16")
2423               (const_string "ssemov")
2424             (eq_attr "alternative" "17,18")
2425               (const_string "ssecvt")
2426             (eq_attr "alternative" "4")
2427               (const_string "multi")
2428             (match_operand:DI 1 "pic_32bit_operand" "")
2429               (const_string "lea")
2430            ]
2431            (const_string "imov")))
2432    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2433    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2434    (set (attr "prefix")
2435      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2436        (const_string "maybe_vex")
2437        (const_string "orig")))
2438    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2439
2440 ;; Stores and loads of ax to arbitrary constant address.
2441 ;; We fake an second form of instruction to force reload to load address
2442 ;; into register when rax is not available
2443 (define_insn "*movabsdi_1_rex64"
2444   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2445         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2446   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2447   "@
2448    movabs{q}\t{%1, %P0|%P0, %1}
2449    mov{q}\t{%1, %a0|%a0, %1}"
2450   [(set_attr "type" "imov")
2451    (set_attr "modrm" "0,*")
2452    (set_attr "length_address" "8,0")
2453    (set_attr "length_immediate" "0,*")
2454    (set_attr "memory" "store")
2455    (set_attr "mode" "DI")])
2456
2457 (define_insn "*movabsdi_2_rex64"
2458   [(set (match_operand:DI 0 "register_operand" "=a,r")
2459         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2460   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2461   "@
2462    movabs{q}\t{%P1, %0|%0, %P1}
2463    mov{q}\t{%a1, %0|%0, %a1}"
2464   [(set_attr "type" "imov")
2465    (set_attr "modrm" "0,*")
2466    (set_attr "length_address" "8,0")
2467    (set_attr "length_immediate" "0")
2468    (set_attr "memory" "load")
2469    (set_attr "mode" "DI")])
2470
2471 ;; Convert impossible stores of immediate to existing instructions.
2472 ;; First try to get scratch register and go through it.  In case this
2473 ;; fails, move by 32bit parts.
2474 (define_peephole2
2475   [(match_scratch:DI 2 "r")
2476    (set (match_operand:DI 0 "memory_operand" "")
2477         (match_operand:DI 1 "immediate_operand" ""))]
2478   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2479    && !x86_64_immediate_operand (operands[1], DImode)"
2480   [(set (match_dup 2) (match_dup 1))
2481    (set (match_dup 0) (match_dup 2))]
2482   "")
2483
2484 ;; We need to define this as both peepholer and splitter for case
2485 ;; peephole2 pass is not run.
2486 ;; "&& 1" is needed to keep it from matching the previous pattern.
2487 (define_peephole2
2488   [(set (match_operand:DI 0 "memory_operand" "")
2489         (match_operand:DI 1 "immediate_operand" ""))]
2490   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2491    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2492   [(set (match_dup 2) (match_dup 3))
2493    (set (match_dup 4) (match_dup 5))]
2494   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2495
2496 (define_split
2497   [(set (match_operand:DI 0 "memory_operand" "")
2498         (match_operand:DI 1 "immediate_operand" ""))]
2499   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2500                     ? epilogue_completed : reload_completed)
2501    && !symbolic_operand (operands[1], DImode)
2502    && !x86_64_immediate_operand (operands[1], DImode)"
2503   [(set (match_dup 2) (match_dup 3))
2504    (set (match_dup 4) (match_dup 5))]
2505   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2506
2507 (define_insn "*swapdi_rex64"
2508   [(set (match_operand:DI 0 "register_operand" "+r")
2509         (match_operand:DI 1 "register_operand" "+r"))
2510    (set (match_dup 1)
2511         (match_dup 0))]
2512   "TARGET_64BIT"
2513   "xchg{q}\t%1, %0"
2514   [(set_attr "type" "imov")
2515    (set_attr "mode" "DI")
2516    (set_attr "pent_pair" "np")
2517    (set_attr "athlon_decode" "vector")
2518    (set_attr "amdfam10_decode" "double")])
2519
2520 (define_expand "movoi"
2521   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2522         (match_operand:OI 1 "general_operand" ""))]
2523   "TARGET_AVX"
2524   "ix86_expand_move (OImode, operands); DONE;")
2525
2526 (define_insn "*movoi_internal"
2527   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2528         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2529   "TARGET_AVX
2530    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2531 {
2532   switch (which_alternative)
2533     {
2534     case 0:
2535       return "vxorps\t%0, %0, %0";
2536     case 1:
2537     case 2:
2538       if (misaligned_operand (operands[0], OImode)
2539           || misaligned_operand (operands[1], OImode))
2540         return "vmovdqu\t{%1, %0|%0, %1}";
2541       else
2542         return "vmovdqa\t{%1, %0|%0, %1}";
2543     default:
2544       gcc_unreachable ();
2545     }
2546 }
2547   [(set_attr "type" "sselog1,ssemov,ssemov")
2548    (set_attr "prefix" "vex")
2549    (set_attr "mode" "OI")])
2550
2551 (define_expand "movti"
2552   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2553         (match_operand:TI 1 "nonimmediate_operand" ""))]
2554   "TARGET_SSE || TARGET_64BIT"
2555 {
2556   if (TARGET_64BIT)
2557     ix86_expand_move (TImode, operands);
2558   else if (push_operand (operands[0], TImode))
2559     ix86_expand_push (TImode, operands[1]);
2560   else
2561     ix86_expand_vector_move (TImode, operands);
2562   DONE;
2563 })
2564
2565 (define_insn "*pushti"
2566   [(set (match_operand:TI 0 "push_operand" "=<")
2567         (match_operand:TI 1 "general_no_elim_operand" "riF*m"))]
2568   "TARGET_64BIT"
2569   "#")
2570
2571 (define_insn "*movti_internal"
2572   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2573         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2574   "TARGET_SSE && !TARGET_64BIT
2575    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2576 {
2577   switch (which_alternative)
2578     {
2579     case 0:
2580       if (get_attr_mode (insn) == MODE_V4SF)
2581         return "%vxorps\t%0, %d0";
2582       else
2583         return "%vpxor\t%0, %d0";
2584     case 1:
2585     case 2:
2586       /* TDmode values are passed as TImode on the stack.  Moving them
2587          to stack may result in unaligned memory access.  */
2588       if (misaligned_operand (operands[0], TImode)
2589           || misaligned_operand (operands[1], TImode))
2590         {
2591           if (get_attr_mode (insn) == MODE_V4SF)
2592             return "%vmovups\t{%1, %0|%0, %1}";
2593          else
2594            return "%vmovdqu\t{%1, %0|%0, %1}";
2595         }
2596       else
2597         {
2598           if (get_attr_mode (insn) == MODE_V4SF)
2599             return "%vmovaps\t{%1, %0|%0, %1}";
2600          else
2601            return "%vmovdqa\t{%1, %0|%0, %1}";
2602         }
2603     default:
2604       gcc_unreachable ();
2605     }
2606 }
2607   [(set_attr "type" "sselog1,ssemov,ssemov")
2608    (set_attr "prefix" "maybe_vex")
2609    (set (attr "mode")
2610         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2611                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2612                  (const_string "V4SF")
2613                (and (eq_attr "alternative" "2")
2614                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2615                         (const_int 0)))
2616                  (const_string "V4SF")]
2617               (const_string "TI")))])
2618
2619 (define_insn "*movti_rex64"
2620   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2621         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2622   "TARGET_64BIT
2623    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2624 {
2625   switch (which_alternative)
2626     {
2627     case 0:
2628     case 1:
2629       return "#";
2630     case 2:
2631       if (get_attr_mode (insn) == MODE_V4SF)
2632         return "%vxorps\t%0, %d0";
2633       else
2634         return "%vpxor\t%0, %d0";
2635     case 3:
2636     case 4:
2637       /* TDmode values are passed as TImode on the stack.  Moving them
2638          to stack may result in unaligned memory access.  */
2639       if (misaligned_operand (operands[0], TImode)
2640           || misaligned_operand (operands[1], TImode))
2641         {
2642           if (get_attr_mode (insn) == MODE_V4SF)
2643             return "%vmovups\t{%1, %0|%0, %1}";
2644          else
2645            return "%vmovdqu\t{%1, %0|%0, %1}";
2646         }
2647       else
2648         {
2649           if (get_attr_mode (insn) == MODE_V4SF)
2650             return "%vmovaps\t{%1, %0|%0, %1}";
2651          else
2652            return "%vmovdqa\t{%1, %0|%0, %1}";
2653         }
2654     default:
2655       gcc_unreachable ();
2656     }
2657 }
2658   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2659    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2660    (set (attr "mode")
2661         (cond [(eq_attr "alternative" "2,3")
2662                  (if_then_else
2663                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2664                        (const_int 0))
2665                    (const_string "V4SF")
2666                    (const_string "TI"))
2667                (eq_attr "alternative" "4")
2668                  (if_then_else
2669                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2670                             (const_int 0))
2671                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2672                             (const_int 0)))
2673                    (const_string "V4SF")
2674                    (const_string "TI"))]
2675                (const_string "DI")))])
2676
2677 (define_split
2678   [(set (match_operand:TI 0 "push_operand" "")
2679         (match_operand:TI 1 "general_operand" ""))]
2680   "TARGET_64BIT && reload_completed
2681    && !SSE_REG_P (operands[1])"
2682   [(const_int 0)]
2683   "ix86_split_long_move (operands); DONE;")
2684
2685 (define_split
2686   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2687         (match_operand:TI 1 "general_operand" ""))]
2688   "reload_completed && !SSE_REG_P (operands[0])
2689    && !SSE_REG_P (operands[1])"
2690   [(const_int 0)]
2691   "ix86_split_long_move (operands); DONE;")
2692
2693 ;; This expands to what emit_move_complex would generate if we didn't
2694 ;; have a movti pattern.  Having this avoids problems with reload on
2695 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2696 ;; to have around all the time.
2697 (define_expand "movcdi"
2698   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2699         (match_operand:CDI 1 "general_operand" ""))]
2700   ""
2701 {
2702   if (push_operand (operands[0], CDImode))
2703     emit_move_complex_push (CDImode, operands[0], operands[1]);
2704   else
2705     emit_move_complex_parts (operands[0], operands[1]);
2706   DONE;
2707 })
2708
2709 (define_expand "movsf"
2710   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2711         (match_operand:SF 1 "general_operand" ""))]
2712   ""
2713   "ix86_expand_move (SFmode, operands); DONE;")
2714
2715 (define_insn "*pushsf"
2716   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2717         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2718   "!TARGET_64BIT"
2719 {
2720   /* Anything else should be already split before reg-stack.  */
2721   gcc_assert (which_alternative == 1);
2722   return "push{l}\t%1";
2723 }
2724   [(set_attr "type" "multi,push,multi")
2725    (set_attr "unit" "i387,*,*")
2726    (set_attr "mode" "SF,SI,SF")])
2727
2728 (define_insn "*pushsf_rex64"
2729   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2730         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2731   "TARGET_64BIT"
2732 {
2733   /* Anything else should be already split before reg-stack.  */
2734   gcc_assert (which_alternative == 1);
2735   return "push{q}\t%q1";
2736 }
2737   [(set_attr "type" "multi,push,multi")
2738    (set_attr "unit" "i387,*,*")
2739    (set_attr "mode" "SF,DI,SF")])
2740
2741 (define_split
2742   [(set (match_operand:SF 0 "push_operand" "")
2743         (match_operand:SF 1 "memory_operand" ""))]
2744   "reload_completed
2745    && MEM_P (operands[1])
2746    && (operands[2] = find_constant_src (insn))"
2747   [(set (match_dup 0)
2748         (match_dup 2))])
2749
2750
2751 ;; %%% Kill this when call knows how to work this out.
2752 (define_split
2753   [(set (match_operand:SF 0 "push_operand" "")
2754         (match_operand:SF 1 "any_fp_register_operand" ""))]
2755   "!TARGET_64BIT"
2756   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2757    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2758
2759 (define_split
2760   [(set (match_operand:SF 0 "push_operand" "")
2761         (match_operand:SF 1 "any_fp_register_operand" ""))]
2762   "TARGET_64BIT"
2763   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2764    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2765
2766 (define_insn "*movsf_1"
2767   [(set (match_operand:SF 0 "nonimmediate_operand"
2768           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2769         (match_operand:SF 1 "general_operand"
2770           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2771   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2772    && (reload_in_progress || reload_completed
2773        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2774        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2775            && standard_80387_constant_p (operands[1]))
2776        || GET_CODE (operands[1]) != CONST_DOUBLE
2777        || memory_operand (operands[0], SFmode))"
2778 {
2779   switch (which_alternative)
2780     {
2781     case 0:
2782     case 1:
2783       return output_387_reg_move (insn, operands);
2784
2785     case 2:
2786       return standard_80387_constant_opcode (operands[1]);
2787
2788     case 3:
2789     case 4:
2790       return "mov{l}\t{%1, %0|%0, %1}";
2791     case 5:
2792       if (get_attr_mode (insn) == MODE_TI)
2793         return "%vpxor\t%0, %d0";
2794       else
2795         return "%vxorps\t%0, %d0";
2796     case 6:
2797       if (get_attr_mode (insn) == MODE_V4SF)
2798         return "%vmovaps\t{%1, %0|%0, %1}";
2799       else
2800         return "%vmovss\t{%1, %d0|%d0, %1}";
2801     case 7:
2802       if (TARGET_AVX)
2803         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2804                                    : "vmovss\t{%1, %0|%0, %1}";
2805       else
2806         return "movss\t{%1, %0|%0, %1}";
2807     case 8:
2808       return "%vmovss\t{%1, %0|%0, %1}";
2809
2810     case 9: case 10: case 14: case 15:
2811       return "movd\t{%1, %0|%0, %1}";
2812     case 12: case 13:
2813       return "%vmovd\t{%1, %0|%0, %1}";
2814
2815     case 11:
2816       return "movq\t{%1, %0|%0, %1}";
2817
2818     default:
2819       gcc_unreachable ();
2820     }
2821 }
2822   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2823    (set (attr "prefix")
2824      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2825        (const_string "maybe_vex")
2826        (const_string "orig")))
2827    (set (attr "mode")
2828         (cond [(eq_attr "alternative" "3,4,9,10")
2829                  (const_string "SI")
2830                (eq_attr "alternative" "5")
2831                  (if_then_else
2832                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2833                                  (const_int 0))
2834                              (ne (symbol_ref "TARGET_SSE2")
2835                                  (const_int 0)))
2836                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2837                             (const_int 0)))
2838                    (const_string "TI")
2839                    (const_string "V4SF"))
2840                /* For architectures resolving dependencies on
2841                   whole SSE registers use APS move to break dependency
2842                   chains, otherwise use short move to avoid extra work.
2843
2844                   Do the same for architectures resolving dependencies on
2845                   the parts.  While in DF mode it is better to always handle
2846                   just register parts, the SF mode is different due to lack
2847                   of instructions to load just part of the register.  It is
2848                   better to maintain the whole registers in single format
2849                   to avoid problems on using packed logical operations.  */
2850                (eq_attr "alternative" "6")
2851                  (if_then_else
2852                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2853                             (const_int 0))
2854                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2855                             (const_int 0)))
2856                    (const_string "V4SF")
2857                    (const_string "SF"))
2858                (eq_attr "alternative" "11")
2859                  (const_string "DI")]
2860                (const_string "SF")))])
2861
2862 (define_insn "*swapsf"
2863   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2864         (match_operand:SF 1 "fp_register_operand" "+f"))
2865    (set (match_dup 1)
2866         (match_dup 0))]
2867   "reload_completed || TARGET_80387"
2868 {
2869   if (STACK_TOP_P (operands[0]))
2870     return "fxch\t%1";
2871   else
2872     return "fxch\t%0";
2873 }
2874   [(set_attr "type" "fxch")
2875    (set_attr "mode" "SF")])
2876
2877 (define_expand "movdf"
2878   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2879         (match_operand:DF 1 "general_operand" ""))]
2880   ""
2881   "ix86_expand_move (DFmode, operands); DONE;")
2882
2883 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2884 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2885 ;; On the average, pushdf using integers can be still shorter.  Allow this
2886 ;; pattern for optimize_size too.
2887
2888 (define_insn "*pushdf_nointeger"
2889   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2890         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2891   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2892 {
2893   /* This insn should be already split before reg-stack.  */
2894   gcc_unreachable ();
2895 }
2896   [(set_attr "type" "multi")
2897    (set_attr "unit" "i387,*,*,*")
2898    (set_attr "mode" "DF,SI,SI,DF")])
2899
2900 (define_insn "*pushdf_integer"
2901   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2902         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2903   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2904 {
2905   /* This insn should be already split before reg-stack.  */
2906   gcc_unreachable ();
2907 }
2908   [(set_attr "type" "multi")
2909    (set_attr "unit" "i387,*,*")
2910    (set_attr "mode" "DF,SI,DF")])
2911
2912 ;; %%% Kill this when call knows how to work this out.
2913 (define_split
2914   [(set (match_operand:DF 0 "push_operand" "")
2915         (match_operand:DF 1 "any_fp_register_operand" ""))]
2916   "reload_completed"
2917   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2918    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2919   "")
2920
2921 (define_split
2922   [(set (match_operand:DF 0 "push_operand" "")
2923         (match_operand:DF 1 "general_operand" ""))]
2924   "reload_completed"
2925   [(const_int 0)]
2926   "ix86_split_long_move (operands); DONE;")
2927
2928 ;; Moving is usually shorter when only FP registers are used. This separate
2929 ;; movdf pattern avoids the use of integer registers for FP operations
2930 ;; when optimizing for size.
2931
2932 (define_insn "*movdf_nointeger"
2933   [(set (match_operand:DF 0 "nonimmediate_operand"
2934                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2935         (match_operand:DF 1 "general_operand"
2936                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2937   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2938    && ((optimize_function_for_size_p (cfun)
2939        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2940    && (reload_in_progress || reload_completed
2941        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2942        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2943            && optimize_function_for_size_p (cfun)
2944            && !memory_operand (operands[0], DFmode)
2945            && standard_80387_constant_p (operands[1]))
2946        || GET_CODE (operands[1]) != CONST_DOUBLE
2947        || ((optimize_function_for_size_p (cfun)
2948             || !TARGET_MEMORY_MISMATCH_STALL
2949             || reload_in_progress || reload_completed)
2950            && memory_operand (operands[0], DFmode)))"
2951 {
2952   switch (which_alternative)
2953     {
2954     case 0:
2955     case 1:
2956       return output_387_reg_move (insn, operands);
2957
2958     case 2:
2959       return standard_80387_constant_opcode (operands[1]);
2960
2961     case 3:
2962     case 4:
2963       return "#";
2964     case 5:
2965       switch (get_attr_mode (insn))
2966         {
2967         case MODE_V4SF:
2968           return "%vxorps\t%0, %d0";
2969         case MODE_V2DF:
2970           return "%vxorpd\t%0, %d0";
2971         case MODE_TI:
2972           return "%vpxor\t%0, %d0";
2973         default:
2974           gcc_unreachable ();
2975         }
2976     case 6:
2977     case 7:
2978     case 8:
2979       switch (get_attr_mode (insn))
2980         {
2981         case MODE_V4SF:
2982           return "%vmovaps\t{%1, %0|%0, %1}";
2983         case MODE_V2DF:
2984           return "%vmovapd\t{%1, %0|%0, %1}";
2985         case MODE_TI:
2986           return "%vmovdqa\t{%1, %0|%0, %1}";
2987         case MODE_DI:
2988           return "%vmovq\t{%1, %0|%0, %1}";
2989         case MODE_DF:
2990           if (TARGET_AVX)
2991             {
2992               if (REG_P (operands[0]) && REG_P (operands[1]))
2993                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2994               else
2995                 return "vmovsd\t{%1, %0|%0, %1}";
2996             }
2997           else
2998             return "movsd\t{%1, %0|%0, %1}";
2999         case MODE_V1DF:
3000           if (TARGET_AVX)
3001             {
3002               if (REG_P (operands[0]))
3003                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3004               else
3005                 return "vmovlpd\t{%1, %0|%0, %1}";
3006             }
3007           else
3008             return "movlpd\t{%1, %0|%0, %1}";
3009         case MODE_V2SF:
3010           if (TARGET_AVX)
3011             {
3012               if (REG_P (operands[0]))
3013                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3014               else
3015                 return "vmovlps\t{%1, %0|%0, %1}";
3016             }
3017           else
3018             return "movlps\t{%1, %0|%0, %1}";
3019         default:
3020           gcc_unreachable ();
3021         }
3022
3023     default:
3024       gcc_unreachable ();
3025     }
3026 }
3027   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3028    (set (attr "prefix")
3029      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3030        (const_string "orig")
3031        (const_string "maybe_vex")))
3032    (set (attr "mode")
3033         (cond [(eq_attr "alternative" "0,1,2")
3034                  (const_string "DF")
3035                (eq_attr "alternative" "3,4")
3036                  (const_string "SI")
3037
3038                /* For SSE1, we have many fewer alternatives.  */
3039                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3040                  (cond [(eq_attr "alternative" "5,6")
3041                           (const_string "V4SF")
3042                        ]
3043                    (const_string "V2SF"))
3044
3045                /* xorps is one byte shorter.  */
3046                (eq_attr "alternative" "5")
3047                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3048                             (const_int 0))
3049                           (const_string "V4SF")
3050                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3051                             (const_int 0))
3052                           (const_string "TI")
3053                        ]
3054                        (const_string "V2DF"))
3055
3056                /* For architectures resolving dependencies on
3057                   whole SSE registers use APD move to break dependency
3058                   chains, otherwise use short move to avoid extra work.
3059
3060                   movaps encodes one byte shorter.  */
3061                (eq_attr "alternative" "6")
3062                  (cond
3063                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3064                         (const_int 0))
3065                       (const_string "V4SF")
3066                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3067                         (const_int 0))
3068                       (const_string "V2DF")
3069                    ]
3070                    (const_string "DF"))
3071                /* For architectures resolving dependencies on register
3072                   parts we may avoid extra work to zero out upper part
3073                   of register.  */
3074                (eq_attr "alternative" "7")
3075                  (if_then_else
3076                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3077                        (const_int 0))
3078                    (const_string "V1DF")
3079                    (const_string "DF"))
3080               ]
3081               (const_string "DF")))])
3082
3083 (define_insn "*movdf_integer_rex64"
3084   [(set (match_operand:DF 0 "nonimmediate_operand"
3085                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3086         (match_operand:DF 1 "general_operand"
3087                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3088   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3089    && (reload_in_progress || reload_completed
3090        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3091        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3092            && optimize_function_for_size_p (cfun)
3093            && standard_80387_constant_p (operands[1]))
3094        || GET_CODE (operands[1]) != CONST_DOUBLE
3095        || memory_operand (operands[0], DFmode))"
3096 {
3097   switch (which_alternative)
3098     {
3099     case 0:
3100     case 1:
3101       return output_387_reg_move (insn, operands);
3102
3103     case 2:
3104       return standard_80387_constant_opcode (operands[1]);
3105
3106     case 3:
3107     case 4:
3108       return "#";
3109
3110     case 5:
3111       switch (get_attr_mode (insn))
3112         {
3113         case MODE_V4SF:
3114           return "%vxorps\t%0, %d0";
3115         case MODE_V2DF:
3116           return "%vxorpd\t%0, %d0";
3117         case MODE_TI:
3118           return "%vpxor\t%0, %d0";
3119         default:
3120           gcc_unreachable ();
3121         }
3122     case 6:
3123     case 7:
3124     case 8:
3125       switch (get_attr_mode (insn))
3126         {
3127         case MODE_V4SF:
3128           return "%vmovaps\t{%1, %0|%0, %1}";
3129         case MODE_V2DF:
3130           return "%vmovapd\t{%1, %0|%0, %1}";
3131         case MODE_TI:
3132           return "%vmovdqa\t{%1, %0|%0, %1}";
3133         case MODE_DI:
3134           return "%vmovq\t{%1, %0|%0, %1}";
3135         case MODE_DF:
3136           if (TARGET_AVX)
3137             {
3138               if (REG_P (operands[0]) && REG_P (operands[1]))
3139                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3140               else
3141                 return "vmovsd\t{%1, %0|%0, %1}";
3142             }
3143           else
3144             return "movsd\t{%1, %0|%0, %1}";
3145         case MODE_V1DF:
3146           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3147         case MODE_V2SF:
3148           return "%vmovlps\t{%1, %d0|%d0, %1}";
3149         default:
3150           gcc_unreachable ();
3151         }
3152
3153     case 9:
3154     case 10:
3155     return "%vmovd\t{%1, %0|%0, %1}";
3156
3157     default:
3158       gcc_unreachable();
3159     }
3160 }
3161   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3162    (set (attr "prefix")
3163      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3164        (const_string "orig")
3165        (const_string "maybe_vex")))
3166    (set (attr "mode")
3167         (cond [(eq_attr "alternative" "0,1,2")
3168                  (const_string "DF")
3169                (eq_attr "alternative" "3,4,9,10")
3170                  (const_string "DI")
3171
3172                /* For SSE1, we have many fewer alternatives.  */
3173                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3174                  (cond [(eq_attr "alternative" "5,6")
3175                           (const_string "V4SF")
3176                        ]
3177                    (const_string "V2SF"))
3178
3179                /* xorps is one byte shorter.  */
3180                (eq_attr "alternative" "5")
3181                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3182                             (const_int 0))
3183                           (const_string "V4SF")
3184                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3185                             (const_int 0))
3186                           (const_string "TI")
3187                        ]
3188                        (const_string "V2DF"))
3189
3190                /* For architectures resolving dependencies on
3191                   whole SSE registers use APD move to break dependency
3192                   chains, otherwise use short move to avoid extra work.
3193
3194                   movaps encodes one byte shorter.  */
3195                (eq_attr "alternative" "6")
3196                  (cond
3197                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3198                         (const_int 0))
3199                       (const_string "V4SF")
3200                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3201                         (const_int 0))
3202                       (const_string "V2DF")
3203                    ]
3204                    (const_string "DF"))
3205                /* For architectures resolving dependencies on register
3206                   parts we may avoid extra work to zero out upper part
3207                   of register.  */
3208                (eq_attr "alternative" "7")
3209                  (if_then_else
3210                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3211                        (const_int 0))
3212                    (const_string "V1DF")
3213                    (const_string "DF"))
3214               ]
3215               (const_string "DF")))])
3216
3217 (define_insn "*movdf_integer"
3218   [(set (match_operand:DF 0 "nonimmediate_operand"
3219                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3220         (match_operand:DF 1 "general_operand"
3221                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3222   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3223    && optimize_function_for_speed_p (cfun)
3224    && TARGET_INTEGER_DFMODE_MOVES
3225    && (reload_in_progress || reload_completed
3226        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3227        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3228            && optimize_function_for_size_p (cfun)
3229            && standard_80387_constant_p (operands[1]))
3230        || GET_CODE (operands[1]) != CONST_DOUBLE
3231        || memory_operand (operands[0], DFmode))"
3232 {
3233   switch (which_alternative)
3234     {
3235     case 0:
3236     case 1:
3237       return output_387_reg_move (insn, operands);
3238
3239     case 2:
3240       return standard_80387_constant_opcode (operands[1]);
3241
3242     case 3:
3243     case 4:
3244       return "#";
3245
3246     case 5:
3247       switch (get_attr_mode (insn))
3248         {
3249         case MODE_V4SF:
3250           return "xorps\t%0, %0";
3251         case MODE_V2DF:
3252           return "xorpd\t%0, %0";
3253         case MODE_TI:
3254           return "pxor\t%0, %0";
3255         default:
3256           gcc_unreachable ();
3257         }
3258     case 6:
3259     case 7:
3260     case 8:
3261       switch (get_attr_mode (insn))
3262         {
3263         case MODE_V4SF:
3264           return "movaps\t{%1, %0|%0, %1}";
3265         case MODE_V2DF:
3266           return "movapd\t{%1, %0|%0, %1}";
3267         case MODE_TI:
3268           return "movdqa\t{%1, %0|%0, %1}";
3269         case MODE_DI:
3270           return "movq\t{%1, %0|%0, %1}";
3271         case MODE_DF:
3272           return "movsd\t{%1, %0|%0, %1}";
3273         case MODE_V1DF:
3274           return "movlpd\t{%1, %0|%0, %1}";
3275         case MODE_V2SF:
3276           return "movlps\t{%1, %0|%0, %1}";
3277         default:
3278           gcc_unreachable ();
3279         }
3280
3281     default:
3282       gcc_unreachable();
3283     }
3284 }
3285   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3286    (set (attr "mode")
3287         (cond [(eq_attr "alternative" "0,1,2")
3288                  (const_string "DF")
3289                (eq_attr "alternative" "3,4")
3290                  (const_string "SI")
3291
3292                /* For SSE1, we have many fewer alternatives.  */
3293                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3294                  (cond [(eq_attr "alternative" "5,6")
3295                           (const_string "V4SF")
3296                        ]
3297                    (const_string "V2SF"))
3298
3299                /* xorps is one byte shorter.  */
3300                (eq_attr "alternative" "5")
3301                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3302                             (const_int 0))
3303                           (const_string "V4SF")
3304                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3305                             (const_int 0))
3306                           (const_string "TI")
3307                        ]
3308                        (const_string "V2DF"))
3309
3310                /* For architectures resolving dependencies on
3311                   whole SSE registers use APD move to break dependency
3312                   chains, otherwise use short move to avoid extra work.
3313
3314                   movaps encodes one byte shorter.  */
3315                (eq_attr "alternative" "6")
3316                  (cond
3317                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3318                         (const_int 0))
3319                       (const_string "V4SF")
3320                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3321                         (const_int 0))
3322                       (const_string "V2DF")
3323                    ]
3324                    (const_string "DF"))
3325                /* For architectures resolving dependencies on register
3326                   parts we may avoid extra work to zero out upper part
3327                   of register.  */
3328                (eq_attr "alternative" "7")
3329                  (if_then_else
3330                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3331                        (const_int 0))
3332                    (const_string "V1DF")
3333                    (const_string "DF"))
3334               ]
3335               (const_string "DF")))])
3336
3337 (define_split
3338   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3339         (match_operand:DF 1 "general_operand" ""))]
3340   "reload_completed
3341    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3342    && ! (ANY_FP_REG_P (operands[0]) ||
3343          (GET_CODE (operands[0]) == SUBREG
3344           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3345    && ! (ANY_FP_REG_P (operands[1]) ||
3346          (GET_CODE (operands[1]) == SUBREG
3347           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3348   [(const_int 0)]
3349   "ix86_split_long_move (operands); DONE;")
3350
3351 (define_insn "*swapdf"
3352   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3353         (match_operand:DF 1 "fp_register_operand" "+f"))
3354    (set (match_dup 1)
3355         (match_dup 0))]
3356   "reload_completed || TARGET_80387"
3357 {
3358   if (STACK_TOP_P (operands[0]))
3359     return "fxch\t%1";
3360   else
3361     return "fxch\t%0";
3362 }
3363   [(set_attr "type" "fxch")
3364    (set_attr "mode" "DF")])
3365
3366 (define_expand "movxf"
3367   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3368         (match_operand:XF 1 "general_operand" ""))]
3369   ""
3370   "ix86_expand_move (XFmode, operands); DONE;")
3371
3372 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3373 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3374 ;; Pushing using integer instructions is longer except for constants
3375 ;; and direct memory references.
3376 ;; (assuming that any given constant is pushed only once, but this ought to be
3377 ;;  handled elsewhere).
3378
3379 (define_insn "*pushxf_nointeger"
3380   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3381         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3382   "optimize_function_for_size_p (cfun)"
3383 {
3384   /* This insn should be already split before reg-stack.  */
3385   gcc_unreachable ();
3386 }
3387   [(set_attr "type" "multi")
3388    (set_attr "unit" "i387,*,*")
3389    (set_attr "mode" "XF,SI,SI")])
3390
3391 (define_insn "*pushxf_integer"
3392   [(set (match_operand:XF 0 "push_operand" "=<,<")
3393         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3394   "optimize_function_for_speed_p (cfun)"
3395 {
3396   /* This insn should be already split before reg-stack.  */
3397   gcc_unreachable ();
3398 }
3399   [(set_attr "type" "multi")
3400    (set_attr "unit" "i387,*")
3401    (set_attr "mode" "XF,SI")])
3402
3403 (define_split
3404   [(set (match_operand 0 "push_operand" "")
3405         (match_operand 1 "general_operand" ""))]
3406   "reload_completed
3407    && (GET_MODE (operands[0]) == XFmode
3408        || GET_MODE (operands[0]) == DFmode)
3409    && !ANY_FP_REG_P (operands[1])"
3410   [(const_int 0)]
3411   "ix86_split_long_move (operands); DONE;")
3412
3413 (define_split
3414   [(set (match_operand:XF 0 "push_operand" "")
3415         (match_operand:XF 1 "any_fp_register_operand" ""))]
3416   ""
3417   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3418    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3419   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3420
3421 ;; Do not use integer registers when optimizing for size
3422 (define_insn "*movxf_nointeger"
3423   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3424         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3425   "optimize_function_for_size_p (cfun)
3426    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3427    && (reload_in_progress || reload_completed
3428        || standard_80387_constant_p (operands[1])
3429        || GET_CODE (operands[1]) != CONST_DOUBLE
3430        || memory_operand (operands[0], XFmode))"
3431 {
3432   switch (which_alternative)
3433     {
3434     case 0:
3435     case 1:
3436       return output_387_reg_move (insn, operands);
3437
3438     case 2:
3439       return standard_80387_constant_opcode (operands[1]);
3440
3441     case 3: case 4:
3442       return "#";
3443     default:
3444       gcc_unreachable ();
3445     }
3446 }
3447   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3448    (set_attr "mode" "XF,XF,XF,SI,SI")])
3449
3450 (define_insn "*movxf_integer"
3451   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3452         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3453   "optimize_function_for_speed_p (cfun)
3454    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3455    && (reload_in_progress || reload_completed
3456        || GET_CODE (operands[1]) != CONST_DOUBLE
3457        || memory_operand (operands[0], XFmode))"
3458 {
3459   switch (which_alternative)
3460     {
3461     case 0:
3462     case 1:
3463       return output_387_reg_move (insn, operands);
3464
3465     case 2:
3466       return standard_80387_constant_opcode (operands[1]);
3467
3468     case 3: case 4:
3469       return "#";
3470
3471     default:
3472       gcc_unreachable ();
3473     }
3474 }
3475   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3476    (set_attr "mode" "XF,XF,XF,SI,SI")])
3477
3478 (define_expand "movtf"
3479   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3480         (match_operand:TF 1 "nonimmediate_operand" ""))]
3481   "TARGET_SSE2"
3482 {
3483   ix86_expand_move (TFmode, operands);
3484   DONE;
3485 })
3486
3487 (define_insn "*movtf_internal"
3488   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3489         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3490   "TARGET_SSE2
3491    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3492 {
3493   switch (which_alternative)
3494     {
3495     case 0:
3496     case 1:
3497       if (get_attr_mode (insn) == MODE_V4SF)
3498         return "%vmovaps\t{%1, %0|%0, %1}";
3499       else
3500         return "%vmovdqa\t{%1, %0|%0, %1}";
3501     case 2:
3502       if (get_attr_mode (insn) == MODE_V4SF)
3503         return "%vxorps\t%0, %d0";
3504       else
3505         return "%vpxor\t%0, %d0";
3506     case 3:
3507     case 4:
3508         return "#";
3509     default:
3510       gcc_unreachable ();
3511     }
3512 }
3513   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3514    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3515    (set (attr "mode")
3516         (cond [(eq_attr "alternative" "0,2")
3517                  (if_then_else
3518                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3519                        (const_int 0))
3520                    (const_string "V4SF")
3521                    (const_string "TI"))
3522                (eq_attr "alternative" "1")
3523                  (if_then_else
3524                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3525                             (const_int 0))
3526                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3527                             (const_int 0)))
3528                    (const_string "V4SF")
3529                    (const_string "TI"))]
3530                (const_string "DI")))])
3531
3532 (define_insn "*pushtf_sse"
3533   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3534         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3535   "TARGET_SSE2"
3536 {
3537   /* This insn should be already split before reg-stack.  */
3538   gcc_unreachable ();
3539 }
3540   [(set_attr "type" "multi")
3541    (set_attr "unit" "sse,*,*")
3542    (set_attr "mode" "TF,SI,SI")])
3543
3544 (define_split
3545   [(set (match_operand:TF 0 "push_operand" "")
3546         (match_operand:TF 1 "general_operand" ""))]
3547   "TARGET_SSE2 && reload_completed
3548    && !SSE_REG_P (operands[1])"
3549   [(const_int 0)]
3550   "ix86_split_long_move (operands); DONE;")
3551
3552 (define_split
3553   [(set (match_operand:TF 0 "push_operand" "")
3554         (match_operand:TF 1 "any_fp_register_operand" ""))]
3555   "TARGET_SSE2"
3556   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3557    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3558   "")
3559
3560 (define_split
3561   [(set (match_operand 0 "nonimmediate_operand" "")
3562         (match_operand 1 "general_operand" ""))]
3563   "reload_completed
3564    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3565    && GET_MODE (operands[0]) == XFmode
3566    && ! (ANY_FP_REG_P (operands[0]) ||
3567          (GET_CODE (operands[0]) == SUBREG
3568           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3569    && ! (ANY_FP_REG_P (operands[1]) ||
3570          (GET_CODE (operands[1]) == SUBREG
3571           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3572   [(const_int 0)]
3573   "ix86_split_long_move (operands); DONE;")
3574
3575 (define_split
3576   [(set (match_operand 0 "register_operand" "")
3577         (match_operand 1 "memory_operand" ""))]
3578   "reload_completed
3579    && MEM_P (operands[1])
3580    && (GET_MODE (operands[0]) == TFmode
3581        || GET_MODE (operands[0]) == XFmode
3582        || GET_MODE (operands[0]) == SFmode
3583        || GET_MODE (operands[0]) == DFmode)
3584    && (operands[2] = find_constant_src (insn))"
3585   [(set (match_dup 0) (match_dup 2))]
3586 {
3587   rtx c = operands[2];
3588   rtx r = operands[0];
3589
3590   if (GET_CODE (r) == SUBREG)
3591     r = SUBREG_REG (r);
3592
3593   if (SSE_REG_P (r))
3594     {
3595       if (!standard_sse_constant_p (c))
3596         FAIL;
3597     }
3598   else if (FP_REG_P (r))
3599     {
3600       if (!standard_80387_constant_p (c))
3601         FAIL;
3602     }
3603   else if (MMX_REG_P (r))
3604     FAIL;
3605 })
3606
3607 (define_split
3608   [(set (match_operand 0 "register_operand" "")
3609         (float_extend (match_operand 1 "memory_operand" "")))]
3610   "reload_completed
3611    && MEM_P (operands[1])
3612    && (GET_MODE (operands[0]) == TFmode
3613        || GET_MODE (operands[0]) == XFmode
3614        || GET_MODE (operands[0]) == SFmode
3615        || GET_MODE (operands[0]) == DFmode)
3616    && (operands[2] = find_constant_src (insn))"
3617   [(set (match_dup 0) (match_dup 2))]
3618 {
3619   rtx c = operands[2];
3620   rtx r = operands[0];
3621
3622   if (GET_CODE (r) == SUBREG)
3623     r = SUBREG_REG (r);
3624
3625   if (SSE_REG_P (r))
3626     {
3627       if (!standard_sse_constant_p (c))
3628         FAIL;
3629     }
3630   else if (FP_REG_P (r))
3631     {
3632       if (!standard_80387_constant_p (c))
3633         FAIL;
3634     }
3635   else if (MMX_REG_P (r))
3636     FAIL;
3637 })
3638
3639 (define_insn "swapxf"
3640   [(set (match_operand:XF 0 "register_operand" "+f")
3641         (match_operand:XF 1 "register_operand" "+f"))
3642    (set (match_dup 1)
3643         (match_dup 0))]
3644   "TARGET_80387"
3645 {
3646   if (STACK_TOP_P (operands[0]))
3647     return "fxch\t%1";
3648   else
3649     return "fxch\t%0";
3650 }
3651   [(set_attr "type" "fxch")
3652    (set_attr "mode" "XF")])
3653
3654 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3655 (define_split
3656   [(set (match_operand:X87MODEF 0 "register_operand" "")
3657         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3658   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3659    && (standard_80387_constant_p (operands[1]) == 8
3660        || standard_80387_constant_p (operands[1]) == 9)"
3661   [(set (match_dup 0)(match_dup 1))
3662    (set (match_dup 0)
3663         (neg:X87MODEF (match_dup 0)))]
3664 {
3665   REAL_VALUE_TYPE r;
3666
3667   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3668   if (real_isnegzero (&r))
3669     operands[1] = CONST0_RTX (<MODE>mode);
3670   else
3671     operands[1] = CONST1_RTX (<MODE>mode);
3672 })
3673
3674 (define_split
3675   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3676         (match_operand:TF 1 "general_operand" ""))]
3677   "reload_completed
3678    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3679   [(const_int 0)]
3680   "ix86_split_long_move (operands); DONE;")
3681 \f
3682 ;; Zero extension instructions
3683
3684 (define_expand "zero_extendhisi2"
3685   [(set (match_operand:SI 0 "register_operand" "")
3686      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3687   ""
3688 {
3689   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3690     {
3691       operands[1] = force_reg (HImode, operands[1]);
3692       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3693       DONE;
3694     }
3695 })
3696
3697 (define_insn "zero_extendhisi2_and"
3698   [(set (match_operand:SI 0 "register_operand" "=r")
3699      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3700    (clobber (reg:CC FLAGS_REG))]
3701   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3702   "#"
3703   [(set_attr "type" "alu1")
3704    (set_attr "mode" "SI")])
3705
3706 (define_split
3707   [(set (match_operand:SI 0 "register_operand" "")
3708         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3709    (clobber (reg:CC FLAGS_REG))]
3710   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3711    && optimize_function_for_speed_p (cfun)"
3712   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3713               (clobber (reg:CC FLAGS_REG))])]
3714   "")
3715
3716 (define_insn "*zero_extendhisi2_movzwl"
3717   [(set (match_operand:SI 0 "register_operand" "=r")
3718      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3719   "!TARGET_ZERO_EXTEND_WITH_AND
3720    || optimize_function_for_size_p (cfun)"
3721   "movz{wl|x}\t{%1, %0|%0, %1}"
3722   [(set_attr "type" "imovx")
3723    (set_attr "mode" "SI")])
3724
3725 (define_expand "zero_extendqihi2"
3726   [(parallel
3727     [(set (match_operand:HI 0 "register_operand" "")
3728        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3729      (clobber (reg:CC FLAGS_REG))])]
3730   ""
3731   "")
3732
3733 (define_insn "*zero_extendqihi2_and"
3734   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3735      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3736    (clobber (reg:CC FLAGS_REG))]
3737   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3738   "#"
3739   [(set_attr "type" "alu1")
3740    (set_attr "mode" "HI")])
3741
3742 (define_insn "*zero_extendqihi2_movzbw_and"
3743   [(set (match_operand:HI 0 "register_operand" "=r,r")
3744      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3745    (clobber (reg:CC FLAGS_REG))]
3746   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3747   "#"
3748   [(set_attr "type" "imovx,alu1")
3749    (set_attr "mode" "HI")])
3750
3751 ; zero extend to SImode here to avoid partial register stalls
3752 (define_insn "*zero_extendqihi2_movzbl"
3753   [(set (match_operand:HI 0 "register_operand" "=r")
3754      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3755   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3756    && reload_completed"
3757   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3758   [(set_attr "type" "imovx")
3759    (set_attr "mode" "SI")])
3760
3761 ;; For the movzbw case strip only the clobber
3762 (define_split
3763   [(set (match_operand:HI 0 "register_operand" "")
3764         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3765    (clobber (reg:CC FLAGS_REG))]
3766   "reload_completed
3767    && (!TARGET_ZERO_EXTEND_WITH_AND
3768        || optimize_function_for_size_p (cfun))
3769    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3770   [(set (match_operand:HI 0 "register_operand" "")
3771         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3772
3773 ;; When source and destination does not overlap, clear destination
3774 ;; first and then do the movb
3775 (define_split
3776   [(set (match_operand:HI 0 "register_operand" "")
3777         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3778    (clobber (reg:CC FLAGS_REG))]
3779   "reload_completed
3780    && ANY_QI_REG_P (operands[0])
3781    && (TARGET_ZERO_EXTEND_WITH_AND
3782        && optimize_function_for_speed_p (cfun))
3783    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3784   [(set (match_dup 0) (const_int 0))
3785    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3786   "operands[2] = gen_lowpart (QImode, operands[0]);")
3787
3788 ;; Rest is handled by single and.
3789 (define_split
3790   [(set (match_operand:HI 0 "register_operand" "")
3791         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3792    (clobber (reg:CC FLAGS_REG))]
3793   "reload_completed
3794    && true_regnum (operands[0]) == true_regnum (operands[1])"
3795   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3796               (clobber (reg:CC FLAGS_REG))])]
3797   "")
3798
3799 (define_expand "zero_extendqisi2"
3800   [(parallel
3801     [(set (match_operand:SI 0 "register_operand" "")
3802        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3803      (clobber (reg:CC FLAGS_REG))])]
3804   ""
3805   "")
3806
3807 (define_insn "*zero_extendqisi2_and"
3808   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3809      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3810    (clobber (reg:CC FLAGS_REG))]
3811   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3812   "#"
3813   [(set_attr "type" "alu1")
3814    (set_attr "mode" "SI")])
3815
3816 (define_insn "*zero_extendqisi2_movzbw_and"
3817   [(set (match_operand:SI 0 "register_operand" "=r,r")
3818      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3819    (clobber (reg:CC FLAGS_REG))]
3820   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3821   "#"
3822   [(set_attr "type" "imovx,alu1")
3823    (set_attr "mode" "SI")])
3824
3825 (define_insn "*zero_extendqisi2_movzbw"
3826   [(set (match_operand:SI 0 "register_operand" "=r")
3827      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3828   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3829    && reload_completed"
3830   "movz{bl|x}\t{%1, %0|%0, %1}"
3831   [(set_attr "type" "imovx")
3832    (set_attr "mode" "SI")])
3833
3834 ;; For the movzbl case strip only the clobber
3835 (define_split
3836   [(set (match_operand:SI 0 "register_operand" "")
3837         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3838    (clobber (reg:CC FLAGS_REG))]
3839   "reload_completed
3840    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3841    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3842   [(set (match_dup 0)
3843         (zero_extend:SI (match_dup 1)))])
3844
3845 ;; When source and destination does not overlap, clear destination
3846 ;; first and then do the movb
3847 (define_split
3848   [(set (match_operand:SI 0 "register_operand" "")
3849         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3850    (clobber (reg:CC FLAGS_REG))]
3851   "reload_completed
3852    && ANY_QI_REG_P (operands[0])
3853    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3854    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3855    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3856   [(set (match_dup 0) (const_int 0))
3857    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3858   "operands[2] = gen_lowpart (QImode, operands[0]);")
3859
3860 ;; Rest is handled by single and.
3861 (define_split
3862   [(set (match_operand:SI 0 "register_operand" "")
3863         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3864    (clobber (reg:CC FLAGS_REG))]
3865   "reload_completed
3866    && true_regnum (operands[0]) == true_regnum (operands[1])"
3867   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3868               (clobber (reg:CC FLAGS_REG))])]
3869   "")
3870
3871 ;; %%% Kill me once multi-word ops are sane.
3872 (define_expand "zero_extendsidi2"
3873   [(set (match_operand:DI 0 "register_operand" "")
3874      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3875   ""
3876 {
3877   if (!TARGET_64BIT)
3878     {
3879       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3880       DONE;
3881     }
3882 })
3883
3884 (define_insn "zero_extendsidi2_32"
3885   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3886         (zero_extend:DI
3887          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3888    (clobber (reg:CC FLAGS_REG))]
3889   "!TARGET_64BIT"
3890   "@
3891    #
3892    #
3893    #
3894    movd\t{%1, %0|%0, %1}
3895    movd\t{%1, %0|%0, %1}
3896    %vmovd\t{%1, %0|%0, %1}
3897    %vmovd\t{%1, %0|%0, %1}"
3898   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3899    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3900    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3901
3902 (define_insn "zero_extendsidi2_rex64"
3903   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3904      (zero_extend:DI
3905        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3906   "TARGET_64BIT"
3907   "@
3908    mov\t{%k1, %k0|%k0, %k1}
3909    #
3910    movd\t{%1, %0|%0, %1}
3911    movd\t{%1, %0|%0, %1}
3912    %vmovd\t{%1, %0|%0, %1}
3913    %vmovd\t{%1, %0|%0, %1}"
3914   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3915    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3916    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3917
3918 (define_split
3919   [(set (match_operand:DI 0 "memory_operand" "")
3920      (zero_extend:DI (match_dup 0)))]
3921   "TARGET_64BIT"
3922   [(set (match_dup 4) (const_int 0))]
3923   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3924
3925 (define_split
3926   [(set (match_operand:DI 0 "register_operand" "")
3927         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3928    (clobber (reg:CC FLAGS_REG))]
3929   "!TARGET_64BIT && reload_completed
3930    && true_regnum (operands[0]) == true_regnum (operands[1])"
3931   [(set (match_dup 4) (const_int 0))]
3932   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3933
3934 (define_split
3935   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3936         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3937    (clobber (reg:CC FLAGS_REG))]
3938   "!TARGET_64BIT && reload_completed
3939    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3940   [(set (match_dup 3) (match_dup 1))
3941    (set (match_dup 4) (const_int 0))]
3942   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3943
3944 (define_insn "zero_extendhidi2"
3945   [(set (match_operand:DI 0 "register_operand" "=r")
3946      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3947   "TARGET_64BIT"
3948   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3949   [(set_attr "type" "imovx")
3950    (set_attr "mode" "DI")])
3951
3952 (define_insn "zero_extendqidi2"
3953   [(set (match_operand:DI 0 "register_operand" "=r")
3954      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3955   "TARGET_64BIT"
3956   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3957   [(set_attr "type" "imovx")
3958    (set_attr "mode" "DI")])
3959 \f
3960 ;; Sign extension instructions
3961
3962 (define_expand "extendsidi2"
3963   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3964                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3965               (clobber (reg:CC FLAGS_REG))
3966               (clobber (match_scratch:SI 2 ""))])]
3967   ""
3968 {
3969   if (TARGET_64BIT)
3970     {
3971       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3972       DONE;
3973     }
3974 })
3975
3976 (define_insn "*extendsidi2_1"
3977   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3978         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3979    (clobber (reg:CC FLAGS_REG))
3980    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3981   "!TARGET_64BIT"
3982   "#")
3983
3984 (define_insn "extendsidi2_rex64"
3985   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3986         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3987   "TARGET_64BIT"
3988   "@
3989    {cltq|cdqe}
3990    movs{lq|x}\t{%1,%0|%0, %1}"
3991   [(set_attr "type" "imovx")
3992    (set_attr "mode" "DI")
3993    (set_attr "prefix_0f" "0")
3994    (set_attr "modrm" "0,1")])
3995
3996 (define_insn "extendhidi2"
3997   [(set (match_operand:DI 0 "register_operand" "=r")
3998         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3999   "TARGET_64BIT"
4000   "movs{wq|x}\t{%1,%0|%0, %1}"
4001   [(set_attr "type" "imovx")
4002    (set_attr "mode" "DI")])
4003
4004 (define_insn "extendqidi2"
4005   [(set (match_operand:DI 0 "register_operand" "=r")
4006         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4007   "TARGET_64BIT"
4008   "movs{bq|x}\t{%1,%0|%0, %1}"
4009    [(set_attr "type" "imovx")
4010     (set_attr "mode" "DI")])
4011
4012 ;; Extend to memory case when source register does die.
4013 (define_split
4014   [(set (match_operand:DI 0 "memory_operand" "")
4015         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4016    (clobber (reg:CC FLAGS_REG))
4017    (clobber (match_operand:SI 2 "register_operand" ""))]
4018   "(reload_completed
4019     && dead_or_set_p (insn, operands[1])
4020     && !reg_mentioned_p (operands[1], operands[0]))"
4021   [(set (match_dup 3) (match_dup 1))
4022    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4023               (clobber (reg:CC FLAGS_REG))])
4024    (set (match_dup 4) (match_dup 1))]
4025   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4026
4027 ;; Extend to memory case when source register does not die.
4028 (define_split
4029   [(set (match_operand:DI 0 "memory_operand" "")
4030         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4031    (clobber (reg:CC FLAGS_REG))
4032    (clobber (match_operand:SI 2 "register_operand" ""))]
4033   "reload_completed"
4034   [(const_int 0)]
4035 {
4036   split_di (&operands[0], 1, &operands[3], &operands[4]);
4037
4038   emit_move_insn (operands[3], operands[1]);
4039
4040   /* Generate a cltd if possible and doing so it profitable.  */
4041   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4042       && true_regnum (operands[1]) == AX_REG
4043       && true_regnum (operands[2]) == DX_REG)
4044     {
4045       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4046     }
4047   else
4048     {
4049       emit_move_insn (operands[2], operands[1]);
4050       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4051     }
4052   emit_move_insn (operands[4], operands[2]);
4053   DONE;
4054 })
4055
4056 ;; Extend to register case.  Optimize case where source and destination
4057 ;; registers match and cases where we can use cltd.
4058 (define_split
4059   [(set (match_operand:DI 0 "register_operand" "")
4060         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4061    (clobber (reg:CC FLAGS_REG))
4062    (clobber (match_scratch:SI 2 ""))]
4063   "reload_completed"
4064   [(const_int 0)]
4065 {
4066   split_di (&operands[0], 1, &operands[3], &operands[4]);
4067
4068   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4069     emit_move_insn (operands[3], operands[1]);
4070
4071   /* Generate a cltd if possible and doing so it profitable.  */
4072   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4073       && true_regnum (operands[3]) == AX_REG)
4074     {
4075       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4076       DONE;
4077     }
4078
4079   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4080     emit_move_insn (operands[4], operands[1]);
4081
4082   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4083   DONE;
4084 })
4085
4086 (define_insn "extendhisi2"
4087   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4088         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4089   ""
4090 {
4091   switch (get_attr_prefix_0f (insn))
4092     {
4093     case 0:
4094       return "{cwtl|cwde}";
4095     default:
4096       return "movs{wl|x}\t{%1,%0|%0, %1}";
4097     }
4098 }
4099   [(set_attr "type" "imovx")
4100    (set_attr "mode" "SI")
4101    (set (attr "prefix_0f")
4102      ;; movsx is short decodable while cwtl is vector decoded.
4103      (if_then_else (and (eq_attr "cpu" "!k6")
4104                         (eq_attr "alternative" "0"))
4105         (const_string "0")
4106         (const_string "1")))
4107    (set (attr "modrm")
4108      (if_then_else (eq_attr "prefix_0f" "0")
4109         (const_string "0")
4110         (const_string "1")))])
4111
4112 (define_insn "*extendhisi2_zext"
4113   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4114         (zero_extend:DI
4115           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4116   "TARGET_64BIT"
4117 {
4118   switch (get_attr_prefix_0f (insn))
4119     {
4120     case 0:
4121       return "{cwtl|cwde}";
4122     default:
4123       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4124     }
4125 }
4126   [(set_attr "type" "imovx")
4127    (set_attr "mode" "SI")
4128    (set (attr "prefix_0f")
4129      ;; movsx is short decodable while cwtl is vector decoded.
4130      (if_then_else (and (eq_attr "cpu" "!k6")
4131                         (eq_attr "alternative" "0"))
4132         (const_string "0")
4133         (const_string "1")))
4134    (set (attr "modrm")
4135      (if_then_else (eq_attr "prefix_0f" "0")
4136         (const_string "0")
4137         (const_string "1")))])
4138
4139 (define_insn "extendqihi2"
4140   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4141         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4142   ""
4143 {
4144   switch (get_attr_prefix_0f (insn))
4145     {
4146     case 0:
4147       return "{cbtw|cbw}";
4148     default:
4149       return "movs{bw|x}\t{%1,%0|%0, %1}";
4150     }
4151 }
4152   [(set_attr "type" "imovx")
4153    (set_attr "mode" "HI")
4154    (set (attr "prefix_0f")
4155      ;; movsx is short decodable while cwtl is vector decoded.
4156      (if_then_else (and (eq_attr "cpu" "!k6")
4157                         (eq_attr "alternative" "0"))
4158         (const_string "0")
4159         (const_string "1")))
4160    (set (attr "modrm")
4161      (if_then_else (eq_attr "prefix_0f" "0")
4162         (const_string "0")
4163         (const_string "1")))])
4164
4165 (define_insn "extendqisi2"
4166   [(set (match_operand:SI 0 "register_operand" "=r")
4167         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4168   ""
4169   "movs{bl|x}\t{%1,%0|%0, %1}"
4170    [(set_attr "type" "imovx")
4171     (set_attr "mode" "SI")])
4172
4173 (define_insn "*extendqisi2_zext"
4174   [(set (match_operand:DI 0 "register_operand" "=r")
4175         (zero_extend:DI
4176           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4177   "TARGET_64BIT"
4178   "movs{bl|x}\t{%1,%k0|%k0, %1}"
4179    [(set_attr "type" "imovx")
4180     (set_attr "mode" "SI")])
4181 \f
4182 ;; Conversions between float and double.
4183
4184 ;; These are all no-ops in the model used for the 80387.  So just
4185 ;; emit moves.
4186
4187 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4188 (define_insn "*dummy_extendsfdf2"
4189   [(set (match_operand:DF 0 "push_operand" "=<")
4190         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4191   "0"
4192   "#")
4193
4194 (define_split
4195   [(set (match_operand:DF 0 "push_operand" "")
4196         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4197   ""
4198   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4199    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4200
4201 (define_insn "*dummy_extendsfxf2"
4202   [(set (match_operand:XF 0 "push_operand" "=<")
4203         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4204   "0"
4205   "#")
4206
4207 (define_split
4208   [(set (match_operand:XF 0 "push_operand" "")
4209         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4210   ""
4211   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4212    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4213   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4214
4215 (define_split
4216   [(set (match_operand:XF 0 "push_operand" "")
4217         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4218   ""
4219   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4220    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4221   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4222
4223 (define_expand "extendsfdf2"
4224   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4225         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4226   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4227 {
4228   /* ??? Needed for compress_float_constant since all fp constants
4229      are LEGITIMATE_CONSTANT_P.  */
4230   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4231     {
4232       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4233           && standard_80387_constant_p (operands[1]) > 0)
4234         {
4235           operands[1] = simplify_const_unary_operation
4236             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4237           emit_move_insn_1 (operands[0], operands[1]);
4238           DONE;
4239         }
4240       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4241     }
4242 })
4243
4244 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4245    cvtss2sd:
4246       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4247       cvtps2pd xmm2,xmm1
4248    We do the conversion post reload to avoid producing of 128bit spills
4249    that might lead to ICE on 32bit target.  The sequence unlikely combine
4250    anyway.  */
4251 (define_split
4252   [(set (match_operand:DF 0 "register_operand" "")
4253         (float_extend:DF
4254           (match_operand:SF 1 "nonimmediate_operand" "")))]
4255   "TARGET_USE_VECTOR_FP_CONVERTS
4256    && optimize_insn_for_speed_p ()
4257    && reload_completed && SSE_REG_P (operands[0])"
4258    [(set (match_dup 2)
4259          (float_extend:V2DF
4260            (vec_select:V2SF
4261              (match_dup 3)
4262              (parallel [(const_int 0) (const_int 1)]))))]
4263 {
4264   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4265   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4266   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4267      Try to avoid move when unpacking can be done in source.  */
4268   if (REG_P (operands[1]))
4269     {
4270       /* If it is unsafe to overwrite upper half of source, we need
4271          to move to destination and unpack there.  */
4272       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4273            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4274           && true_regnum (operands[0]) != true_regnum (operands[1]))
4275         {
4276           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4277           emit_move_insn (tmp, operands[1]);
4278         }
4279       else
4280         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4281       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4282     }
4283   else
4284     emit_insn (gen_vec_setv4sf_0 (operands[3],
4285                                   CONST0_RTX (V4SFmode), operands[1]));
4286 })
4287
4288 (define_insn "*extendsfdf2_mixed"
4289   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4290         (float_extend:DF
4291           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4292   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4293 {
4294   switch (which_alternative)
4295     {
4296     case 0:
4297     case 1:
4298       return output_387_reg_move (insn, operands);
4299
4300     case 2:
4301       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4302
4303     default:
4304       gcc_unreachable ();
4305     }
4306 }
4307   [(set_attr "type" "fmov,fmov,ssecvt")
4308    (set_attr "prefix" "orig,orig,maybe_vex")
4309    (set_attr "mode" "SF,XF,DF")])
4310
4311 (define_insn "*extendsfdf2_sse"
4312   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4313         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4314   "TARGET_SSE2 && TARGET_SSE_MATH"
4315   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4316   [(set_attr "type" "ssecvt")
4317    (set_attr "prefix" "maybe_vex")
4318    (set_attr "mode" "DF")])
4319
4320 (define_insn "*extendsfdf2_i387"
4321   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4322         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4323   "TARGET_80387"
4324   "* return output_387_reg_move (insn, operands);"
4325   [(set_attr "type" "fmov")
4326    (set_attr "mode" "SF,XF")])
4327
4328 (define_expand "extend<mode>xf2"
4329   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4330         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4331   "TARGET_80387"
4332 {
4333   /* ??? Needed for compress_float_constant since all fp constants
4334      are LEGITIMATE_CONSTANT_P.  */
4335   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4336     {
4337       if (standard_80387_constant_p (operands[1]) > 0)
4338         {
4339           operands[1] = simplify_const_unary_operation
4340             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4341           emit_move_insn_1 (operands[0], operands[1]);
4342           DONE;
4343         }
4344       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4345     }
4346 })
4347
4348 (define_insn "*extend<mode>xf2_i387"
4349   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4350         (float_extend:XF
4351           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4352   "TARGET_80387"
4353   "* return output_387_reg_move (insn, operands);"
4354   [(set_attr "type" "fmov")
4355    (set_attr "mode" "<MODE>,XF")])
4356
4357 ;; %%% This seems bad bad news.
4358 ;; This cannot output into an f-reg because there is no way to be sure
4359 ;; of truncating in that case.  Otherwise this is just like a simple move
4360 ;; insn.  So we pretend we can output to a reg in order to get better
4361 ;; register preferencing, but we really use a stack slot.
4362
4363 ;; Conversion from DFmode to SFmode.
4364
4365 (define_expand "truncdfsf2"
4366   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4367         (float_truncate:SF
4368           (match_operand:DF 1 "nonimmediate_operand" "")))]
4369   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4370 {
4371   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4372     ;
4373   else if (flag_unsafe_math_optimizations)
4374     ;
4375   else
4376     {
4377       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4378       rtx temp = assign_386_stack_local (SFmode, slot);
4379       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4380       DONE;
4381     }
4382 })
4383
4384 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4385    cvtsd2ss:
4386       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4387       cvtpd2ps xmm2,xmm1
4388    We do the conversion post reload to avoid producing of 128bit spills
4389    that might lead to ICE on 32bit target.  The sequence unlikely combine
4390    anyway.  */
4391 (define_split
4392   [(set (match_operand:SF 0 "register_operand" "")
4393         (float_truncate:SF
4394           (match_operand:DF 1 "nonimmediate_operand" "")))]
4395   "TARGET_USE_VECTOR_FP_CONVERTS
4396    && optimize_insn_for_speed_p ()
4397    && reload_completed && SSE_REG_P (operands[0])"
4398    [(set (match_dup 2)
4399          (vec_concat:V4SF
4400            (float_truncate:V2SF
4401              (match_dup 4))
4402            (match_dup 3)))]
4403 {
4404   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4405   operands[3] = CONST0_RTX (V2SFmode);
4406   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4407   /* Use movsd for loading from memory, unpcklpd for registers.
4408      Try to avoid move when unpacking can be done in source, or SSE3
4409      movddup is available.  */
4410   if (REG_P (operands[1]))
4411     {
4412       if (!TARGET_SSE3
4413           && true_regnum (operands[0]) != true_regnum (operands[1])
4414           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4415               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4416         {
4417           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4418           emit_move_insn (tmp, operands[1]);
4419           operands[1] = tmp;
4420         }
4421       else if (!TARGET_SSE3)
4422         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4423       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4424     }
4425   else
4426     emit_insn (gen_sse2_loadlpd (operands[4],
4427                                  CONST0_RTX (V2DFmode), operands[1]));
4428 })
4429
4430 (define_expand "truncdfsf2_with_temp"
4431   [(parallel [(set (match_operand:SF 0 "" "")
4432                    (float_truncate:SF (match_operand:DF 1 "" "")))
4433               (clobber (match_operand:SF 2 "" ""))])]
4434   "")
4435
4436 (define_insn "*truncdfsf_fast_mixed"
4437   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4438         (float_truncate:SF
4439           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4440   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4441 {
4442   switch (which_alternative)
4443     {
4444     case 0:
4445       return output_387_reg_move (insn, operands);
4446     case 1:
4447       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4448     default:
4449       gcc_unreachable ();
4450     }
4451 }
4452   [(set_attr "type" "fmov,ssecvt")
4453    (set_attr "prefix" "orig,maybe_vex")
4454    (set_attr "mode" "SF")])
4455
4456 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4457 ;; because nothing we do here is unsafe.
4458 (define_insn "*truncdfsf_fast_sse"
4459   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4460         (float_truncate:SF
4461           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4462   "TARGET_SSE2 && TARGET_SSE_MATH"
4463   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4464   [(set_attr "type" "ssecvt")
4465    (set_attr "prefix" "maybe_vex")
4466    (set_attr "mode" "SF")])
4467
4468 (define_insn "*truncdfsf_fast_i387"
4469   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4470         (float_truncate:SF
4471           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4472   "TARGET_80387 && flag_unsafe_math_optimizations"
4473   "* return output_387_reg_move (insn, operands);"
4474   [(set_attr "type" "fmov")
4475    (set_attr "mode" "SF")])
4476
4477 (define_insn "*truncdfsf_mixed"
4478   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4479         (float_truncate:SF
4480           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4481    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4482   "TARGET_MIX_SSE_I387"
4483 {
4484   switch (which_alternative)
4485     {
4486     case 0:
4487       return output_387_reg_move (insn, operands);
4488     case 1:
4489       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4490
4491     default:
4492       return "#";
4493     }
4494 }
4495   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4496    (set_attr "unit" "*,*,i387,i387,i387")
4497    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4498    (set_attr "mode" "SF")])
4499
4500 (define_insn "*truncdfsf_i387"
4501   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4502         (float_truncate:SF
4503           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4504    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4505   "TARGET_80387"
4506 {
4507   switch (which_alternative)
4508     {
4509     case 0:
4510       return output_387_reg_move (insn, operands);
4511
4512     default:
4513       return "#";
4514     }
4515 }
4516   [(set_attr "type" "fmov,multi,multi,multi")
4517    (set_attr "unit" "*,i387,i387,i387")
4518    (set_attr "mode" "SF")])
4519
4520 (define_insn "*truncdfsf2_i387_1"
4521   [(set (match_operand:SF 0 "memory_operand" "=m")
4522         (float_truncate:SF
4523           (match_operand:DF 1 "register_operand" "f")))]
4524   "TARGET_80387
4525    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4526    && !TARGET_MIX_SSE_I387"
4527   "* return output_387_reg_move (insn, operands);"
4528   [(set_attr "type" "fmov")
4529    (set_attr "mode" "SF")])
4530
4531 (define_split
4532   [(set (match_operand:SF 0 "register_operand" "")
4533         (float_truncate:SF
4534          (match_operand:DF 1 "fp_register_operand" "")))
4535    (clobber (match_operand 2 "" ""))]
4536   "reload_completed"
4537   [(set (match_dup 2) (match_dup 1))
4538    (set (match_dup 0) (match_dup 2))]
4539 {
4540   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4541 })
4542
4543 ;; Conversion from XFmode to {SF,DF}mode
4544
4545 (define_expand "truncxf<mode>2"
4546   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4547                    (float_truncate:MODEF
4548                      (match_operand:XF 1 "register_operand" "")))
4549               (clobber (match_dup 2))])]
4550   "TARGET_80387"
4551 {
4552   if (flag_unsafe_math_optimizations)
4553     {
4554       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4555       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4556       if (reg != operands[0])
4557         emit_move_insn (operands[0], reg);
4558       DONE;
4559     }
4560   else
4561     {
4562       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4563       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4564     }
4565 })
4566
4567 (define_insn "*truncxfsf2_mixed"
4568   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4569         (float_truncate:SF
4570           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4571    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4572   "TARGET_80387"
4573 {
4574   gcc_assert (!which_alternative);
4575   return output_387_reg_move (insn, operands);
4576 }
4577   [(set_attr "type" "fmov,multi,multi,multi")
4578    (set_attr "unit" "*,i387,i387,i387")
4579    (set_attr "mode" "SF")])
4580
4581 (define_insn "*truncxfdf2_mixed"
4582   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4583         (float_truncate:DF
4584           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4585    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4586   "TARGET_80387"
4587 {
4588   gcc_assert (!which_alternative);
4589   return output_387_reg_move (insn, operands);
4590 }
4591   [(set_attr "type" "fmov,multi,multi,multi")
4592    (set_attr "unit" "*,i387,i387,i387")
4593    (set_attr "mode" "DF")])
4594
4595 (define_insn "truncxf<mode>2_i387_noop"
4596   [(set (match_operand:MODEF 0 "register_operand" "=f")
4597         (float_truncate:MODEF
4598           (match_operand:XF 1 "register_operand" "f")))]
4599   "TARGET_80387 && flag_unsafe_math_optimizations"
4600   "* return output_387_reg_move (insn, operands);"
4601   [(set_attr "type" "fmov")
4602    (set_attr "mode" "<MODE>")])
4603
4604 (define_insn "*truncxf<mode>2_i387"
4605   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4606         (float_truncate:MODEF
4607           (match_operand:XF 1 "register_operand" "f")))]
4608   "TARGET_80387"
4609   "* return output_387_reg_move (insn, operands);"
4610   [(set_attr "type" "fmov")
4611    (set_attr "mode" "<MODE>")])
4612
4613 (define_split
4614   [(set (match_operand:MODEF 0 "register_operand" "")
4615         (float_truncate:MODEF
4616           (match_operand:XF 1 "register_operand" "")))
4617    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4618   "TARGET_80387 && reload_completed"
4619   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4620    (set (match_dup 0) (match_dup 2))]
4621   "")
4622
4623 (define_split
4624   [(set (match_operand:MODEF 0 "memory_operand" "")
4625         (float_truncate:MODEF
4626           (match_operand:XF 1 "register_operand" "")))
4627    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4628   "TARGET_80387"
4629   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4630   "")
4631 \f
4632 ;; Signed conversion to DImode.
4633
4634 (define_expand "fix_truncxfdi2"
4635   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4636                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4637               (clobber (reg:CC FLAGS_REG))])]
4638   "TARGET_80387"
4639 {
4640   if (TARGET_FISTTP)
4641    {
4642      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4643      DONE;
4644    }
4645 })
4646
4647 (define_expand "fix_trunc<mode>di2"
4648   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4649                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4650               (clobber (reg:CC FLAGS_REG))])]
4651   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4652 {
4653   if (TARGET_FISTTP
4654       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4655    {
4656      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4657      DONE;
4658    }
4659   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4660    {
4661      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4662      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4663      if (out != operands[0])
4664         emit_move_insn (operands[0], out);
4665      DONE;
4666    }
4667 })
4668
4669 ;; Signed conversion to SImode.
4670
4671 (define_expand "fix_truncxfsi2"
4672   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4673                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4674               (clobber (reg:CC FLAGS_REG))])]
4675   "TARGET_80387"
4676 {
4677   if (TARGET_FISTTP)
4678    {
4679      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4680      DONE;
4681    }
4682 })
4683
4684 (define_expand "fix_trunc<mode>si2"
4685   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4686                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4687               (clobber (reg:CC FLAGS_REG))])]
4688   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4689 {
4690   if (TARGET_FISTTP
4691       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4692    {
4693      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4694      DONE;
4695    }
4696   if (SSE_FLOAT_MODE_P (<MODE>mode))
4697    {
4698      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4699      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4700      if (out != operands[0])
4701         emit_move_insn (operands[0], out);
4702      DONE;
4703    }
4704 })
4705
4706 ;; Signed conversion to HImode.
4707
4708 (define_expand "fix_trunc<mode>hi2"
4709   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4710                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4711               (clobber (reg:CC FLAGS_REG))])]
4712   "TARGET_80387
4713    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4714 {
4715   if (TARGET_FISTTP)
4716    {
4717      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4718      DONE;
4719    }
4720 })
4721
4722 ;; Unsigned conversion to SImode.
4723
4724 (define_expand "fixuns_trunc<mode>si2"
4725   [(parallel
4726     [(set (match_operand:SI 0 "register_operand" "")
4727           (unsigned_fix:SI
4728             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4729      (use (match_dup 2))
4730      (clobber (match_scratch:<ssevecmode> 3 ""))
4731      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4732   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4733 {
4734   enum machine_mode mode = <MODE>mode;
4735   enum machine_mode vecmode = <ssevecmode>mode;
4736   REAL_VALUE_TYPE TWO31r;
4737   rtx two31;
4738
4739   if (optimize_insn_for_size_p ())
4740     FAIL;
4741
4742   real_ldexp (&TWO31r, &dconst1, 31);
4743   two31 = const_double_from_real_value (TWO31r, mode);
4744   two31 = ix86_build_const_vector (mode, true, two31);
4745   operands[2] = force_reg (vecmode, two31);
4746 })
4747
4748 (define_insn_and_split "*fixuns_trunc<mode>_1"
4749   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4750         (unsigned_fix:SI
4751           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4752    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4753    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4754    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4755   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4756    && optimize_function_for_speed_p (cfun)"
4757   "#"
4758   "&& reload_completed"
4759   [(const_int 0)]
4760 {
4761   ix86_split_convert_uns_si_sse (operands);
4762   DONE;
4763 })
4764
4765 ;; Unsigned conversion to HImode.
4766 ;; Without these patterns, we'll try the unsigned SI conversion which
4767 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4768
4769 (define_expand "fixuns_trunc<mode>hi2"
4770   [(set (match_dup 2)
4771         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4772    (set (match_operand:HI 0 "nonimmediate_operand" "")
4773         (subreg:HI (match_dup 2) 0))]
4774   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4775   "operands[2] = gen_reg_rtx (SImode);")
4776
4777 ;; When SSE is available, it is always faster to use it!
4778 (define_insn "fix_trunc<mode>di_sse"
4779   [(set (match_operand:DI 0 "register_operand" "=r,r")
4780         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4781   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4782    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4783   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4784   [(set_attr "type" "sseicvt")
4785    (set_attr "prefix" "maybe_vex")
4786    (set_attr "mode" "<MODE>")
4787    (set_attr "athlon_decode" "double,vector")
4788    (set_attr "amdfam10_decode" "double,double")])
4789
4790 (define_insn "fix_trunc<mode>si_sse"
4791   [(set (match_operand:SI 0 "register_operand" "=r,r")
4792         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4793   "SSE_FLOAT_MODE_P (<MODE>mode)
4794    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4795   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4796   [(set_attr "type" "sseicvt")
4797    (set_attr "prefix" "maybe_vex")
4798    (set_attr "mode" "<MODE>")
4799    (set_attr "athlon_decode" "double,vector")
4800    (set_attr "amdfam10_decode" "double,double")])
4801
4802 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4803 (define_peephole2
4804   [(set (match_operand:MODEF 0 "register_operand" "")
4805         (match_operand:MODEF 1 "memory_operand" ""))
4806    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4807         (fix:SSEMODEI24 (match_dup 0)))]
4808   "TARGET_SHORTEN_X87_SSE
4809    && peep2_reg_dead_p (2, operands[0])"
4810   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4811   "")
4812
4813 ;; Avoid vector decoded forms of the instruction.
4814 (define_peephole2
4815   [(match_scratch:DF 2 "Y2")
4816    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4817         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4818   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4819   [(set (match_dup 2) (match_dup 1))
4820    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4821   "")
4822
4823 (define_peephole2
4824   [(match_scratch:SF 2 "x")
4825    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4826         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4827   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4828   [(set (match_dup 2) (match_dup 1))
4829    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4830   "")
4831
4832 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4833   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4834         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4835   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4836    && TARGET_FISTTP
4837    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4838          && (TARGET_64BIT || <MODE>mode != DImode))
4839         && TARGET_SSE_MATH)
4840    && !(reload_completed || reload_in_progress)"
4841   "#"
4842   "&& 1"
4843   [(const_int 0)]
4844 {
4845   if (memory_operand (operands[0], VOIDmode))
4846     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4847   else
4848     {
4849       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4850       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4851                                                             operands[1],
4852                                                             operands[2]));
4853     }
4854   DONE;
4855 }
4856   [(set_attr "type" "fisttp")
4857    (set_attr "mode" "<MODE>")])
4858
4859 (define_insn "fix_trunc<mode>_i387_fisttp"
4860   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4861         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4862    (clobber (match_scratch:XF 2 "=&1f"))]
4863   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4864    && TARGET_FISTTP
4865    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4866          && (TARGET_64BIT || <MODE>mode != DImode))
4867         && TARGET_SSE_MATH)"
4868   "* return output_fix_trunc (insn, operands, 1);"
4869   [(set_attr "type" "fisttp")
4870    (set_attr "mode" "<MODE>")])
4871
4872 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4873   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4874         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4875    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4876    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4877   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4878    && TARGET_FISTTP
4879    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4880         && (TARGET_64BIT || <MODE>mode != DImode))
4881         && TARGET_SSE_MATH)"
4882   "#"
4883   [(set_attr "type" "fisttp")
4884    (set_attr "mode" "<MODE>")])
4885
4886 (define_split
4887   [(set (match_operand:X87MODEI 0 "register_operand" "")
4888         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4889    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4890    (clobber (match_scratch 3 ""))]
4891   "reload_completed"
4892   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4893               (clobber (match_dup 3))])
4894    (set (match_dup 0) (match_dup 2))]
4895   "")
4896
4897 (define_split
4898   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4899         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4900    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4901    (clobber (match_scratch 3 ""))]
4902   "reload_completed"
4903   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4904               (clobber (match_dup 3))])]
4905   "")
4906
4907 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4908 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4909 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4910 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4911 ;; function in i386.c.
4912 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4913   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4914         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4915    (clobber (reg:CC FLAGS_REG))]
4916   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4917    && !TARGET_FISTTP
4918    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4919          && (TARGET_64BIT || <MODE>mode != DImode))
4920    && !(reload_completed || reload_in_progress)"
4921   "#"
4922   "&& 1"
4923   [(const_int 0)]
4924 {
4925   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4926
4927   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4928   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4929   if (memory_operand (operands[0], VOIDmode))
4930     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4931                                          operands[2], operands[3]));
4932   else
4933     {
4934       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4935       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4936                                                      operands[2], operands[3],
4937                                                      operands[4]));
4938     }
4939   DONE;
4940 }
4941   [(set_attr "type" "fistp")
4942    (set_attr "i387_cw" "trunc")
4943    (set_attr "mode" "<MODE>")])
4944
4945 (define_insn "fix_truncdi_i387"
4946   [(set (match_operand:DI 0 "memory_operand" "=m")
4947         (fix:DI (match_operand 1 "register_operand" "f")))
4948    (use (match_operand:HI 2 "memory_operand" "m"))
4949    (use (match_operand:HI 3 "memory_operand" "m"))
4950    (clobber (match_scratch:XF 4 "=&1f"))]
4951   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4952    && !TARGET_FISTTP
4953    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4954   "* return output_fix_trunc (insn, operands, 0);"
4955   [(set_attr "type" "fistp")
4956    (set_attr "i387_cw" "trunc")
4957    (set_attr "mode" "DI")])
4958
4959 (define_insn "fix_truncdi_i387_with_temp"
4960   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4961         (fix:DI (match_operand 1 "register_operand" "f,f")))
4962    (use (match_operand:HI 2 "memory_operand" "m,m"))
4963    (use (match_operand:HI 3 "memory_operand" "m,m"))
4964    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4965    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4966   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4967    && !TARGET_FISTTP
4968    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4969   "#"
4970   [(set_attr "type" "fistp")
4971    (set_attr "i387_cw" "trunc")
4972    (set_attr "mode" "DI")])
4973
4974 (define_split
4975   [(set (match_operand:DI 0 "register_operand" "")
4976         (fix:DI (match_operand 1 "register_operand" "")))
4977    (use (match_operand:HI 2 "memory_operand" ""))
4978    (use (match_operand:HI 3 "memory_operand" ""))
4979    (clobber (match_operand:DI 4 "memory_operand" ""))
4980    (clobber (match_scratch 5 ""))]
4981   "reload_completed"
4982   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4983               (use (match_dup 2))
4984               (use (match_dup 3))
4985               (clobber (match_dup 5))])
4986    (set (match_dup 0) (match_dup 4))]
4987   "")
4988
4989 (define_split
4990   [(set (match_operand:DI 0 "memory_operand" "")
4991         (fix:DI (match_operand 1 "register_operand" "")))
4992    (use (match_operand:HI 2 "memory_operand" ""))
4993    (use (match_operand:HI 3 "memory_operand" ""))
4994    (clobber (match_operand:DI 4 "memory_operand" ""))
4995    (clobber (match_scratch 5 ""))]
4996   "reload_completed"
4997   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4998               (use (match_dup 2))
4999               (use (match_dup 3))
5000               (clobber (match_dup 5))])]
5001   "")
5002
5003 (define_insn "fix_trunc<mode>_i387"
5004   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5005         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5006    (use (match_operand:HI 2 "memory_operand" "m"))
5007    (use (match_operand:HI 3 "memory_operand" "m"))]
5008   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5009    && !TARGET_FISTTP
5010    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5011   "* return output_fix_trunc (insn, operands, 0);"
5012   [(set_attr "type" "fistp")
5013    (set_attr "i387_cw" "trunc")
5014    (set_attr "mode" "<MODE>")])
5015
5016 (define_insn "fix_trunc<mode>_i387_with_temp"
5017   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5018         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5019    (use (match_operand:HI 2 "memory_operand" "m,m"))
5020    (use (match_operand:HI 3 "memory_operand" "m,m"))
5021    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5022   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5023    && !TARGET_FISTTP
5024    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5025   "#"
5026   [(set_attr "type" "fistp")
5027    (set_attr "i387_cw" "trunc")
5028    (set_attr "mode" "<MODE>")])
5029
5030 (define_split
5031   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5032         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5033    (use (match_operand:HI 2 "memory_operand" ""))
5034    (use (match_operand:HI 3 "memory_operand" ""))
5035    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5036   "reload_completed"
5037   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5038               (use (match_dup 2))
5039               (use (match_dup 3))])
5040    (set (match_dup 0) (match_dup 4))]
5041   "")
5042
5043 (define_split
5044   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5045         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5046    (use (match_operand:HI 2 "memory_operand" ""))
5047    (use (match_operand:HI 3 "memory_operand" ""))
5048    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5049   "reload_completed"
5050   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5051               (use (match_dup 2))
5052               (use (match_dup 3))])]
5053   "")
5054
5055 (define_insn "x86_fnstcw_1"
5056   [(set (match_operand:HI 0 "memory_operand" "=m")
5057         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5058   "TARGET_80387"
5059   "fnstcw\t%0"
5060   [(set_attr "length" "2")
5061    (set_attr "mode" "HI")
5062    (set_attr "unit" "i387")])
5063
5064 (define_insn "x86_fldcw_1"
5065   [(set (reg:HI FPCR_REG)
5066         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5067   "TARGET_80387"
5068   "fldcw\t%0"
5069   [(set_attr "length" "2")
5070    (set_attr "mode" "HI")
5071    (set_attr "unit" "i387")
5072    (set_attr "athlon_decode" "vector")
5073    (set_attr "amdfam10_decode" "vector")])
5074 \f
5075 ;; Conversion between fixed point and floating point.
5076
5077 ;; Even though we only accept memory inputs, the backend _really_
5078 ;; wants to be able to do this between registers.
5079
5080 (define_expand "floathi<mode>2"
5081   [(set (match_operand:X87MODEF 0 "register_operand" "")
5082         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5083   "TARGET_80387
5084    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5085        || TARGET_MIX_SSE_I387)"
5086   "")
5087
5088 ;; Pre-reload splitter to add memory clobber to the pattern.
5089 (define_insn_and_split "*floathi<mode>2_1"
5090   [(set (match_operand:X87MODEF 0 "register_operand" "")
5091         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5092   "TARGET_80387
5093    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5094        || TARGET_MIX_SSE_I387)
5095    && !(reload_completed || reload_in_progress)"
5096   "#"
5097   "&& 1"
5098   [(parallel [(set (match_dup 0)
5099               (float:X87MODEF (match_dup 1)))
5100    (clobber (match_dup 2))])]
5101   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5102
5103 (define_insn "*floathi<mode>2_i387_with_temp"
5104   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5105         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5106   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5107   "TARGET_80387
5108    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5109        || TARGET_MIX_SSE_I387)"
5110   "#"
5111   [(set_attr "type" "fmov,multi")
5112    (set_attr "mode" "<MODE>")
5113    (set_attr "unit" "*,i387")
5114    (set_attr "fp_int_src" "true")])
5115
5116 (define_insn "*floathi<mode>2_i387"
5117   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5118         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5119   "TARGET_80387
5120    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5121        || TARGET_MIX_SSE_I387)"
5122   "fild%z1\t%1"
5123   [(set_attr "type" "fmov")
5124    (set_attr "mode" "<MODE>")
5125    (set_attr "fp_int_src" "true")])
5126
5127 (define_split
5128   [(set (match_operand:X87MODEF 0 "register_operand" "")
5129         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5130    (clobber (match_operand:HI 2 "memory_operand" ""))]
5131   "TARGET_80387
5132    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5133        || TARGET_MIX_SSE_I387)
5134    && reload_completed"
5135   [(set (match_dup 2) (match_dup 1))
5136    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5137   "")
5138
5139 (define_split
5140   [(set (match_operand:X87MODEF 0 "register_operand" "")
5141         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5142    (clobber (match_operand:HI 2 "memory_operand" ""))]
5143    "TARGET_80387
5144     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5145         || TARGET_MIX_SSE_I387)
5146     && reload_completed"
5147   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5148   "")
5149
5150 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5151   [(set (match_operand:X87MODEF 0 "register_operand" "")
5152         (float:X87MODEF
5153           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5154   "TARGET_80387
5155    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5156        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5157   "")
5158
5159 ;; Pre-reload splitter to add memory clobber to the pattern.
5160 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5161   [(set (match_operand:X87MODEF 0 "register_operand" "")
5162         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5163   "((TARGET_80387
5164      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5165            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5166          || TARGET_MIX_SSE_I387))
5167     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5168         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5169         && ((<SSEMODEI24:MODE>mode == SImode
5170              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5171              && optimize_function_for_speed_p (cfun)
5172              && flag_trapping_math)
5173             || !(TARGET_INTER_UNIT_CONVERSIONS
5174                  || optimize_function_for_size_p (cfun)))))
5175    && !(reload_completed || reload_in_progress)"
5176   "#"
5177   "&& 1"
5178   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5179               (clobber (match_dup 2))])]
5180 {
5181   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5182
5183   /* Avoid store forwarding (partial memory) stall penalty
5184      by passing DImode value through XMM registers.  */
5185   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5186       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5187       && optimize_function_for_speed_p (cfun))
5188     {
5189       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5190                                                             operands[1],
5191                                                             operands[2]));
5192       DONE;
5193     }
5194 })
5195
5196 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5197   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5198         (float:MODEF
5199           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5200    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5201   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5202    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5203   "#"
5204   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5205    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5206    (set_attr "unit" "*,i387,*,*,*")
5207    (set_attr "athlon_decode" "*,*,double,direct,double")
5208    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5209    (set_attr "fp_int_src" "true")])
5210
5211 (define_insn "*floatsi<mode>2_vector_mixed"
5212   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5213         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5214   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5215    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5216   "@
5217    fild%z1\t%1
5218    #"
5219   [(set_attr "type" "fmov,sseicvt")
5220    (set_attr "mode" "<MODE>,<ssevecmode>")
5221    (set_attr "unit" "i387,*")
5222    (set_attr "athlon_decode" "*,direct")
5223    (set_attr "amdfam10_decode" "*,double")
5224    (set_attr "fp_int_src" "true")])
5225
5226 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5227   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5228         (float:MODEF
5229           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5230   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5231   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5232    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5233   "#"
5234   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5235    (set_attr "mode" "<MODEF:MODE>")
5236    (set_attr "unit" "*,i387,*,*")
5237    (set_attr "athlon_decode" "*,*,double,direct")
5238    (set_attr "amdfam10_decode" "*,*,vector,double")
5239    (set_attr "fp_int_src" "true")])
5240
5241 (define_split
5242   [(set (match_operand:MODEF 0 "register_operand" "")
5243         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5244    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5245   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5246    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5247    && TARGET_INTER_UNIT_CONVERSIONS
5248    && reload_completed
5249    && (SSE_REG_P (operands[0])
5250        || (GET_CODE (operands[0]) == SUBREG
5251            && SSE_REG_P (operands[0])))"
5252   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5253   "")
5254
5255 (define_split
5256   [(set (match_operand:MODEF 0 "register_operand" "")
5257         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5258    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5259   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5260    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5261    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5262    && reload_completed
5263    && (SSE_REG_P (operands[0])
5264        || (GET_CODE (operands[0]) == SUBREG
5265            && SSE_REG_P (operands[0])))"
5266   [(set (match_dup 2) (match_dup 1))
5267    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5268   "")
5269
5270 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5271   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5272         (float:MODEF
5273           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5274   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5275    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5276    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5277   "@
5278    fild%z1\t%1
5279    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5280    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5281   [(set_attr "type" "fmov,sseicvt,sseicvt")
5282    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5283    (set_attr "mode" "<MODEF:MODE>")
5284    (set_attr "unit" "i387,*,*")
5285    (set_attr "athlon_decode" "*,double,direct")
5286    (set_attr "amdfam10_decode" "*,vector,double")
5287    (set_attr "fp_int_src" "true")])
5288
5289 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5290   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5291         (float:MODEF
5292           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5293   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5294    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5295    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5296   "@
5297    fild%z1\t%1
5298    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5299   [(set_attr "type" "fmov,sseicvt")
5300    (set_attr "prefix" "orig,maybe_vex")
5301    (set_attr "mode" "<MODEF:MODE>")
5302    (set_attr "athlon_decode" "*,direct")
5303    (set_attr "amdfam10_decode" "*,double")
5304    (set_attr "fp_int_src" "true")])
5305
5306 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5307   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5308         (float:MODEF
5309           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5310    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5311   "TARGET_SSE2 && TARGET_SSE_MATH
5312    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5313   "#"
5314   [(set_attr "type" "sseicvt")
5315    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5316    (set_attr "athlon_decode" "double,direct,double")
5317    (set_attr "amdfam10_decode" "vector,double,double")
5318    (set_attr "fp_int_src" "true")])
5319
5320 (define_insn "*floatsi<mode>2_vector_sse"
5321   [(set (match_operand:MODEF 0 "register_operand" "=x")
5322         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5323   "TARGET_SSE2 && TARGET_SSE_MATH
5324    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5325   "#"
5326   [(set_attr "type" "sseicvt")
5327    (set_attr "mode" "<MODE>")
5328    (set_attr "athlon_decode" "direct")
5329    (set_attr "amdfam10_decode" "double")
5330    (set_attr "fp_int_src" "true")])
5331
5332 (define_split
5333   [(set (match_operand:MODEF 0 "register_operand" "")
5334         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5335    (clobber (match_operand:SI 2 "memory_operand" ""))]
5336   "TARGET_SSE2 && TARGET_SSE_MATH
5337    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5338    && reload_completed
5339    && (SSE_REG_P (operands[0])
5340        || (GET_CODE (operands[0]) == SUBREG
5341            && SSE_REG_P (operands[0])))"
5342   [(const_int 0)]
5343 {
5344   rtx op1 = operands[1];
5345
5346   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5347                                      <MODE>mode, 0);
5348   if (GET_CODE (op1) == SUBREG)
5349     op1 = SUBREG_REG (op1);
5350
5351   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5352     {
5353       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5354       emit_insn (gen_sse2_loadld (operands[4],
5355                                   CONST0_RTX (V4SImode), operands[1]));
5356     }
5357   /* We can ignore possible trapping value in the
5358      high part of SSE register for non-trapping math. */
5359   else if (SSE_REG_P (op1) && !flag_trapping_math)
5360     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5361   else
5362     {
5363       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5364       emit_move_insn (operands[2], operands[1]);
5365       emit_insn (gen_sse2_loadld (operands[4],
5366                                   CONST0_RTX (V4SImode), operands[2]));
5367     }
5368   emit_insn
5369     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5370   DONE;
5371 })
5372
5373 (define_split
5374   [(set (match_operand:MODEF 0 "register_operand" "")
5375         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5376    (clobber (match_operand:SI 2 "memory_operand" ""))]
5377   "TARGET_SSE2 && TARGET_SSE_MATH
5378    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5379    && reload_completed
5380    && (SSE_REG_P (operands[0])
5381        || (GET_CODE (operands[0]) == SUBREG
5382            && SSE_REG_P (operands[0])))"
5383   [(const_int 0)]
5384 {
5385   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5386                                      <MODE>mode, 0);
5387   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5388
5389   emit_insn (gen_sse2_loadld (operands[4],
5390                               CONST0_RTX (V4SImode), operands[1]));
5391   emit_insn
5392     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5393   DONE;
5394 })
5395
5396 (define_split
5397   [(set (match_operand:MODEF 0 "register_operand" "")
5398         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5399   "TARGET_SSE2 && TARGET_SSE_MATH
5400    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5401    && reload_completed
5402    && (SSE_REG_P (operands[0])
5403        || (GET_CODE (operands[0]) == SUBREG
5404            && SSE_REG_P (operands[0])))"
5405   [(const_int 0)]
5406 {
5407   rtx op1 = operands[1];
5408
5409   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5410                                      <MODE>mode, 0);
5411   if (GET_CODE (op1) == SUBREG)
5412     op1 = SUBREG_REG (op1);
5413
5414   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5415     {
5416       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5417       emit_insn (gen_sse2_loadld (operands[4],
5418                                   CONST0_RTX (V4SImode), operands[1]));
5419     }
5420   /* We can ignore possible trapping value in the
5421      high part of SSE register for non-trapping math. */
5422   else if (SSE_REG_P (op1) && !flag_trapping_math)
5423     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5424   else
5425     gcc_unreachable ();
5426   emit_insn
5427     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5428   DONE;
5429 })
5430
5431 (define_split
5432   [(set (match_operand:MODEF 0 "register_operand" "")
5433         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5434   "TARGET_SSE2 && TARGET_SSE_MATH
5435    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5436    && reload_completed
5437    && (SSE_REG_P (operands[0])
5438        || (GET_CODE (operands[0]) == SUBREG
5439            && SSE_REG_P (operands[0])))"
5440   [(const_int 0)]
5441 {
5442   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5443                                      <MODE>mode, 0);
5444   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5445
5446   emit_insn (gen_sse2_loadld (operands[4],
5447                               CONST0_RTX (V4SImode), operands[1]));
5448   emit_insn
5449     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5450   DONE;
5451 })
5452
5453 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5454   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5455         (float:MODEF
5456           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5457   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5458   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5459    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5460   "#"
5461   [(set_attr "type" "sseicvt")
5462    (set_attr "mode" "<MODEF:MODE>")
5463    (set_attr "athlon_decode" "double,direct")
5464    (set_attr "amdfam10_decode" "vector,double")
5465    (set_attr "fp_int_src" "true")])
5466
5467 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5468   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5469         (float:MODEF
5470           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5471   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5472    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5473    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5474   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5475   [(set_attr "type" "sseicvt")
5476    (set_attr "prefix" "maybe_vex")
5477    (set_attr "mode" "<MODEF:MODE>")
5478    (set_attr "athlon_decode" "double,direct")
5479    (set_attr "amdfam10_decode" "vector,double")
5480    (set_attr "fp_int_src" "true")])
5481
5482 (define_split
5483   [(set (match_operand:MODEF 0 "register_operand" "")
5484         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5485    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5486   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5487    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5488    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5489    && reload_completed
5490    && (SSE_REG_P (operands[0])
5491        || (GET_CODE (operands[0]) == SUBREG
5492            && SSE_REG_P (operands[0])))"
5493   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5494   "")
5495
5496 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5497   [(set (match_operand:MODEF 0 "register_operand" "=x")
5498         (float:MODEF
5499           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5500   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5501    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5502    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5503   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5504   [(set_attr "type" "sseicvt")
5505    (set_attr "prefix" "maybe_vex")
5506    (set_attr "mode" "<MODEF:MODE>")
5507    (set_attr "athlon_decode" "direct")
5508    (set_attr "amdfam10_decode" "double")
5509    (set_attr "fp_int_src" "true")])
5510
5511 (define_split
5512   [(set (match_operand:MODEF 0 "register_operand" "")
5513         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5514    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5515   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5516    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5517    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5518    && reload_completed
5519    && (SSE_REG_P (operands[0])
5520        || (GET_CODE (operands[0]) == SUBREG
5521            && SSE_REG_P (operands[0])))"
5522   [(set (match_dup 2) (match_dup 1))
5523    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5524   "")
5525
5526 (define_split
5527   [(set (match_operand:MODEF 0 "register_operand" "")
5528         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5529    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5530   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5531    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5532    && reload_completed
5533    && (SSE_REG_P (operands[0])
5534        || (GET_CODE (operands[0]) == SUBREG
5535            && SSE_REG_P (operands[0])))"
5536   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5537   "")
5538
5539 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5540   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5541         (float:X87MODEF
5542           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5543   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5544   "TARGET_80387"
5545   "@
5546    fild%z1\t%1
5547    #"
5548   [(set_attr "type" "fmov,multi")
5549    (set_attr "mode" "<X87MODEF:MODE>")
5550    (set_attr "unit" "*,i387")
5551    (set_attr "fp_int_src" "true")])
5552
5553 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5554   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5555         (float:X87MODEF
5556           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5557   "TARGET_80387"
5558   "fild%z1\t%1"
5559   [(set_attr "type" "fmov")
5560    (set_attr "mode" "<X87MODEF:MODE>")
5561    (set_attr "fp_int_src" "true")])
5562
5563 (define_split
5564   [(set (match_operand:X87MODEF 0 "register_operand" "")
5565         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5566    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5567   "TARGET_80387
5568    && reload_completed
5569    && FP_REG_P (operands[0])"
5570   [(set (match_dup 2) (match_dup 1))
5571    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5572   "")
5573
5574 (define_split
5575   [(set (match_operand:X87MODEF 0 "register_operand" "")
5576         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5577    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5578   "TARGET_80387
5579    && reload_completed
5580    && FP_REG_P (operands[0])"
5581   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5582   "")
5583
5584 ;; Avoid store forwarding (partial memory) stall penalty
5585 ;; by passing DImode value through XMM registers.  */
5586
5587 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5588   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5589         (float:X87MODEF
5590           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5591    (clobber (match_scratch:V4SI 3 "=X,x"))
5592    (clobber (match_scratch:V4SI 4 "=X,x"))
5593    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5594   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5595    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5596   "#"
5597   [(set_attr "type" "multi")
5598    (set_attr "mode" "<X87MODEF:MODE>")
5599    (set_attr "unit" "i387")
5600    (set_attr "fp_int_src" "true")])
5601
5602 (define_split
5603   [(set (match_operand:X87MODEF 0 "register_operand" "")
5604         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5605    (clobber (match_scratch:V4SI 3 ""))
5606    (clobber (match_scratch:V4SI 4 ""))
5607    (clobber (match_operand:DI 2 "memory_operand" ""))]
5608   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5609    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5610    && reload_completed
5611    && FP_REG_P (operands[0])"
5612   [(set (match_dup 2) (match_dup 3))
5613    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5614 {
5615   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5616      Assemble the 64-bit DImode value in an xmm register.  */
5617   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5618                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5619   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5620                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5621   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5622
5623   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5624 })
5625
5626 (define_split
5627   [(set (match_operand:X87MODEF 0 "register_operand" "")
5628         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5629    (clobber (match_scratch:V4SI 3 ""))
5630    (clobber (match_scratch:V4SI 4 ""))
5631    (clobber (match_operand:DI 2 "memory_operand" ""))]
5632   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5633    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5634    && reload_completed
5635    && FP_REG_P (operands[0])"
5636   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5637   "")
5638
5639 ;; Avoid store forwarding (partial memory) stall penalty by extending
5640 ;; SImode value to DImode through XMM register instead of pushing two
5641 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5642 ;; targets benefit from this optimization. Also note that fild
5643 ;; loads from memory only.
5644
5645 (define_insn "*floatunssi<mode>2_1"
5646   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5647         (unsigned_float:X87MODEF
5648           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5649    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5650    (clobber (match_scratch:SI 3 "=X,x"))]
5651   "!TARGET_64BIT
5652    && TARGET_80387 && TARGET_SSE"
5653   "#"
5654   [(set_attr "type" "multi")
5655    (set_attr "mode" "<MODE>")])
5656
5657 (define_split
5658   [(set (match_operand:X87MODEF 0 "register_operand" "")
5659         (unsigned_float:X87MODEF
5660           (match_operand:SI 1 "register_operand" "")))
5661    (clobber (match_operand:DI 2 "memory_operand" ""))
5662    (clobber (match_scratch:SI 3 ""))]
5663   "!TARGET_64BIT
5664    && TARGET_80387 && TARGET_SSE
5665    && reload_completed"
5666   [(set (match_dup 2) (match_dup 1))
5667    (set (match_dup 0)
5668         (float:X87MODEF (match_dup 2)))]
5669   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5670
5671 (define_split
5672   [(set (match_operand:X87MODEF 0 "register_operand" "")
5673         (unsigned_float:X87MODEF
5674           (match_operand:SI 1 "memory_operand" "")))
5675    (clobber (match_operand:DI 2 "memory_operand" ""))
5676    (clobber (match_scratch:SI 3 ""))]
5677   "!TARGET_64BIT
5678    && TARGET_80387 && TARGET_SSE
5679    && reload_completed"
5680   [(set (match_dup 2) (match_dup 3))
5681    (set (match_dup 0)
5682         (float:X87MODEF (match_dup 2)))]
5683 {
5684   emit_move_insn (operands[3], operands[1]);
5685   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5686 })
5687
5688 (define_expand "floatunssi<mode>2"
5689   [(parallel
5690      [(set (match_operand:X87MODEF 0 "register_operand" "")
5691            (unsigned_float:X87MODEF
5692              (match_operand:SI 1 "nonimmediate_operand" "")))
5693       (clobber (match_dup 2))
5694       (clobber (match_scratch:SI 3 ""))])]
5695   "!TARGET_64BIT
5696    && ((TARGET_80387 && TARGET_SSE)
5697        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5698 {
5699   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5700     {
5701       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5702       DONE;
5703     }
5704   else
5705     {
5706       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5707       operands[2] = assign_386_stack_local (DImode, slot);
5708     }
5709 })
5710
5711 (define_expand "floatunsdisf2"
5712   [(use (match_operand:SF 0 "register_operand" ""))
5713    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5714   "TARGET_64BIT && TARGET_SSE_MATH"
5715   "x86_emit_floatuns (operands); DONE;")
5716
5717 (define_expand "floatunsdidf2"
5718   [(use (match_operand:DF 0 "register_operand" ""))
5719    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5720   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5721    && TARGET_SSE2 && TARGET_SSE_MATH"
5722 {
5723   if (TARGET_64BIT)
5724     x86_emit_floatuns (operands);
5725   else
5726     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5727   DONE;
5728 })
5729 \f
5730 ;; Add instructions
5731
5732 ;; %%% splits for addditi3
5733
5734 (define_expand "addti3"
5735   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5736         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5737                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5738   "TARGET_64BIT"
5739   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5740
5741 (define_insn "*addti3_1"
5742   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5743         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5744                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5745    (clobber (reg:CC FLAGS_REG))]
5746   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5747   "#")
5748
5749 (define_split
5750   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5751         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5752                  (match_operand:TI 2 "x86_64_general_operand" "")))
5753    (clobber (reg:CC FLAGS_REG))]
5754   "TARGET_64BIT && reload_completed"
5755   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5756                                           UNSPEC_ADD_CARRY))
5757               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5758    (parallel [(set (match_dup 3)
5759                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5760                                      (match_dup 4))
5761                             (match_dup 5)))
5762               (clobber (reg:CC FLAGS_REG))])]
5763   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5764
5765 ;; %%% splits for addsidi3
5766 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5767 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5768 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5769
5770 (define_expand "adddi3"
5771   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5772         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5773                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5774   ""
5775   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5776
5777 (define_insn "*adddi3_1"
5778   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5779         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5780                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5781    (clobber (reg:CC FLAGS_REG))]
5782   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5783   "#")
5784
5785 (define_split
5786   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5787         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5788                  (match_operand:DI 2 "general_operand" "")))
5789    (clobber (reg:CC FLAGS_REG))]
5790   "!TARGET_64BIT && reload_completed"
5791   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5792                                           UNSPEC_ADD_CARRY))
5793               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5794    (parallel [(set (match_dup 3)
5795                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5796                                      (match_dup 4))
5797                             (match_dup 5)))
5798               (clobber (reg:CC FLAGS_REG))])]
5799   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5800
5801 (define_insn "adddi3_carry_rex64"
5802   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5803           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5804                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5805                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5806    (clobber (reg:CC FLAGS_REG))]
5807   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5808   "adc{q}\t{%2, %0|%0, %2}"
5809   [(set_attr "type" "alu")
5810    (set_attr "pent_pair" "pu")
5811    (set_attr "mode" "DI")])
5812
5813 (define_insn "*adddi3_cc_rex64"
5814   [(set (reg:CC FLAGS_REG)
5815         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5816                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5817                    UNSPEC_ADD_CARRY))
5818    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5819         (plus:DI (match_dup 1) (match_dup 2)))]
5820   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5821   "add{q}\t{%2, %0|%0, %2}"
5822   [(set_attr "type" "alu")
5823    (set_attr "mode" "DI")])
5824
5825 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5826   [(set (reg:CCC FLAGS_REG)
5827         (compare:CCC
5828             (plusminus:SWI
5829                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5830                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5831             (match_dup 1)))
5832    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5833         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5834   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5835   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5836   [(set_attr "type" "alu")
5837    (set_attr "mode" "<MODE>")])
5838
5839 (define_insn "*add<mode>3_cconly_overflow"
5840   [(set (reg:CCC FLAGS_REG)
5841         (compare:CCC
5842                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5843                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5844                 (match_dup 1)))
5845    (clobber (match_scratch:SWI 0 "=<r>"))]
5846   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5847   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5848   [(set_attr "type" "alu")
5849    (set_attr "mode" "<MODE>")])
5850
5851 (define_insn "*sub<mode>3_cconly_overflow"
5852   [(set (reg:CCC FLAGS_REG)
5853         (compare:CCC
5854              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5855                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5856              (match_dup 0)))]
5857   ""
5858   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5859   [(set_attr "type" "icmp")
5860    (set_attr "mode" "<MODE>")])
5861
5862 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5863   [(set (reg:CCC FLAGS_REG)
5864         (compare:CCC
5865             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5866                           (match_operand:SI 2 "general_operand" "g"))
5867             (match_dup 1)))
5868    (set (match_operand:DI 0 "register_operand" "=r")
5869         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5870   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5871   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5872   [(set_attr "type" "alu")
5873    (set_attr "mode" "SI")])
5874
5875 (define_insn "addqi3_carry"
5876   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5877           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5878                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5879                    (match_operand:QI 2 "general_operand" "qn,qm")))
5880    (clobber (reg:CC FLAGS_REG))]
5881   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5882   "adc{b}\t{%2, %0|%0, %2}"
5883   [(set_attr "type" "alu")
5884    (set_attr "pent_pair" "pu")
5885    (set_attr "mode" "QI")])
5886
5887 (define_insn "addhi3_carry"
5888   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5889           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5890                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5891                    (match_operand:HI 2 "general_operand" "rn,rm")))
5892    (clobber (reg:CC FLAGS_REG))]
5893   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5894   "adc{w}\t{%2, %0|%0, %2}"
5895   [(set_attr "type" "alu")
5896    (set_attr "pent_pair" "pu")
5897    (set_attr "mode" "HI")])
5898
5899 (define_insn "addsi3_carry"
5900   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5901           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5902                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5903                    (match_operand:SI 2 "general_operand" "ri,rm")))
5904    (clobber (reg:CC FLAGS_REG))]
5905   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5906   "adc{l}\t{%2, %0|%0, %2}"
5907   [(set_attr "type" "alu")
5908    (set_attr "pent_pair" "pu")
5909    (set_attr "mode" "SI")])
5910
5911 (define_insn "*addsi3_carry_zext"
5912   [(set (match_operand:DI 0 "register_operand" "=r")
5913           (zero_extend:DI
5914             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5915                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5916                      (match_operand:SI 2 "general_operand" "g"))))
5917    (clobber (reg:CC FLAGS_REG))]
5918   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5919   "adc{l}\t{%2, %k0|%k0, %2}"
5920   [(set_attr "type" "alu")
5921    (set_attr "pent_pair" "pu")
5922    (set_attr "mode" "SI")])
5923
5924 (define_insn "*addsi3_cc"
5925   [(set (reg:CC FLAGS_REG)
5926         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5927                     (match_operand:SI 2 "general_operand" "ri,rm")]
5928                    UNSPEC_ADD_CARRY))
5929    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5930         (plus:SI (match_dup 1) (match_dup 2)))]
5931   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5932   "add{l}\t{%2, %0|%0, %2}"
5933   [(set_attr "type" "alu")
5934    (set_attr "mode" "SI")])
5935
5936 (define_insn "addqi3_cc"
5937   [(set (reg:CC FLAGS_REG)
5938         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5939                     (match_operand:QI 2 "general_operand" "qn,qm")]
5940                    UNSPEC_ADD_CARRY))
5941    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5942         (plus:QI (match_dup 1) (match_dup 2)))]
5943   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5944   "add{b}\t{%2, %0|%0, %2}"
5945   [(set_attr "type" "alu")
5946    (set_attr "mode" "QI")])
5947
5948 (define_expand "addsi3"
5949   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5950         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5951                  (match_operand:SI 2 "general_operand" "")))]
5952   ""
5953   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5954
5955 (define_insn "*lea_1"
5956   [(set (match_operand:SI 0 "register_operand" "=r")
5957         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5958   "!TARGET_64BIT"
5959   "lea{l}\t{%a1, %0|%0, %a1}"
5960   [(set_attr "type" "lea")
5961    (set_attr "mode" "SI")])
5962
5963 (define_insn "*lea_1_rex64"
5964   [(set (match_operand:SI 0 "register_operand" "=r")
5965         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5966   "TARGET_64BIT"
5967   "lea{l}\t{%a1, %0|%0, %a1}"
5968   [(set_attr "type" "lea")
5969    (set_attr "mode" "SI")])
5970
5971 (define_insn "*lea_1_zext"
5972   [(set (match_operand:DI 0 "register_operand" "=r")
5973         (zero_extend:DI
5974          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5975   "TARGET_64BIT"
5976   "lea{l}\t{%a1, %k0|%k0, %a1}"
5977   [(set_attr "type" "lea")
5978    (set_attr "mode" "SI")])
5979
5980 (define_insn "*lea_2_rex64"
5981   [(set (match_operand:DI 0 "register_operand" "=r")
5982         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5983   "TARGET_64BIT"
5984   "lea{q}\t{%a1, %0|%0, %a1}"
5985   [(set_attr "type" "lea")
5986    (set_attr "mode" "DI")])
5987
5988 ;; The lea patterns for non-Pmodes needs to be matched by several
5989 ;; insns converted to real lea by splitters.
5990
5991 (define_insn_and_split "*lea_general_1"
5992   [(set (match_operand 0 "register_operand" "=r")
5993         (plus (plus (match_operand 1 "index_register_operand" "l")
5994                     (match_operand 2 "register_operand" "r"))
5995               (match_operand 3 "immediate_operand" "i")))]
5996   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5997     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5998    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5999    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6000    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6001    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6002        || GET_MODE (operands[3]) == VOIDmode)"
6003   "#"
6004   "&& reload_completed"
6005   [(const_int 0)]
6006 {
6007   rtx pat;
6008   operands[0] = gen_lowpart (SImode, operands[0]);
6009   operands[1] = gen_lowpart (Pmode, operands[1]);
6010   operands[2] = gen_lowpart (Pmode, operands[2]);
6011   operands[3] = gen_lowpart (Pmode, operands[3]);
6012   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6013                       operands[3]);
6014   if (Pmode != SImode)
6015     pat = gen_rtx_SUBREG (SImode, pat, 0);
6016   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6017   DONE;
6018 }
6019   [(set_attr "type" "lea")
6020    (set_attr "mode" "SI")])
6021
6022 (define_insn_and_split "*lea_general_1_zext"
6023   [(set (match_operand:DI 0 "register_operand" "=r")
6024         (zero_extend:DI
6025           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6026                             (match_operand:SI 2 "register_operand" "r"))
6027                    (match_operand:SI 3 "immediate_operand" "i"))))]
6028   "TARGET_64BIT"
6029   "#"
6030   "&& reload_completed"
6031   [(set (match_dup 0)
6032         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6033                                                      (match_dup 2))
6034                                             (match_dup 3)) 0)))]
6035 {
6036   operands[1] = gen_lowpart (Pmode, operands[1]);
6037   operands[2] = gen_lowpart (Pmode, operands[2]);
6038   operands[3] = gen_lowpart (Pmode, operands[3]);
6039 }
6040   [(set_attr "type" "lea")
6041    (set_attr "mode" "SI")])
6042
6043 (define_insn_and_split "*lea_general_2"
6044   [(set (match_operand 0 "register_operand" "=r")
6045         (plus (mult (match_operand 1 "index_register_operand" "l")
6046                     (match_operand 2 "const248_operand" "i"))
6047               (match_operand 3 "nonmemory_operand" "ri")))]
6048   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6049     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6050    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6051    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6052    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6053        || GET_MODE (operands[3]) == VOIDmode)"
6054   "#"
6055   "&& reload_completed"
6056   [(const_int 0)]
6057 {
6058   rtx pat;
6059   operands[0] = gen_lowpart (SImode, operands[0]);
6060   operands[1] = gen_lowpart (Pmode, operands[1]);
6061   operands[3] = gen_lowpart (Pmode, operands[3]);
6062   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6063                       operands[3]);
6064   if (Pmode != SImode)
6065     pat = gen_rtx_SUBREG (SImode, pat, 0);
6066   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6067   DONE;
6068 }
6069   [(set_attr "type" "lea")
6070    (set_attr "mode" "SI")])
6071
6072 (define_insn_and_split "*lea_general_2_zext"
6073   [(set (match_operand:DI 0 "register_operand" "=r")
6074         (zero_extend:DI
6075           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6076                             (match_operand:SI 2 "const248_operand" "n"))
6077                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6078   "TARGET_64BIT"
6079   "#"
6080   "&& reload_completed"
6081   [(set (match_dup 0)
6082         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6083                                                      (match_dup 2))
6084                                             (match_dup 3)) 0)))]
6085 {
6086   operands[1] = gen_lowpart (Pmode, operands[1]);
6087   operands[3] = gen_lowpart (Pmode, operands[3]);
6088 }
6089   [(set_attr "type" "lea")
6090    (set_attr "mode" "SI")])
6091
6092 (define_insn_and_split "*lea_general_3"
6093   [(set (match_operand 0 "register_operand" "=r")
6094         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6095                           (match_operand 2 "const248_operand" "i"))
6096                     (match_operand 3 "register_operand" "r"))
6097               (match_operand 4 "immediate_operand" "i")))]
6098   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6099     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6100    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6101    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6102    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6103   "#"
6104   "&& reload_completed"
6105   [(const_int 0)]
6106 {
6107   rtx pat;
6108   operands[0] = gen_lowpart (SImode, operands[0]);
6109   operands[1] = gen_lowpart (Pmode, operands[1]);
6110   operands[3] = gen_lowpart (Pmode, operands[3]);
6111   operands[4] = gen_lowpart (Pmode, operands[4]);
6112   pat = gen_rtx_PLUS (Pmode,
6113                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6114                                                          operands[2]),
6115                                     operands[3]),
6116                       operands[4]);
6117   if (Pmode != SImode)
6118     pat = gen_rtx_SUBREG (SImode, pat, 0);
6119   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6120   DONE;
6121 }
6122   [(set_attr "type" "lea")
6123    (set_attr "mode" "SI")])
6124
6125 (define_insn_and_split "*lea_general_3_zext"
6126   [(set (match_operand:DI 0 "register_operand" "=r")
6127         (zero_extend:DI
6128           (plus:SI (plus:SI (mult:SI
6129                               (match_operand:SI 1 "index_register_operand" "l")
6130                               (match_operand:SI 2 "const248_operand" "n"))
6131                             (match_operand:SI 3 "register_operand" "r"))
6132                    (match_operand:SI 4 "immediate_operand" "i"))))]
6133   "TARGET_64BIT"
6134   "#"
6135   "&& reload_completed"
6136   [(set (match_dup 0)
6137         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6138                                                               (match_dup 2))
6139                                                      (match_dup 3))
6140                                             (match_dup 4)) 0)))]
6141 {
6142   operands[1] = gen_lowpart (Pmode, operands[1]);
6143   operands[3] = gen_lowpart (Pmode, operands[3]);
6144   operands[4] = gen_lowpart (Pmode, operands[4]);
6145 }
6146   [(set_attr "type" "lea")
6147    (set_attr "mode" "SI")])
6148
6149 (define_insn "*adddi_1_rex64"
6150   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6151         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6152                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6153    (clobber (reg:CC FLAGS_REG))]
6154   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6155 {
6156   switch (get_attr_type (insn))
6157     {
6158     case TYPE_LEA:
6159       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6160       return "lea{q}\t{%a2, %0|%0, %a2}";
6161
6162     case TYPE_INCDEC:
6163       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6164       if (operands[2] == const1_rtx)
6165         return "inc{q}\t%0";
6166       else
6167         {
6168           gcc_assert (operands[2] == constm1_rtx);
6169           return "dec{q}\t%0";
6170         }
6171
6172     default:
6173       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6174
6175       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6176          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6177       if (CONST_INT_P (operands[2])
6178           /* Avoid overflows.  */
6179           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6180           && (INTVAL (operands[2]) == 128
6181               || (INTVAL (operands[2]) < 0
6182                   && INTVAL (operands[2]) != -128)))
6183         {
6184           operands[2] = GEN_INT (-INTVAL (operands[2]));
6185           return "sub{q}\t{%2, %0|%0, %2}";
6186         }
6187       return "add{q}\t{%2, %0|%0, %2}";
6188     }
6189 }
6190   [(set (attr "type")
6191      (cond [(eq_attr "alternative" "2")
6192               (const_string "lea")
6193             ; Current assemblers are broken and do not allow @GOTOFF in
6194             ; ought but a memory context.
6195             (match_operand:DI 2 "pic_symbolic_operand" "")
6196               (const_string "lea")
6197             (match_operand:DI 2 "incdec_operand" "")
6198               (const_string "incdec")
6199            ]
6200            (const_string "alu")))
6201    (set_attr "mode" "DI")])
6202
6203 ;; Convert lea to the lea pattern to avoid flags dependency.
6204 (define_split
6205   [(set (match_operand:DI 0 "register_operand" "")
6206         (plus:DI (match_operand:DI 1 "register_operand" "")
6207                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6208    (clobber (reg:CC FLAGS_REG))]
6209   "TARGET_64BIT && reload_completed
6210    && true_regnum (operands[0]) != true_regnum (operands[1])"
6211   [(set (match_dup 0)
6212         (plus:DI (match_dup 1)
6213                  (match_dup 2)))]
6214   "")
6215
6216 (define_insn "*adddi_2_rex64"
6217   [(set (reg FLAGS_REG)
6218         (compare
6219           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6220                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6221           (const_int 0)))
6222    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6223         (plus:DI (match_dup 1) (match_dup 2)))]
6224   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6225    && ix86_binary_operator_ok (PLUS, DImode, operands)
6226    /* Current assemblers are broken and do not allow @GOTOFF in
6227       ought but a memory context.  */
6228    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6229 {
6230   switch (get_attr_type (insn))
6231     {
6232     case TYPE_INCDEC:
6233       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6234       if (operands[2] == const1_rtx)
6235         return "inc{q}\t%0";
6236       else
6237         {
6238           gcc_assert (operands[2] == constm1_rtx);
6239           return "dec{q}\t%0";
6240         }
6241
6242     default:
6243       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6244       /* ???? We ought to handle there the 32bit case too
6245          - do we need new constraint?  */
6246       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6247          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6248       if (CONST_INT_P (operands[2])
6249           /* Avoid overflows.  */
6250           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6251           && (INTVAL (operands[2]) == 128
6252               || (INTVAL (operands[2]) < 0
6253                   && INTVAL (operands[2]) != -128)))
6254         {
6255           operands[2] = GEN_INT (-INTVAL (operands[2]));
6256           return "sub{q}\t{%2, %0|%0, %2}";
6257         }
6258       return "add{q}\t{%2, %0|%0, %2}";
6259     }
6260 }
6261   [(set (attr "type")
6262      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6263         (const_string "incdec")
6264         (const_string "alu")))
6265    (set_attr "mode" "DI")])
6266
6267 (define_insn "*adddi_3_rex64"
6268   [(set (reg FLAGS_REG)
6269         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6270                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6271    (clobber (match_scratch:DI 0 "=r"))]
6272   "TARGET_64BIT
6273    && ix86_match_ccmode (insn, CCZmode)
6274    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6275    /* Current assemblers are broken and do not allow @GOTOFF in
6276       ought but a memory context.  */
6277    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6278 {
6279   switch (get_attr_type (insn))
6280     {
6281     case TYPE_INCDEC:
6282       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6283       if (operands[2] == const1_rtx)
6284         return "inc{q}\t%0";
6285       else
6286         {
6287           gcc_assert (operands[2] == constm1_rtx);
6288           return "dec{q}\t%0";
6289         }
6290
6291     default:
6292       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6293       /* ???? We ought to handle there the 32bit case too
6294          - do we need new constraint?  */
6295       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6296          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6297       if (CONST_INT_P (operands[2])
6298           /* Avoid overflows.  */
6299           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6300           && (INTVAL (operands[2]) == 128
6301               || (INTVAL (operands[2]) < 0
6302                   && INTVAL (operands[2]) != -128)))
6303         {
6304           operands[2] = GEN_INT (-INTVAL (operands[2]));
6305           return "sub{q}\t{%2, %0|%0, %2}";
6306         }
6307       return "add{q}\t{%2, %0|%0, %2}";
6308     }
6309 }
6310   [(set (attr "type")
6311      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6312         (const_string "incdec")
6313         (const_string "alu")))
6314    (set_attr "mode" "DI")])
6315
6316 ; For comparisons against 1, -1 and 128, we may generate better code
6317 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6318 ; is matched then.  We can't accept general immediate, because for
6319 ; case of overflows,  the result is messed up.
6320 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6321 ; when negated.
6322 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6323 ; only for comparisons not depending on it.
6324 (define_insn "*adddi_4_rex64"
6325   [(set (reg FLAGS_REG)
6326         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6327                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6328    (clobber (match_scratch:DI 0 "=rm"))]
6329   "TARGET_64BIT
6330    &&  ix86_match_ccmode (insn, CCGCmode)"
6331 {
6332   switch (get_attr_type (insn))
6333     {
6334     case TYPE_INCDEC:
6335       if (operands[2] == constm1_rtx)
6336         return "inc{q}\t%0";
6337       else
6338         {
6339           gcc_assert (operands[2] == const1_rtx);
6340           return "dec{q}\t%0";
6341         }
6342
6343     default:
6344       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6345       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6346          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6347       if ((INTVAL (operands[2]) == -128
6348            || (INTVAL (operands[2]) > 0
6349                && INTVAL (operands[2]) != 128))
6350           /* Avoid overflows.  */
6351           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6352         return "sub{q}\t{%2, %0|%0, %2}";
6353       operands[2] = GEN_INT (-INTVAL (operands[2]));
6354       return "add{q}\t{%2, %0|%0, %2}";
6355     }
6356 }
6357   [(set (attr "type")
6358      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6359         (const_string "incdec")
6360         (const_string "alu")))
6361    (set_attr "mode" "DI")])
6362
6363 (define_insn "*adddi_5_rex64"
6364   [(set (reg FLAGS_REG)
6365         (compare
6366           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6367                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6368           (const_int 0)))
6369    (clobber (match_scratch:DI 0 "=r"))]
6370   "TARGET_64BIT
6371    && ix86_match_ccmode (insn, CCGOCmode)
6372    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6373    /* Current assemblers are broken and do not allow @GOTOFF in
6374       ought but a memory context.  */
6375    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6376 {
6377   switch (get_attr_type (insn))
6378     {
6379     case TYPE_INCDEC:
6380       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6381       if (operands[2] == const1_rtx)
6382         return "inc{q}\t%0";
6383       else
6384         {
6385           gcc_assert (operands[2] == constm1_rtx);
6386           return "dec{q}\t%0";
6387         }
6388
6389     default:
6390       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6391       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6392          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6393       if (CONST_INT_P (operands[2])
6394           /* Avoid overflows.  */
6395           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6396           && (INTVAL (operands[2]) == 128
6397               || (INTVAL (operands[2]) < 0
6398                   && INTVAL (operands[2]) != -128)))
6399         {
6400           operands[2] = GEN_INT (-INTVAL (operands[2]));
6401           return "sub{q}\t{%2, %0|%0, %2}";
6402         }
6403       return "add{q}\t{%2, %0|%0, %2}";
6404     }
6405 }
6406   [(set (attr "type")
6407      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6408         (const_string "incdec")
6409         (const_string "alu")))
6410    (set_attr "mode" "DI")])
6411
6412
6413 (define_insn "*addsi_1"
6414   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6415         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6416                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6417    (clobber (reg:CC FLAGS_REG))]
6418   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6419 {
6420   switch (get_attr_type (insn))
6421     {
6422     case TYPE_LEA:
6423       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6424       return "lea{l}\t{%a2, %0|%0, %a2}";
6425
6426     case TYPE_INCDEC:
6427       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6428       if (operands[2] == const1_rtx)
6429         return "inc{l}\t%0";
6430       else
6431         {
6432           gcc_assert (operands[2] == constm1_rtx);
6433           return "dec{l}\t%0";
6434         }
6435
6436     default:
6437       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6438
6439       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6440          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6441       if (CONST_INT_P (operands[2])
6442           && (INTVAL (operands[2]) == 128
6443               || (INTVAL (operands[2]) < 0
6444                   && INTVAL (operands[2]) != -128)))
6445         {
6446           operands[2] = GEN_INT (-INTVAL (operands[2]));
6447           return "sub{l}\t{%2, %0|%0, %2}";
6448         }
6449       return "add{l}\t{%2, %0|%0, %2}";
6450     }
6451 }
6452   [(set (attr "type")
6453      (cond [(eq_attr "alternative" "2")
6454               (const_string "lea")
6455             ; Current assemblers are broken and do not allow @GOTOFF in
6456             ; ought but a memory context.
6457             (match_operand:SI 2 "pic_symbolic_operand" "")
6458               (const_string "lea")
6459             (match_operand:SI 2 "incdec_operand" "")
6460               (const_string "incdec")
6461            ]
6462            (const_string "alu")))
6463    (set_attr "mode" "SI")])
6464
6465 ;; Convert lea to the lea pattern to avoid flags dependency.
6466 (define_split
6467   [(set (match_operand 0 "register_operand" "")
6468         (plus (match_operand 1 "register_operand" "")
6469               (match_operand 2 "nonmemory_operand" "")))
6470    (clobber (reg:CC FLAGS_REG))]
6471   "reload_completed
6472    && true_regnum (operands[0]) != true_regnum (operands[1])"
6473   [(const_int 0)]
6474 {
6475   rtx pat;
6476   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6477      may confuse gen_lowpart.  */
6478   if (GET_MODE (operands[0]) != Pmode)
6479     {
6480       operands[1] = gen_lowpart (Pmode, operands[1]);
6481       operands[2] = gen_lowpart (Pmode, operands[2]);
6482     }
6483   operands[0] = gen_lowpart (SImode, operands[0]);
6484   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6485   if (Pmode != SImode)
6486     pat = gen_rtx_SUBREG (SImode, pat, 0);
6487   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6488   DONE;
6489 })
6490
6491 ;; It may seem that nonimmediate operand is proper one for operand 1.
6492 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6493 ;; we take care in ix86_binary_operator_ok to not allow two memory
6494 ;; operands so proper swapping will be done in reload.  This allow
6495 ;; patterns constructed from addsi_1 to match.
6496 (define_insn "addsi_1_zext"
6497   [(set (match_operand:DI 0 "register_operand" "=r,r")
6498         (zero_extend:DI
6499           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6500                    (match_operand:SI 2 "general_operand" "g,li"))))
6501    (clobber (reg:CC FLAGS_REG))]
6502   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6503 {
6504   switch (get_attr_type (insn))
6505     {
6506     case TYPE_LEA:
6507       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6508       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6509
6510     case TYPE_INCDEC:
6511       if (operands[2] == const1_rtx)
6512         return "inc{l}\t%k0";
6513       else
6514         {
6515           gcc_assert (operands[2] == constm1_rtx);
6516           return "dec{l}\t%k0";
6517         }
6518
6519     default:
6520       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6521          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6522       if (CONST_INT_P (operands[2])
6523           && (INTVAL (operands[2]) == 128
6524               || (INTVAL (operands[2]) < 0
6525                   && INTVAL (operands[2]) != -128)))
6526         {
6527           operands[2] = GEN_INT (-INTVAL (operands[2]));
6528           return "sub{l}\t{%2, %k0|%k0, %2}";
6529         }
6530       return "add{l}\t{%2, %k0|%k0, %2}";
6531     }
6532 }
6533   [(set (attr "type")
6534      (cond [(eq_attr "alternative" "1")
6535               (const_string "lea")
6536             ; Current assemblers are broken and do not allow @GOTOFF in
6537             ; ought but a memory context.
6538             (match_operand:SI 2 "pic_symbolic_operand" "")
6539               (const_string "lea")
6540             (match_operand:SI 2 "incdec_operand" "")
6541               (const_string "incdec")
6542            ]
6543            (const_string "alu")))
6544    (set_attr "mode" "SI")])
6545
6546 ;; Convert lea to the lea pattern to avoid flags dependency.
6547 (define_split
6548   [(set (match_operand:DI 0 "register_operand" "")
6549         (zero_extend:DI
6550           (plus:SI (match_operand:SI 1 "register_operand" "")
6551                    (match_operand:SI 2 "nonmemory_operand" ""))))
6552    (clobber (reg:CC FLAGS_REG))]
6553   "TARGET_64BIT && reload_completed
6554    && true_regnum (operands[0]) != true_regnum (operands[1])"
6555   [(set (match_dup 0)
6556         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6557 {
6558   operands[1] = gen_lowpart (Pmode, operands[1]);
6559   operands[2] = gen_lowpart (Pmode, operands[2]);
6560 })
6561
6562 (define_insn "*addsi_2"
6563   [(set (reg FLAGS_REG)
6564         (compare
6565           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6566                    (match_operand:SI 2 "general_operand" "g,ri"))
6567           (const_int 0)))
6568    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6569         (plus:SI (match_dup 1) (match_dup 2)))]
6570   "ix86_match_ccmode (insn, CCGOCmode)
6571    && ix86_binary_operator_ok (PLUS, SImode, operands)
6572    /* Current assemblers are broken and do not allow @GOTOFF in
6573       ought but a memory context.  */
6574    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6575 {
6576   switch (get_attr_type (insn))
6577     {
6578     case TYPE_INCDEC:
6579       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6580       if (operands[2] == const1_rtx)
6581         return "inc{l}\t%0";
6582       else
6583         {
6584           gcc_assert (operands[2] == constm1_rtx);
6585           return "dec{l}\t%0";
6586         }
6587
6588     default:
6589       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6590       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6591          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6592       if (CONST_INT_P (operands[2])
6593           && (INTVAL (operands[2]) == 128
6594               || (INTVAL (operands[2]) < 0
6595                   && INTVAL (operands[2]) != -128)))
6596         {
6597           operands[2] = GEN_INT (-INTVAL (operands[2]));
6598           return "sub{l}\t{%2, %0|%0, %2}";
6599         }
6600       return "add{l}\t{%2, %0|%0, %2}";
6601     }
6602 }
6603   [(set (attr "type")
6604      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6605         (const_string "incdec")
6606         (const_string "alu")))
6607    (set_attr "mode" "SI")])
6608
6609 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6610 (define_insn "*addsi_2_zext"
6611   [(set (reg FLAGS_REG)
6612         (compare
6613           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6614                    (match_operand:SI 2 "general_operand" "g"))
6615           (const_int 0)))
6616    (set (match_operand:DI 0 "register_operand" "=r")
6617         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6618   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6619    && ix86_binary_operator_ok (PLUS, SImode, operands)
6620    /* Current assemblers are broken and do not allow @GOTOFF in
6621       ought but a memory context.  */
6622    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6623 {
6624   switch (get_attr_type (insn))
6625     {
6626     case TYPE_INCDEC:
6627       if (operands[2] == const1_rtx)
6628         return "inc{l}\t%k0";
6629       else
6630         {
6631           gcc_assert (operands[2] == constm1_rtx);
6632           return "dec{l}\t%k0";
6633         }
6634
6635     default:
6636       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6637          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6638       if (CONST_INT_P (operands[2])
6639           && (INTVAL (operands[2]) == 128
6640               || (INTVAL (operands[2]) < 0
6641                   && INTVAL (operands[2]) != -128)))
6642         {
6643           operands[2] = GEN_INT (-INTVAL (operands[2]));
6644           return "sub{l}\t{%2, %k0|%k0, %2}";
6645         }
6646       return "add{l}\t{%2, %k0|%k0, %2}";
6647     }
6648 }
6649   [(set (attr "type")
6650      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6651         (const_string "incdec")
6652         (const_string "alu")))
6653    (set_attr "mode" "SI")])
6654
6655 (define_insn "*addsi_3"
6656   [(set (reg FLAGS_REG)
6657         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6658                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6659    (clobber (match_scratch:SI 0 "=r"))]
6660   "ix86_match_ccmode (insn, CCZmode)
6661    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6662    /* Current assemblers are broken and do not allow @GOTOFF in
6663       ought but a memory context.  */
6664    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6665 {
6666   switch (get_attr_type (insn))
6667     {
6668     case TYPE_INCDEC:
6669       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6670       if (operands[2] == const1_rtx)
6671         return "inc{l}\t%0";
6672       else
6673         {
6674           gcc_assert (operands[2] == constm1_rtx);
6675           return "dec{l}\t%0";
6676         }
6677
6678     default:
6679       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6680       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6681          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6682       if (CONST_INT_P (operands[2])
6683           && (INTVAL (operands[2]) == 128
6684               || (INTVAL (operands[2]) < 0
6685                   && INTVAL (operands[2]) != -128)))
6686         {
6687           operands[2] = GEN_INT (-INTVAL (operands[2]));
6688           return "sub{l}\t{%2, %0|%0, %2}";
6689         }
6690       return "add{l}\t{%2, %0|%0, %2}";
6691     }
6692 }
6693   [(set (attr "type")
6694      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6695         (const_string "incdec")
6696         (const_string "alu")))
6697    (set_attr "mode" "SI")])
6698
6699 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6700 (define_insn "*addsi_3_zext"
6701   [(set (reg FLAGS_REG)
6702         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6703                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6704    (set (match_operand:DI 0 "register_operand" "=r")
6705         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6706   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6707    && ix86_binary_operator_ok (PLUS, SImode, operands)
6708    /* Current assemblers are broken and do not allow @GOTOFF in
6709       ought but a memory context.  */
6710    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6711 {
6712   switch (get_attr_type (insn))
6713     {
6714     case TYPE_INCDEC:
6715       if (operands[2] == const1_rtx)
6716         return "inc{l}\t%k0";
6717       else
6718         {
6719           gcc_assert (operands[2] == constm1_rtx);
6720           return "dec{l}\t%k0";
6721         }
6722
6723     default:
6724       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6725          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6726       if (CONST_INT_P (operands[2])
6727           && (INTVAL (operands[2]) == 128
6728               || (INTVAL (operands[2]) < 0
6729                   && INTVAL (operands[2]) != -128)))
6730         {
6731           operands[2] = GEN_INT (-INTVAL (operands[2]));
6732           return "sub{l}\t{%2, %k0|%k0, %2}";
6733         }
6734       return "add{l}\t{%2, %k0|%k0, %2}";
6735     }
6736 }
6737   [(set (attr "type")
6738      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6739         (const_string "incdec")
6740         (const_string "alu")))
6741    (set_attr "mode" "SI")])
6742
6743 ; For comparisons against 1, -1 and 128, we may generate better code
6744 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6745 ; is matched then.  We can't accept general immediate, because for
6746 ; case of overflows,  the result is messed up.
6747 ; This pattern also don't hold of 0x80000000, since the value overflows
6748 ; when negated.
6749 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6750 ; only for comparisons not depending on it.
6751 (define_insn "*addsi_4"
6752   [(set (reg FLAGS_REG)
6753         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6754                  (match_operand:SI 2 "const_int_operand" "n")))
6755    (clobber (match_scratch:SI 0 "=rm"))]
6756   "ix86_match_ccmode (insn, CCGCmode)
6757    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6758 {
6759   switch (get_attr_type (insn))
6760     {
6761     case TYPE_INCDEC:
6762       if (operands[2] == constm1_rtx)
6763         return "inc{l}\t%0";
6764       else
6765         {
6766           gcc_assert (operands[2] == const1_rtx);
6767           return "dec{l}\t%0";
6768         }
6769
6770     default:
6771       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6772       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6773          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6774       if ((INTVAL (operands[2]) == -128
6775            || (INTVAL (operands[2]) > 0
6776                && INTVAL (operands[2]) != 128)))
6777         return "sub{l}\t{%2, %0|%0, %2}";
6778       operands[2] = GEN_INT (-INTVAL (operands[2]));
6779       return "add{l}\t{%2, %0|%0, %2}";
6780     }
6781 }
6782   [(set (attr "type")
6783      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6784         (const_string "incdec")
6785         (const_string "alu")))
6786    (set_attr "mode" "SI")])
6787
6788 (define_insn "*addsi_5"
6789   [(set (reg FLAGS_REG)
6790         (compare
6791           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6792                    (match_operand:SI 2 "general_operand" "g"))
6793           (const_int 0)))
6794    (clobber (match_scratch:SI 0 "=r"))]
6795   "ix86_match_ccmode (insn, CCGOCmode)
6796    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6797    /* Current assemblers are broken and do not allow @GOTOFF in
6798       ought but a memory context.  */
6799    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6800 {
6801   switch (get_attr_type (insn))
6802     {
6803     case TYPE_INCDEC:
6804       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6805       if (operands[2] == const1_rtx)
6806         return "inc{l}\t%0";
6807       else
6808         {
6809           gcc_assert (operands[2] == constm1_rtx);
6810           return "dec{l}\t%0";
6811         }
6812
6813     default:
6814       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6815       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6816          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6817       if (CONST_INT_P (operands[2])
6818           && (INTVAL (operands[2]) == 128
6819               || (INTVAL (operands[2]) < 0
6820                   && INTVAL (operands[2]) != -128)))
6821         {
6822           operands[2] = GEN_INT (-INTVAL (operands[2]));
6823           return "sub{l}\t{%2, %0|%0, %2}";
6824         }
6825       return "add{l}\t{%2, %0|%0, %2}";
6826     }
6827 }
6828   [(set (attr "type")
6829      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6830         (const_string "incdec")
6831         (const_string "alu")))
6832    (set_attr "mode" "SI")])
6833
6834 (define_expand "addhi3"
6835   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6836         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6837                  (match_operand:HI 2 "general_operand" "")))]
6838   "TARGET_HIMODE_MATH"
6839   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6840
6841 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6842 ;; type optimizations enabled by define-splits.  This is not important
6843 ;; for PII, and in fact harmful because of partial register stalls.
6844
6845 (define_insn "*addhi_1_lea"
6846   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6847         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6848                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6849    (clobber (reg:CC FLAGS_REG))]
6850   "!TARGET_PARTIAL_REG_STALL
6851    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6852 {
6853   switch (get_attr_type (insn))
6854     {
6855     case TYPE_LEA:
6856       return "#";
6857     case TYPE_INCDEC:
6858       if (operands[2] == const1_rtx)
6859         return "inc{w}\t%0";
6860       else
6861         {
6862           gcc_assert (operands[2] == constm1_rtx);
6863           return "dec{w}\t%0";
6864         }
6865
6866     default:
6867       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6868          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6869       if (CONST_INT_P (operands[2])
6870           && (INTVAL (operands[2]) == 128
6871               || (INTVAL (operands[2]) < 0
6872                   && INTVAL (operands[2]) != -128)))
6873         {
6874           operands[2] = GEN_INT (-INTVAL (operands[2]));
6875           return "sub{w}\t{%2, %0|%0, %2}";
6876         }
6877       return "add{w}\t{%2, %0|%0, %2}";
6878     }
6879 }
6880   [(set (attr "type")
6881      (if_then_else (eq_attr "alternative" "2")
6882         (const_string "lea")
6883         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6884            (const_string "incdec")
6885            (const_string "alu"))))
6886    (set_attr "mode" "HI,HI,SI")])
6887
6888 (define_insn "*addhi_1"
6889   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6890         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6891                  (match_operand:HI 2 "general_operand" "rn,rm")))
6892    (clobber (reg:CC FLAGS_REG))]
6893   "TARGET_PARTIAL_REG_STALL
6894    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6895 {
6896   switch (get_attr_type (insn))
6897     {
6898     case TYPE_INCDEC:
6899       if (operands[2] == const1_rtx)
6900         return "inc{w}\t%0";
6901       else
6902         {
6903           gcc_assert (operands[2] == constm1_rtx);
6904           return "dec{w}\t%0";
6905         }
6906
6907     default:
6908       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6909          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6910       if (CONST_INT_P (operands[2])
6911           && (INTVAL (operands[2]) == 128
6912               || (INTVAL (operands[2]) < 0
6913                   && INTVAL (operands[2]) != -128)))
6914         {
6915           operands[2] = GEN_INT (-INTVAL (operands[2]));
6916           return "sub{w}\t{%2, %0|%0, %2}";
6917         }
6918       return "add{w}\t{%2, %0|%0, %2}";
6919     }
6920 }
6921   [(set (attr "type")
6922      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6923         (const_string "incdec")
6924         (const_string "alu")))
6925    (set_attr "mode" "HI")])
6926
6927 (define_insn "*addhi_2"
6928   [(set (reg FLAGS_REG)
6929         (compare
6930           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6931                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6932           (const_int 0)))
6933    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6934         (plus:HI (match_dup 1) (match_dup 2)))]
6935   "ix86_match_ccmode (insn, CCGOCmode)
6936    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6937 {
6938   switch (get_attr_type (insn))
6939     {
6940     case TYPE_INCDEC:
6941       if (operands[2] == const1_rtx)
6942         return "inc{w}\t%0";
6943       else
6944         {
6945           gcc_assert (operands[2] == constm1_rtx);
6946           return "dec{w}\t%0";
6947         }
6948
6949     default:
6950       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6951          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6952       if (CONST_INT_P (operands[2])
6953           && (INTVAL (operands[2]) == 128
6954               || (INTVAL (operands[2]) < 0
6955                   && INTVAL (operands[2]) != -128)))
6956         {
6957           operands[2] = GEN_INT (-INTVAL (operands[2]));
6958           return "sub{w}\t{%2, %0|%0, %2}";
6959         }
6960       return "add{w}\t{%2, %0|%0, %2}";
6961     }
6962 }
6963   [(set (attr "type")
6964      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6965         (const_string "incdec")
6966         (const_string "alu")))
6967    (set_attr "mode" "HI")])
6968
6969 (define_insn "*addhi_3"
6970   [(set (reg FLAGS_REG)
6971         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6972                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6973    (clobber (match_scratch:HI 0 "=r"))]
6974   "ix86_match_ccmode (insn, CCZmode)
6975    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6976 {
6977   switch (get_attr_type (insn))
6978     {
6979     case TYPE_INCDEC:
6980       if (operands[2] == const1_rtx)
6981         return "inc{w}\t%0";
6982       else
6983         {
6984           gcc_assert (operands[2] == constm1_rtx);
6985           return "dec{w}\t%0";
6986         }
6987
6988     default:
6989       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6990          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6991       if (CONST_INT_P (operands[2])
6992           && (INTVAL (operands[2]) == 128
6993               || (INTVAL (operands[2]) < 0
6994                   && INTVAL (operands[2]) != -128)))
6995         {
6996           operands[2] = GEN_INT (-INTVAL (operands[2]));
6997           return "sub{w}\t{%2, %0|%0, %2}";
6998         }
6999       return "add{w}\t{%2, %0|%0, %2}";
7000     }
7001 }
7002   [(set (attr "type")
7003      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7004         (const_string "incdec")
7005         (const_string "alu")))
7006    (set_attr "mode" "HI")])
7007
7008 ; See comments above addsi_4 for details.
7009 (define_insn "*addhi_4"
7010   [(set (reg FLAGS_REG)
7011         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7012                  (match_operand:HI 2 "const_int_operand" "n")))
7013    (clobber (match_scratch:HI 0 "=rm"))]
7014   "ix86_match_ccmode (insn, CCGCmode)
7015    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7016 {
7017   switch (get_attr_type (insn))
7018     {
7019     case TYPE_INCDEC:
7020       if (operands[2] == constm1_rtx)
7021         return "inc{w}\t%0";
7022       else
7023         {
7024           gcc_assert (operands[2] == const1_rtx);
7025           return "dec{w}\t%0";
7026         }
7027
7028     default:
7029       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7030       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7031          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7032       if ((INTVAL (operands[2]) == -128
7033            || (INTVAL (operands[2]) > 0
7034                && INTVAL (operands[2]) != 128)))
7035         return "sub{w}\t{%2, %0|%0, %2}";
7036       operands[2] = GEN_INT (-INTVAL (operands[2]));
7037       return "add{w}\t{%2, %0|%0, %2}";
7038     }
7039 }
7040   [(set (attr "type")
7041      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7042         (const_string "incdec")
7043         (const_string "alu")))
7044    (set_attr "mode" "SI")])
7045
7046
7047 (define_insn "*addhi_5"
7048   [(set (reg FLAGS_REG)
7049         (compare
7050           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7051                    (match_operand:HI 2 "general_operand" "rmn"))
7052           (const_int 0)))
7053    (clobber (match_scratch:HI 0 "=r"))]
7054   "ix86_match_ccmode (insn, CCGOCmode)
7055    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7056 {
7057   switch (get_attr_type (insn))
7058     {
7059     case TYPE_INCDEC:
7060       if (operands[2] == const1_rtx)
7061         return "inc{w}\t%0";
7062       else
7063         {
7064           gcc_assert (operands[2] == constm1_rtx);
7065           return "dec{w}\t%0";
7066         }
7067
7068     default:
7069       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7070          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7071       if (CONST_INT_P (operands[2])
7072           && (INTVAL (operands[2]) == 128
7073               || (INTVAL (operands[2]) < 0
7074                   && INTVAL (operands[2]) != -128)))
7075         {
7076           operands[2] = GEN_INT (-INTVAL (operands[2]));
7077           return "sub{w}\t{%2, %0|%0, %2}";
7078         }
7079       return "add{w}\t{%2, %0|%0, %2}";
7080     }
7081 }
7082   [(set (attr "type")
7083      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7084         (const_string "incdec")
7085         (const_string "alu")))
7086    (set_attr "mode" "HI")])
7087
7088 (define_expand "addqi3"
7089   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7090         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7091                  (match_operand:QI 2 "general_operand" "")))]
7092   "TARGET_QIMODE_MATH"
7093   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7094
7095 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7096 (define_insn "*addqi_1_lea"
7097   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7098         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7099                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7100    (clobber (reg:CC FLAGS_REG))]
7101   "!TARGET_PARTIAL_REG_STALL
7102    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7103 {
7104   int widen = (which_alternative == 2);
7105   switch (get_attr_type (insn))
7106     {
7107     case TYPE_LEA:
7108       return "#";
7109     case TYPE_INCDEC:
7110       if (operands[2] == const1_rtx)
7111         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7112       else
7113         {
7114           gcc_assert (operands[2] == constm1_rtx);
7115           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7116         }
7117
7118     default:
7119       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7120          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7121       if (CONST_INT_P (operands[2])
7122           && (INTVAL (operands[2]) == 128
7123               || (INTVAL (operands[2]) < 0
7124                   && INTVAL (operands[2]) != -128)))
7125         {
7126           operands[2] = GEN_INT (-INTVAL (operands[2]));
7127           if (widen)
7128             return "sub{l}\t{%2, %k0|%k0, %2}";
7129           else
7130             return "sub{b}\t{%2, %0|%0, %2}";
7131         }
7132       if (widen)
7133         return "add{l}\t{%k2, %k0|%k0, %k2}";
7134       else
7135         return "add{b}\t{%2, %0|%0, %2}";
7136     }
7137 }
7138   [(set (attr "type")
7139      (if_then_else (eq_attr "alternative" "3")
7140         (const_string "lea")
7141         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7142            (const_string "incdec")
7143            (const_string "alu"))))
7144    (set_attr "mode" "QI,QI,SI,SI")])
7145
7146 (define_insn "*addqi_1"
7147   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7148         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7149                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7150    (clobber (reg:CC FLAGS_REG))]
7151   "TARGET_PARTIAL_REG_STALL
7152    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7153 {
7154   int widen = (which_alternative == 2);
7155   switch (get_attr_type (insn))
7156     {
7157     case TYPE_INCDEC:
7158       if (operands[2] == const1_rtx)
7159         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7160       else
7161         {
7162           gcc_assert (operands[2] == constm1_rtx);
7163           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7164         }
7165
7166     default:
7167       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7168          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7169       if (CONST_INT_P (operands[2])
7170           && (INTVAL (operands[2]) == 128
7171               || (INTVAL (operands[2]) < 0
7172                   && INTVAL (operands[2]) != -128)))
7173         {
7174           operands[2] = GEN_INT (-INTVAL (operands[2]));
7175           if (widen)
7176             return "sub{l}\t{%2, %k0|%k0, %2}";
7177           else
7178             return "sub{b}\t{%2, %0|%0, %2}";
7179         }
7180       if (widen)
7181         return "add{l}\t{%k2, %k0|%k0, %k2}";
7182       else
7183         return "add{b}\t{%2, %0|%0, %2}";
7184     }
7185 }
7186   [(set (attr "type")
7187      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7188         (const_string "incdec")
7189         (const_string "alu")))
7190    (set_attr "mode" "QI,QI,SI")])
7191
7192 (define_insn "*addqi_1_slp"
7193   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7194         (plus:QI (match_dup 0)
7195                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7196    (clobber (reg:CC FLAGS_REG))]
7197   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7198    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7199 {
7200   switch (get_attr_type (insn))
7201     {
7202     case TYPE_INCDEC:
7203       if (operands[1] == const1_rtx)
7204         return "inc{b}\t%0";
7205       else
7206         {
7207           gcc_assert (operands[1] == constm1_rtx);
7208           return "dec{b}\t%0";
7209         }
7210
7211     default:
7212       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7213       if (CONST_INT_P (operands[1])
7214           && INTVAL (operands[1]) < 0)
7215         {
7216           operands[1] = GEN_INT (-INTVAL (operands[1]));
7217           return "sub{b}\t{%1, %0|%0, %1}";
7218         }
7219       return "add{b}\t{%1, %0|%0, %1}";
7220     }
7221 }
7222   [(set (attr "type")
7223      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7224         (const_string "incdec")
7225         (const_string "alu1")))
7226    (set (attr "memory")
7227      (if_then_else (match_operand 1 "memory_operand" "")
7228         (const_string "load")
7229         (const_string "none")))
7230    (set_attr "mode" "QI")])
7231
7232 (define_insn "*addqi_2"
7233   [(set (reg FLAGS_REG)
7234         (compare
7235           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7236                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7237           (const_int 0)))
7238    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7239         (plus:QI (match_dup 1) (match_dup 2)))]
7240   "ix86_match_ccmode (insn, CCGOCmode)
7241    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7242 {
7243   switch (get_attr_type (insn))
7244     {
7245     case TYPE_INCDEC:
7246       if (operands[2] == const1_rtx)
7247         return "inc{b}\t%0";
7248       else
7249         {
7250           gcc_assert (operands[2] == constm1_rtx
7251                       || (CONST_INT_P (operands[2])
7252                           && INTVAL (operands[2]) == 255));
7253           return "dec{b}\t%0";
7254         }
7255
7256     default:
7257       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7258       if (CONST_INT_P (operands[2])
7259           && INTVAL (operands[2]) < 0)
7260         {
7261           operands[2] = GEN_INT (-INTVAL (operands[2]));
7262           return "sub{b}\t{%2, %0|%0, %2}";
7263         }
7264       return "add{b}\t{%2, %0|%0, %2}";
7265     }
7266 }
7267   [(set (attr "type")
7268      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7269         (const_string "incdec")
7270         (const_string "alu")))
7271    (set_attr "mode" "QI")])
7272
7273 (define_insn "*addqi_3"
7274   [(set (reg FLAGS_REG)
7275         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7276                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7277    (clobber (match_scratch:QI 0 "=q"))]
7278   "ix86_match_ccmode (insn, CCZmode)
7279    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7280 {
7281   switch (get_attr_type (insn))
7282     {
7283     case TYPE_INCDEC:
7284       if (operands[2] == const1_rtx)
7285         return "inc{b}\t%0";
7286       else
7287         {
7288           gcc_assert (operands[2] == constm1_rtx
7289                       || (CONST_INT_P (operands[2])
7290                           && INTVAL (operands[2]) == 255));
7291           return "dec{b}\t%0";
7292         }
7293
7294     default:
7295       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7296       if (CONST_INT_P (operands[2])
7297           && INTVAL (operands[2]) < 0)
7298         {
7299           operands[2] = GEN_INT (-INTVAL (operands[2]));
7300           return "sub{b}\t{%2, %0|%0, %2}";
7301         }
7302       return "add{b}\t{%2, %0|%0, %2}";
7303     }
7304 }
7305   [(set (attr "type")
7306      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7307         (const_string "incdec")
7308         (const_string "alu")))
7309    (set_attr "mode" "QI")])
7310
7311 ; See comments above addsi_4 for details.
7312 (define_insn "*addqi_4"
7313   [(set (reg FLAGS_REG)
7314         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7315                  (match_operand:QI 2 "const_int_operand" "n")))
7316    (clobber (match_scratch:QI 0 "=qm"))]
7317   "ix86_match_ccmode (insn, CCGCmode)
7318    && (INTVAL (operands[2]) & 0xff) != 0x80"
7319 {
7320   switch (get_attr_type (insn))
7321     {
7322     case TYPE_INCDEC:
7323       if (operands[2] == constm1_rtx
7324           || (CONST_INT_P (operands[2])
7325               && INTVAL (operands[2]) == 255))
7326         return "inc{b}\t%0";
7327       else
7328         {
7329           gcc_assert (operands[2] == const1_rtx);
7330           return "dec{b}\t%0";
7331         }
7332
7333     default:
7334       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7335       if (INTVAL (operands[2]) < 0)
7336         {
7337           operands[2] = GEN_INT (-INTVAL (operands[2]));
7338           return "add{b}\t{%2, %0|%0, %2}";
7339         }
7340       return "sub{b}\t{%2, %0|%0, %2}";
7341     }
7342 }
7343   [(set (attr "type")
7344      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7345         (const_string "incdec")
7346         (const_string "alu")))
7347    (set_attr "mode" "QI")])
7348
7349
7350 (define_insn "*addqi_5"
7351   [(set (reg FLAGS_REG)
7352         (compare
7353           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7354                    (match_operand:QI 2 "general_operand" "qmn"))
7355           (const_int 0)))
7356    (clobber (match_scratch:QI 0 "=q"))]
7357   "ix86_match_ccmode (insn, CCGOCmode)
7358    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7359 {
7360   switch (get_attr_type (insn))
7361     {
7362     case TYPE_INCDEC:
7363       if (operands[2] == const1_rtx)
7364         return "inc{b}\t%0";
7365       else
7366         {
7367           gcc_assert (operands[2] == constm1_rtx
7368                       || (CONST_INT_P (operands[2])
7369                           && INTVAL (operands[2]) == 255));
7370           return "dec{b}\t%0";
7371         }
7372
7373     default:
7374       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7375       if (CONST_INT_P (operands[2])
7376           && INTVAL (operands[2]) < 0)
7377         {
7378           operands[2] = GEN_INT (-INTVAL (operands[2]));
7379           return "sub{b}\t{%2, %0|%0, %2}";
7380         }
7381       return "add{b}\t{%2, %0|%0, %2}";
7382     }
7383 }
7384   [(set (attr "type")
7385      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7386         (const_string "incdec")
7387         (const_string "alu")))
7388    (set_attr "mode" "QI")])
7389
7390
7391 (define_insn "addqi_ext_1"
7392   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7393                          (const_int 8)
7394                          (const_int 8))
7395         (plus:SI
7396           (zero_extract:SI
7397             (match_operand 1 "ext_register_operand" "0")
7398             (const_int 8)
7399             (const_int 8))
7400           (match_operand:QI 2 "general_operand" "Qmn")))
7401    (clobber (reg:CC FLAGS_REG))]
7402   "!TARGET_64BIT"
7403 {
7404   switch (get_attr_type (insn))
7405     {
7406     case TYPE_INCDEC:
7407       if (operands[2] == const1_rtx)
7408         return "inc{b}\t%h0";
7409       else
7410         {
7411           gcc_assert (operands[2] == constm1_rtx
7412                       || (CONST_INT_P (operands[2])
7413                           && INTVAL (operands[2]) == 255));
7414           return "dec{b}\t%h0";
7415         }
7416
7417     default:
7418       return "add{b}\t{%2, %h0|%h0, %2}";
7419     }
7420 }
7421   [(set (attr "type")
7422      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7423         (const_string "incdec")
7424         (const_string "alu")))
7425    (set_attr "mode" "QI")])
7426
7427 (define_insn "*addqi_ext_1_rex64"
7428   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7429                          (const_int 8)
7430                          (const_int 8))
7431         (plus:SI
7432           (zero_extract:SI
7433             (match_operand 1 "ext_register_operand" "0")
7434             (const_int 8)
7435             (const_int 8))
7436           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7437    (clobber (reg:CC FLAGS_REG))]
7438   "TARGET_64BIT"
7439 {
7440   switch (get_attr_type (insn))
7441     {
7442     case TYPE_INCDEC:
7443       if (operands[2] == const1_rtx)
7444         return "inc{b}\t%h0";
7445       else
7446         {
7447           gcc_assert (operands[2] == constm1_rtx
7448                       || (CONST_INT_P (operands[2])
7449                           && INTVAL (operands[2]) == 255));
7450           return "dec{b}\t%h0";
7451         }
7452
7453     default:
7454       return "add{b}\t{%2, %h0|%h0, %2}";
7455     }
7456 }
7457   [(set (attr "type")
7458      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7459         (const_string "incdec")
7460         (const_string "alu")))
7461    (set_attr "mode" "QI")])
7462
7463 (define_insn "*addqi_ext_2"
7464   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7465                          (const_int 8)
7466                          (const_int 8))
7467         (plus:SI
7468           (zero_extract:SI
7469             (match_operand 1 "ext_register_operand" "%0")
7470             (const_int 8)
7471             (const_int 8))
7472           (zero_extract:SI
7473             (match_operand 2 "ext_register_operand" "Q")
7474             (const_int 8)
7475             (const_int 8))))
7476    (clobber (reg:CC FLAGS_REG))]
7477   ""
7478   "add{b}\t{%h2, %h0|%h0, %h2}"
7479   [(set_attr "type" "alu")
7480    (set_attr "mode" "QI")])
7481
7482 ;; The patterns that match these are at the end of this file.
7483
7484 (define_expand "addxf3"
7485   [(set (match_operand:XF 0 "register_operand" "")
7486         (plus:XF (match_operand:XF 1 "register_operand" "")
7487                  (match_operand:XF 2 "register_operand" "")))]
7488   "TARGET_80387"
7489   "")
7490
7491 (define_expand "add<mode>3"
7492   [(set (match_operand:MODEF 0 "register_operand" "")
7493         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7494                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7495   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7496   "")
7497 \f
7498 ;; Subtract instructions
7499
7500 ;; %%% splits for subditi3
7501
7502 (define_expand "subti3"
7503   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7504         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7505                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7506   "TARGET_64BIT"
7507   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7508
7509 (define_insn "*subti3_1"
7510   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7511         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7512                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7513    (clobber (reg:CC FLAGS_REG))]
7514   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7515   "#")
7516
7517 (define_split
7518   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7519         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7520                   (match_operand:TI 2 "x86_64_general_operand" "")))
7521    (clobber (reg:CC FLAGS_REG))]
7522   "TARGET_64BIT && reload_completed"
7523   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7524               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7525    (parallel [(set (match_dup 3)
7526                    (minus:DI (match_dup 4)
7527                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7528                                       (match_dup 5))))
7529               (clobber (reg:CC FLAGS_REG))])]
7530   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7531
7532 ;; %%% splits for subsidi3
7533
7534 (define_expand "subdi3"
7535   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7536         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7537                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7538   ""
7539   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7540
7541 (define_insn "*subdi3_1"
7542   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7543         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7544                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7545    (clobber (reg:CC FLAGS_REG))]
7546   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7547   "#")
7548
7549 (define_split
7550   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7551         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7552                   (match_operand:DI 2 "general_operand" "")))
7553    (clobber (reg:CC FLAGS_REG))]
7554   "!TARGET_64BIT && reload_completed"
7555   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7556               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7557    (parallel [(set (match_dup 3)
7558                    (minus:SI (match_dup 4)
7559                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7560                                       (match_dup 5))))
7561               (clobber (reg:CC FLAGS_REG))])]
7562   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7563
7564 (define_insn "subdi3_carry_rex64"
7565   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7566           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7567             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7568                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7569    (clobber (reg:CC FLAGS_REG))]
7570   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7571   "sbb{q}\t{%2, %0|%0, %2}"
7572   [(set_attr "type" "alu")
7573    (set_attr "pent_pair" "pu")
7574    (set_attr "mode" "DI")])
7575
7576 (define_insn "*subdi_1_rex64"
7577   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7578         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7579                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7580    (clobber (reg:CC FLAGS_REG))]
7581   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7582   "sub{q}\t{%2, %0|%0, %2}"
7583   [(set_attr "type" "alu")
7584    (set_attr "mode" "DI")])
7585
7586 (define_insn "*subdi_2_rex64"
7587   [(set (reg FLAGS_REG)
7588         (compare
7589           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7590                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7591           (const_int 0)))
7592    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7593         (minus:DI (match_dup 1) (match_dup 2)))]
7594   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7595    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7596   "sub{q}\t{%2, %0|%0, %2}"
7597   [(set_attr "type" "alu")
7598    (set_attr "mode" "DI")])
7599
7600 (define_insn "*subdi_3_rex63"
7601   [(set (reg FLAGS_REG)
7602         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7603                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7604    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7605         (minus:DI (match_dup 1) (match_dup 2)))]
7606   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7607    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7608   "sub{q}\t{%2, %0|%0, %2}"
7609   [(set_attr "type" "alu")
7610    (set_attr "mode" "DI")])
7611
7612 (define_insn "subqi3_carry"
7613   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7614           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7615             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7616                (match_operand:QI 2 "general_operand" "qn,qm"))))
7617    (clobber (reg:CC FLAGS_REG))]
7618   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7619   "sbb{b}\t{%2, %0|%0, %2}"
7620   [(set_attr "type" "alu")
7621    (set_attr "pent_pair" "pu")
7622    (set_attr "mode" "QI")])
7623
7624 (define_insn "subhi3_carry"
7625   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7626           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7627             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7628                (match_operand:HI 2 "general_operand" "rn,rm"))))
7629    (clobber (reg:CC FLAGS_REG))]
7630   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7631   "sbb{w}\t{%2, %0|%0, %2}"
7632   [(set_attr "type" "alu")
7633    (set_attr "pent_pair" "pu")
7634    (set_attr "mode" "HI")])
7635
7636 (define_insn "subsi3_carry"
7637   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7638           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7639             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7640                (match_operand:SI 2 "general_operand" "ri,rm"))))
7641    (clobber (reg:CC FLAGS_REG))]
7642   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7643   "sbb{l}\t{%2, %0|%0, %2}"
7644   [(set_attr "type" "alu")
7645    (set_attr "pent_pair" "pu")
7646    (set_attr "mode" "SI")])
7647
7648 (define_insn "subsi3_carry_zext"
7649   [(set (match_operand:DI 0 "register_operand" "=r")
7650           (zero_extend:DI
7651             (minus:SI (match_operand:SI 1 "register_operand" "0")
7652               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7653                  (match_operand:SI 2 "general_operand" "g")))))
7654    (clobber (reg:CC FLAGS_REG))]
7655   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7656   "sbb{l}\t{%2, %k0|%k0, %2}"
7657   [(set_attr "type" "alu")
7658    (set_attr "pent_pair" "pu")
7659    (set_attr "mode" "SI")])
7660
7661 (define_expand "subsi3"
7662   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7663         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7664                   (match_operand:SI 2 "general_operand" "")))]
7665   ""
7666   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7667
7668 (define_insn "*subsi_1"
7669   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7670         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7671                   (match_operand:SI 2 "general_operand" "ri,rm")))
7672    (clobber (reg:CC FLAGS_REG))]
7673   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7674   "sub{l}\t{%2, %0|%0, %2}"
7675   [(set_attr "type" "alu")
7676    (set_attr "mode" "SI")])
7677
7678 (define_insn "*subsi_1_zext"
7679   [(set (match_operand:DI 0 "register_operand" "=r")
7680         (zero_extend:DI
7681           (minus:SI (match_operand:SI 1 "register_operand" "0")
7682                     (match_operand:SI 2 "general_operand" "g"))))
7683    (clobber (reg:CC FLAGS_REG))]
7684   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7685   "sub{l}\t{%2, %k0|%k0, %2}"
7686   [(set_attr "type" "alu")
7687    (set_attr "mode" "SI")])
7688
7689 (define_insn "*subsi_2"
7690   [(set (reg FLAGS_REG)
7691         (compare
7692           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7693                     (match_operand:SI 2 "general_operand" "ri,rm"))
7694           (const_int 0)))
7695    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7696         (minus:SI (match_dup 1) (match_dup 2)))]
7697   "ix86_match_ccmode (insn, CCGOCmode)
7698    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7699   "sub{l}\t{%2, %0|%0, %2}"
7700   [(set_attr "type" "alu")
7701    (set_attr "mode" "SI")])
7702
7703 (define_insn "*subsi_2_zext"
7704   [(set (reg FLAGS_REG)
7705         (compare
7706           (minus:SI (match_operand:SI 1 "register_operand" "0")
7707                     (match_operand:SI 2 "general_operand" "g"))
7708           (const_int 0)))
7709    (set (match_operand:DI 0 "register_operand" "=r")
7710         (zero_extend:DI
7711           (minus:SI (match_dup 1)
7712                     (match_dup 2))))]
7713   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7714    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7715   "sub{l}\t{%2, %k0|%k0, %2}"
7716   [(set_attr "type" "alu")
7717    (set_attr "mode" "SI")])
7718
7719 (define_insn "*subsi_3"
7720   [(set (reg FLAGS_REG)
7721         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7722                  (match_operand:SI 2 "general_operand" "ri,rm")))
7723    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7724         (minus:SI (match_dup 1) (match_dup 2)))]
7725   "ix86_match_ccmode (insn, CCmode)
7726    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7727   "sub{l}\t{%2, %0|%0, %2}"
7728   [(set_attr "type" "alu")
7729    (set_attr "mode" "SI")])
7730
7731 (define_insn "*subsi_3_zext"
7732   [(set (reg FLAGS_REG)
7733         (compare (match_operand:SI 1 "register_operand" "0")
7734                  (match_operand:SI 2 "general_operand" "g")))
7735    (set (match_operand:DI 0 "register_operand" "=r")
7736         (zero_extend:DI
7737           (minus:SI (match_dup 1)
7738                     (match_dup 2))))]
7739   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7740    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7741   "sub{l}\t{%2, %1|%1, %2}"
7742   [(set_attr "type" "alu")
7743    (set_attr "mode" "DI")])
7744
7745 (define_expand "subhi3"
7746   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7747         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7748                   (match_operand:HI 2 "general_operand" "")))]
7749   "TARGET_HIMODE_MATH"
7750   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7751
7752 (define_insn "*subhi_1"
7753   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7754         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7755                   (match_operand:HI 2 "general_operand" "rn,rm")))
7756    (clobber (reg:CC FLAGS_REG))]
7757   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7758   "sub{w}\t{%2, %0|%0, %2}"
7759   [(set_attr "type" "alu")
7760    (set_attr "mode" "HI")])
7761
7762 (define_insn "*subhi_2"
7763   [(set (reg FLAGS_REG)
7764         (compare
7765           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7766                     (match_operand:HI 2 "general_operand" "rn,rm"))
7767           (const_int 0)))
7768    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7769         (minus:HI (match_dup 1) (match_dup 2)))]
7770   "ix86_match_ccmode (insn, CCGOCmode)
7771    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7772   "sub{w}\t{%2, %0|%0, %2}"
7773   [(set_attr "type" "alu")
7774    (set_attr "mode" "HI")])
7775
7776 (define_insn "*subhi_3"
7777   [(set (reg FLAGS_REG)
7778         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7779                  (match_operand:HI 2 "general_operand" "rn,rm")))
7780    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7781         (minus:HI (match_dup 1) (match_dup 2)))]
7782   "ix86_match_ccmode (insn, CCmode)
7783    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7784   "sub{w}\t{%2, %0|%0, %2}"
7785   [(set_attr "type" "alu")
7786    (set_attr "mode" "HI")])
7787
7788 (define_expand "subqi3"
7789   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7790         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7791                   (match_operand:QI 2 "general_operand" "")))]
7792   "TARGET_QIMODE_MATH"
7793   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7794
7795 (define_insn "*subqi_1"
7796   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7797         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7798                   (match_operand:QI 2 "general_operand" "qn,qm")))
7799    (clobber (reg:CC FLAGS_REG))]
7800   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7801   "sub{b}\t{%2, %0|%0, %2}"
7802   [(set_attr "type" "alu")
7803    (set_attr "mode" "QI")])
7804
7805 (define_insn "*subqi_1_slp"
7806   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7807         (minus:QI (match_dup 0)
7808                   (match_operand:QI 1 "general_operand" "qn,qm")))
7809    (clobber (reg:CC FLAGS_REG))]
7810   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7811    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7812   "sub{b}\t{%1, %0|%0, %1}"
7813   [(set_attr "type" "alu1")
7814    (set_attr "mode" "QI")])
7815
7816 (define_insn "*subqi_2"
7817   [(set (reg FLAGS_REG)
7818         (compare
7819           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7820                     (match_operand:QI 2 "general_operand" "qn,qm"))
7821           (const_int 0)))
7822    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7823         (minus:QI (match_dup 1) (match_dup 2)))]
7824   "ix86_match_ccmode (insn, CCGOCmode)
7825    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7826   "sub{b}\t{%2, %0|%0, %2}"
7827   [(set_attr "type" "alu")
7828    (set_attr "mode" "QI")])
7829
7830 (define_insn "*subqi_3"
7831   [(set (reg FLAGS_REG)
7832         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7833                  (match_operand:QI 2 "general_operand" "qn,qm")))
7834    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7835         (minus:QI (match_dup 1) (match_dup 2)))]
7836   "ix86_match_ccmode (insn, CCmode)
7837    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7838   "sub{b}\t{%2, %0|%0, %2}"
7839   [(set_attr "type" "alu")
7840    (set_attr "mode" "QI")])
7841
7842 ;; The patterns that match these are at the end of this file.
7843
7844 (define_expand "subxf3"
7845   [(set (match_operand:XF 0 "register_operand" "")
7846         (minus:XF (match_operand:XF 1 "register_operand" "")
7847                   (match_operand:XF 2 "register_operand" "")))]
7848   "TARGET_80387"
7849   "")
7850
7851 (define_expand "sub<mode>3"
7852   [(set (match_operand:MODEF 0 "register_operand" "")
7853         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7854                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7855   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7856   "")
7857 \f
7858 ;; Multiply instructions
7859
7860 (define_expand "muldi3"
7861   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7862                    (mult:DI (match_operand:DI 1 "register_operand" "")
7863                             (match_operand:DI 2 "x86_64_general_operand" "")))
7864               (clobber (reg:CC FLAGS_REG))])]
7865   "TARGET_64BIT"
7866   "")
7867
7868 ;; On AMDFAM10
7869 ;; IMUL reg64, reg64, imm8      Direct
7870 ;; IMUL reg64, mem64, imm8      VectorPath
7871 ;; IMUL reg64, reg64, imm32     Direct
7872 ;; IMUL reg64, mem64, imm32     VectorPath
7873 ;; IMUL reg64, reg64            Direct
7874 ;; IMUL reg64, mem64            Direct
7875
7876 (define_insn "*muldi3_1_rex64"
7877   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7878         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7879                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7880    (clobber (reg:CC FLAGS_REG))]
7881   "TARGET_64BIT
7882    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7883   "@
7884    imul{q}\t{%2, %1, %0|%0, %1, %2}
7885    imul{q}\t{%2, %1, %0|%0, %1, %2}
7886    imul{q}\t{%2, %0|%0, %2}"
7887   [(set_attr "type" "imul")
7888    (set_attr "prefix_0f" "0,0,1")
7889    (set (attr "athlon_decode")
7890         (cond [(eq_attr "cpu" "athlon")
7891                   (const_string "vector")
7892                (eq_attr "alternative" "1")
7893                   (const_string "vector")
7894                (and (eq_attr "alternative" "2")
7895                     (match_operand 1 "memory_operand" ""))
7896                   (const_string "vector")]
7897               (const_string "direct")))
7898    (set (attr "amdfam10_decode")
7899         (cond [(and (eq_attr "alternative" "0,1")
7900                     (match_operand 1 "memory_operand" ""))
7901                   (const_string "vector")]
7902               (const_string "direct")))
7903    (set_attr "mode" "DI")])
7904
7905 (define_expand "mulsi3"
7906   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7907                    (mult:SI (match_operand:SI 1 "register_operand" "")
7908                             (match_operand:SI 2 "general_operand" "")))
7909               (clobber (reg:CC FLAGS_REG))])]
7910   ""
7911   "")
7912
7913 ;; On AMDFAM10
7914 ;; IMUL reg32, reg32, imm8      Direct
7915 ;; IMUL reg32, mem32, imm8      VectorPath
7916 ;; IMUL reg32, reg32, imm32     Direct
7917 ;; IMUL reg32, mem32, imm32     VectorPath
7918 ;; IMUL reg32, reg32            Direct
7919 ;; IMUL reg32, mem32            Direct
7920
7921 (define_insn "*mulsi3_1"
7922   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7923         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7924                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7925    (clobber (reg:CC FLAGS_REG))]
7926   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7927   "@
7928    imul{l}\t{%2, %1, %0|%0, %1, %2}
7929    imul{l}\t{%2, %1, %0|%0, %1, %2}
7930    imul{l}\t{%2, %0|%0, %2}"
7931   [(set_attr "type" "imul")
7932    (set_attr "prefix_0f" "0,0,1")
7933    (set (attr "athlon_decode")
7934         (cond [(eq_attr "cpu" "athlon")
7935                   (const_string "vector")
7936                (eq_attr "alternative" "1")
7937                   (const_string "vector")
7938                (and (eq_attr "alternative" "2")
7939                     (match_operand 1 "memory_operand" ""))
7940                   (const_string "vector")]
7941               (const_string "direct")))
7942    (set (attr "amdfam10_decode")
7943         (cond [(and (eq_attr "alternative" "0,1")
7944                     (match_operand 1 "memory_operand" ""))
7945                   (const_string "vector")]
7946               (const_string "direct")))
7947    (set_attr "mode" "SI")])
7948
7949 (define_insn "*mulsi3_1_zext"
7950   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7951         (zero_extend:DI
7952           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7953                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7954    (clobber (reg:CC FLAGS_REG))]
7955   "TARGET_64BIT
7956    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7957   "@
7958    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7959    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7960    imul{l}\t{%2, %k0|%k0, %2}"
7961   [(set_attr "type" "imul")
7962    (set_attr "prefix_0f" "0,0,1")
7963    (set (attr "athlon_decode")
7964         (cond [(eq_attr "cpu" "athlon")
7965                   (const_string "vector")
7966                (eq_attr "alternative" "1")
7967                   (const_string "vector")
7968                (and (eq_attr "alternative" "2")
7969                     (match_operand 1 "memory_operand" ""))
7970                   (const_string "vector")]
7971               (const_string "direct")))
7972    (set (attr "amdfam10_decode")
7973         (cond [(and (eq_attr "alternative" "0,1")
7974                     (match_operand 1 "memory_operand" ""))
7975                   (const_string "vector")]
7976               (const_string "direct")))
7977    (set_attr "mode" "SI")])
7978
7979 (define_expand "mulhi3"
7980   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7981                    (mult:HI (match_operand:HI 1 "register_operand" "")
7982                             (match_operand:HI 2 "general_operand" "")))
7983               (clobber (reg:CC FLAGS_REG))])]
7984   "TARGET_HIMODE_MATH"
7985   "")
7986
7987 ;; On AMDFAM10
7988 ;; IMUL reg16, reg16, imm8      VectorPath
7989 ;; IMUL reg16, mem16, imm8      VectorPath
7990 ;; IMUL reg16, reg16, imm16     VectorPath
7991 ;; IMUL reg16, mem16, imm16     VectorPath
7992 ;; IMUL reg16, reg16            Direct
7993 ;; IMUL reg16, mem16            Direct
7994 (define_insn "*mulhi3_1"
7995   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7996         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7997                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7998    (clobber (reg:CC FLAGS_REG))]
7999   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8000   "@
8001    imul{w}\t{%2, %1, %0|%0, %1, %2}
8002    imul{w}\t{%2, %1, %0|%0, %1, %2}
8003    imul{w}\t{%2, %0|%0, %2}"
8004   [(set_attr "type" "imul")
8005    (set_attr "prefix_0f" "0,0,1")
8006    (set (attr "athlon_decode")
8007         (cond [(eq_attr "cpu" "athlon")
8008                   (const_string "vector")
8009                (eq_attr "alternative" "1,2")
8010                   (const_string "vector")]
8011               (const_string "direct")))
8012    (set (attr "amdfam10_decode")
8013         (cond [(eq_attr "alternative" "0,1")
8014                   (const_string "vector")]
8015               (const_string "direct")))
8016    (set_attr "mode" "HI")])
8017
8018 (define_expand "mulqi3"
8019   [(parallel [(set (match_operand:QI 0 "register_operand" "")
8020                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8021                             (match_operand:QI 2 "register_operand" "")))
8022               (clobber (reg:CC FLAGS_REG))])]
8023   "TARGET_QIMODE_MATH"
8024   "")
8025
8026 ;;On AMDFAM10
8027 ;; MUL reg8     Direct
8028 ;; MUL mem8     Direct
8029
8030 (define_insn "*mulqi3_1"
8031   [(set (match_operand:QI 0 "register_operand" "=a")
8032         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8033                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8034    (clobber (reg:CC FLAGS_REG))]
8035   "TARGET_QIMODE_MATH
8036    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8037   "mul{b}\t%2"
8038   [(set_attr "type" "imul")
8039    (set_attr "length_immediate" "0")
8040    (set (attr "athlon_decode")
8041      (if_then_else (eq_attr "cpu" "athlon")
8042         (const_string "vector")
8043         (const_string "direct")))
8044    (set_attr "amdfam10_decode" "direct")
8045    (set_attr "mode" "QI")])
8046
8047 (define_expand "umulqihi3"
8048   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8049                    (mult:HI (zero_extend:HI
8050                               (match_operand:QI 1 "nonimmediate_operand" ""))
8051                             (zero_extend:HI
8052                               (match_operand:QI 2 "register_operand" ""))))
8053               (clobber (reg:CC FLAGS_REG))])]
8054   "TARGET_QIMODE_MATH"
8055   "")
8056
8057 (define_insn "*umulqihi3_1"
8058   [(set (match_operand:HI 0 "register_operand" "=a")
8059         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8060                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8061    (clobber (reg:CC FLAGS_REG))]
8062   "TARGET_QIMODE_MATH
8063    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8064   "mul{b}\t%2"
8065   [(set_attr "type" "imul")
8066    (set_attr "length_immediate" "0")
8067    (set (attr "athlon_decode")
8068      (if_then_else (eq_attr "cpu" "athlon")
8069         (const_string "vector")
8070         (const_string "direct")))
8071    (set_attr "amdfam10_decode" "direct")
8072    (set_attr "mode" "QI")])
8073
8074 (define_expand "mulqihi3"
8075   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8076                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8077                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8078               (clobber (reg:CC FLAGS_REG))])]
8079   "TARGET_QIMODE_MATH"
8080   "")
8081
8082 (define_insn "*mulqihi3_insn"
8083   [(set (match_operand:HI 0 "register_operand" "=a")
8084         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8085                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8086    (clobber (reg:CC FLAGS_REG))]
8087   "TARGET_QIMODE_MATH
8088    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8089   "imul{b}\t%2"
8090   [(set_attr "type" "imul")
8091    (set_attr "length_immediate" "0")
8092    (set (attr "athlon_decode")
8093      (if_then_else (eq_attr "cpu" "athlon")
8094         (const_string "vector")
8095         (const_string "direct")))
8096    (set_attr "amdfam10_decode" "direct")
8097    (set_attr "mode" "QI")])
8098
8099 (define_expand "umulditi3"
8100   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8101                    (mult:TI (zero_extend:TI
8102                               (match_operand:DI 1 "nonimmediate_operand" ""))
8103                             (zero_extend:TI
8104                               (match_operand:DI 2 "register_operand" ""))))
8105               (clobber (reg:CC FLAGS_REG))])]
8106   "TARGET_64BIT"
8107   "")
8108
8109 (define_insn "*umulditi3_insn"
8110   [(set (match_operand:TI 0 "register_operand" "=A")
8111         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8112                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8113    (clobber (reg:CC FLAGS_REG))]
8114   "TARGET_64BIT
8115    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8116   "mul{q}\t%2"
8117   [(set_attr "type" "imul")
8118    (set_attr "length_immediate" "0")
8119    (set (attr "athlon_decode")
8120      (if_then_else (eq_attr "cpu" "athlon")
8121         (const_string "vector")
8122         (const_string "double")))
8123    (set_attr "amdfam10_decode" "double")
8124    (set_attr "mode" "DI")])
8125
8126 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8127 (define_expand "umulsidi3"
8128   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8129                    (mult:DI (zero_extend:DI
8130                               (match_operand:SI 1 "nonimmediate_operand" ""))
8131                             (zero_extend:DI
8132                               (match_operand:SI 2 "register_operand" ""))))
8133               (clobber (reg:CC FLAGS_REG))])]
8134   "!TARGET_64BIT"
8135   "")
8136
8137 (define_insn "*umulsidi3_insn"
8138   [(set (match_operand:DI 0 "register_operand" "=A")
8139         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8140                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8141    (clobber (reg:CC FLAGS_REG))]
8142   "!TARGET_64BIT
8143    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8144   "mul{l}\t%2"
8145   [(set_attr "type" "imul")
8146    (set_attr "length_immediate" "0")
8147    (set (attr "athlon_decode")
8148      (if_then_else (eq_attr "cpu" "athlon")
8149         (const_string "vector")
8150         (const_string "double")))
8151    (set_attr "amdfam10_decode" "double")
8152    (set_attr "mode" "SI")])
8153
8154 (define_expand "mulditi3"
8155   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8156                    (mult:TI (sign_extend:TI
8157                               (match_operand:DI 1 "nonimmediate_operand" ""))
8158                             (sign_extend:TI
8159                               (match_operand:DI 2 "register_operand" ""))))
8160               (clobber (reg:CC FLAGS_REG))])]
8161   "TARGET_64BIT"
8162   "")
8163
8164 (define_insn "*mulditi3_insn"
8165   [(set (match_operand:TI 0 "register_operand" "=A")
8166         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8167                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8168    (clobber (reg:CC FLAGS_REG))]
8169   "TARGET_64BIT
8170    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8171   "imul{q}\t%2"
8172   [(set_attr "type" "imul")
8173    (set_attr "length_immediate" "0")
8174    (set (attr "athlon_decode")
8175      (if_then_else (eq_attr "cpu" "athlon")
8176         (const_string "vector")
8177         (const_string "double")))
8178    (set_attr "amdfam10_decode" "double")
8179    (set_attr "mode" "DI")])
8180
8181 (define_expand "mulsidi3"
8182   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8183                    (mult:DI (sign_extend:DI
8184                               (match_operand:SI 1 "nonimmediate_operand" ""))
8185                             (sign_extend:DI
8186                               (match_operand:SI 2 "register_operand" ""))))
8187               (clobber (reg:CC FLAGS_REG))])]
8188   "!TARGET_64BIT"
8189   "")
8190
8191 (define_insn "*mulsidi3_insn"
8192   [(set (match_operand:DI 0 "register_operand" "=A")
8193         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8194                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8195    (clobber (reg:CC FLAGS_REG))]
8196   "!TARGET_64BIT
8197    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8198   "imul{l}\t%2"
8199   [(set_attr "type" "imul")
8200    (set_attr "length_immediate" "0")
8201    (set (attr "athlon_decode")
8202      (if_then_else (eq_attr "cpu" "athlon")
8203         (const_string "vector")
8204         (const_string "double")))
8205    (set_attr "amdfam10_decode" "double")
8206    (set_attr "mode" "SI")])
8207
8208 (define_expand "umuldi3_highpart"
8209   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8210                    (truncate:DI
8211                      (lshiftrt:TI
8212                        (mult:TI (zero_extend:TI
8213                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8214                                 (zero_extend:TI
8215                                   (match_operand:DI 2 "register_operand" "")))
8216                        (const_int 64))))
8217               (clobber (match_scratch:DI 3 ""))
8218               (clobber (reg:CC FLAGS_REG))])]
8219   "TARGET_64BIT"
8220   "")
8221
8222 (define_insn "*umuldi3_highpart_rex64"
8223   [(set (match_operand:DI 0 "register_operand" "=d")
8224         (truncate:DI
8225           (lshiftrt:TI
8226             (mult:TI (zero_extend:TI
8227                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8228                      (zero_extend:TI
8229                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8230             (const_int 64))))
8231    (clobber (match_scratch:DI 3 "=1"))
8232    (clobber (reg:CC FLAGS_REG))]
8233   "TARGET_64BIT
8234    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8235   "mul{q}\t%2"
8236   [(set_attr "type" "imul")
8237    (set_attr "length_immediate" "0")
8238    (set (attr "athlon_decode")
8239      (if_then_else (eq_attr "cpu" "athlon")
8240         (const_string "vector")
8241         (const_string "double")))
8242    (set_attr "amdfam10_decode" "double")
8243    (set_attr "mode" "DI")])
8244
8245 (define_expand "umulsi3_highpart"
8246   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8247                    (truncate:SI
8248                      (lshiftrt:DI
8249                        (mult:DI (zero_extend:DI
8250                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8251                                 (zero_extend:DI
8252                                   (match_operand:SI 2 "register_operand" "")))
8253                        (const_int 32))))
8254               (clobber (match_scratch:SI 3 ""))
8255               (clobber (reg:CC FLAGS_REG))])]
8256   ""
8257   "")
8258
8259 (define_insn "*umulsi3_highpart_insn"
8260   [(set (match_operand:SI 0 "register_operand" "=d")
8261         (truncate:SI
8262           (lshiftrt:DI
8263             (mult:DI (zero_extend:DI
8264                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8265                      (zero_extend:DI
8266                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8267             (const_int 32))))
8268    (clobber (match_scratch:SI 3 "=1"))
8269    (clobber (reg:CC FLAGS_REG))]
8270   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8271   "mul{l}\t%2"
8272   [(set_attr "type" "imul")
8273    (set_attr "length_immediate" "0")
8274    (set (attr "athlon_decode")
8275      (if_then_else (eq_attr "cpu" "athlon")
8276         (const_string "vector")
8277         (const_string "double")))
8278    (set_attr "amdfam10_decode" "double")
8279    (set_attr "mode" "SI")])
8280
8281 (define_insn "*umulsi3_highpart_zext"
8282   [(set (match_operand:DI 0 "register_operand" "=d")
8283         (zero_extend:DI (truncate:SI
8284           (lshiftrt:DI
8285             (mult:DI (zero_extend:DI
8286                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8287                      (zero_extend:DI
8288                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8289             (const_int 32)))))
8290    (clobber (match_scratch:SI 3 "=1"))
8291    (clobber (reg:CC FLAGS_REG))]
8292   "TARGET_64BIT
8293    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8294   "mul{l}\t%2"
8295   [(set_attr "type" "imul")
8296    (set_attr "length_immediate" "0")
8297    (set (attr "athlon_decode")
8298      (if_then_else (eq_attr "cpu" "athlon")
8299         (const_string "vector")
8300         (const_string "double")))
8301    (set_attr "amdfam10_decode" "double")
8302    (set_attr "mode" "SI")])
8303
8304 (define_expand "smuldi3_highpart"
8305   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8306                    (truncate:DI
8307                      (lshiftrt:TI
8308                        (mult:TI (sign_extend:TI
8309                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8310                                 (sign_extend:TI
8311                                   (match_operand:DI 2 "register_operand" "")))
8312                        (const_int 64))))
8313               (clobber (match_scratch:DI 3 ""))
8314               (clobber (reg:CC FLAGS_REG))])]
8315   "TARGET_64BIT"
8316   "")
8317
8318 (define_insn "*smuldi3_highpart_rex64"
8319   [(set (match_operand:DI 0 "register_operand" "=d")
8320         (truncate:DI
8321           (lshiftrt:TI
8322             (mult:TI (sign_extend:TI
8323                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8324                      (sign_extend:TI
8325                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8326             (const_int 64))))
8327    (clobber (match_scratch:DI 3 "=1"))
8328    (clobber (reg:CC FLAGS_REG))]
8329   "TARGET_64BIT
8330    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8331   "imul{q}\t%2"
8332   [(set_attr "type" "imul")
8333    (set (attr "athlon_decode")
8334      (if_then_else (eq_attr "cpu" "athlon")
8335         (const_string "vector")
8336         (const_string "double")))
8337    (set_attr "amdfam10_decode" "double")
8338    (set_attr "mode" "DI")])
8339
8340 (define_expand "smulsi3_highpart"
8341   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8342                    (truncate:SI
8343                      (lshiftrt:DI
8344                        (mult:DI (sign_extend:DI
8345                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8346                                 (sign_extend:DI
8347                                   (match_operand:SI 2 "register_operand" "")))
8348                        (const_int 32))))
8349               (clobber (match_scratch:SI 3 ""))
8350               (clobber (reg:CC FLAGS_REG))])]
8351   ""
8352   "")
8353
8354 (define_insn "*smulsi3_highpart_insn"
8355   [(set (match_operand:SI 0 "register_operand" "=d")
8356         (truncate:SI
8357           (lshiftrt:DI
8358             (mult:DI (sign_extend:DI
8359                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8360                      (sign_extend:DI
8361                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8362             (const_int 32))))
8363    (clobber (match_scratch:SI 3 "=1"))
8364    (clobber (reg:CC FLAGS_REG))]
8365   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8366   "imul{l}\t%2"
8367   [(set_attr "type" "imul")
8368    (set (attr "athlon_decode")
8369      (if_then_else (eq_attr "cpu" "athlon")
8370         (const_string "vector")
8371         (const_string "double")))
8372    (set_attr "amdfam10_decode" "double")
8373    (set_attr "mode" "SI")])
8374
8375 (define_insn "*smulsi3_highpart_zext"
8376   [(set (match_operand:DI 0 "register_operand" "=d")
8377         (zero_extend:DI (truncate:SI
8378           (lshiftrt:DI
8379             (mult:DI (sign_extend:DI
8380                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8381                      (sign_extend:DI
8382                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8383             (const_int 32)))))
8384    (clobber (match_scratch:SI 3 "=1"))
8385    (clobber (reg:CC FLAGS_REG))]
8386   "TARGET_64BIT
8387    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8388   "imul{l}\t%2"
8389   [(set_attr "type" "imul")
8390    (set (attr "athlon_decode")
8391      (if_then_else (eq_attr "cpu" "athlon")
8392         (const_string "vector")
8393         (const_string "double")))
8394    (set_attr "amdfam10_decode" "double")
8395    (set_attr "mode" "SI")])
8396
8397 ;; The patterns that match these are at the end of this file.
8398
8399 (define_expand "mulxf3"
8400   [(set (match_operand:XF 0 "register_operand" "")
8401         (mult:XF (match_operand:XF 1 "register_operand" "")
8402                  (match_operand:XF 2 "register_operand" "")))]
8403   "TARGET_80387"
8404   "")
8405
8406 (define_expand "mul<mode>3"
8407   [(set (match_operand:MODEF 0 "register_operand" "")
8408         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8409                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8410   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8411   "")
8412
8413 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8414
8415 \f
8416 ;; Divide instructions
8417
8418 (define_insn "divqi3"
8419   [(set (match_operand:QI 0 "register_operand" "=a")
8420         (div:QI (match_operand:HI 1 "register_operand" "0")
8421                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8422    (clobber (reg:CC FLAGS_REG))]
8423   "TARGET_QIMODE_MATH"
8424   "idiv{b}\t%2"
8425   [(set_attr "type" "idiv")
8426    (set_attr "mode" "QI")])
8427
8428 (define_insn "udivqi3"
8429   [(set (match_operand:QI 0 "register_operand" "=a")
8430         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8431                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8432    (clobber (reg:CC FLAGS_REG))]
8433   "TARGET_QIMODE_MATH"
8434   "div{b}\t%2"
8435   [(set_attr "type" "idiv")
8436    (set_attr "mode" "QI")])
8437
8438 ;; The patterns that match these are at the end of this file.
8439
8440 (define_expand "divxf3"
8441   [(set (match_operand:XF 0 "register_operand" "")
8442         (div:XF (match_operand:XF 1 "register_operand" "")
8443                 (match_operand:XF 2 "register_operand" "")))]
8444   "TARGET_80387"
8445   "")
8446
8447 (define_expand "divdf3"
8448   [(set (match_operand:DF 0 "register_operand" "")
8449         (div:DF (match_operand:DF 1 "register_operand" "")
8450                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8451    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8452    "")
8453
8454 (define_expand "divsf3"
8455   [(set (match_operand:SF 0 "register_operand" "")
8456         (div:SF (match_operand:SF 1 "register_operand" "")
8457                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8458   "TARGET_80387 || TARGET_SSE_MATH"
8459 {
8460   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8461       && flag_finite_math_only && !flag_trapping_math
8462       && flag_unsafe_math_optimizations)
8463     {
8464       ix86_emit_swdivsf (operands[0], operands[1],
8465                          operands[2], SFmode);
8466       DONE;
8467     }
8468 })
8469 \f
8470 ;; Remainder instructions.
8471
8472 (define_expand "divmoddi4"
8473   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8474                    (div:DI (match_operand:DI 1 "register_operand" "")
8475                            (match_operand:DI 2 "nonimmediate_operand" "")))
8476               (set (match_operand:DI 3 "register_operand" "")
8477                    (mod:DI (match_dup 1) (match_dup 2)))
8478               (clobber (reg:CC FLAGS_REG))])]
8479   "TARGET_64BIT"
8480   "")
8481
8482 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8483 ;; Penalize eax case slightly because it results in worse scheduling
8484 ;; of code.
8485 (define_insn "*divmoddi4_nocltd_rex64"
8486   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8487         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8488                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8489    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8490         (mod:DI (match_dup 2) (match_dup 3)))
8491    (clobber (reg:CC FLAGS_REG))]
8492   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8493   "#"
8494   [(set_attr "type" "multi")])
8495
8496 (define_insn "*divmoddi4_cltd_rex64"
8497   [(set (match_operand:DI 0 "register_operand" "=a")
8498         (div:DI (match_operand:DI 2 "register_operand" "a")
8499                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8500    (set (match_operand:DI 1 "register_operand" "=&d")
8501         (mod:DI (match_dup 2) (match_dup 3)))
8502    (clobber (reg:CC FLAGS_REG))]
8503   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8504   "#"
8505   [(set_attr "type" "multi")])
8506
8507 (define_insn "*divmoddi_noext_rex64"
8508   [(set (match_operand:DI 0 "register_operand" "=a")
8509         (div:DI (match_operand:DI 1 "register_operand" "0")
8510                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8511    (set (match_operand:DI 3 "register_operand" "=d")
8512         (mod:DI (match_dup 1) (match_dup 2)))
8513    (use (match_operand:DI 4 "register_operand" "3"))
8514    (clobber (reg:CC FLAGS_REG))]
8515   "TARGET_64BIT"
8516   "idiv{q}\t%2"
8517   [(set_attr "type" "idiv")
8518    (set_attr "mode" "DI")])
8519
8520 (define_split
8521   [(set (match_operand:DI 0 "register_operand" "")
8522         (div:DI (match_operand:DI 1 "register_operand" "")
8523                 (match_operand:DI 2 "nonimmediate_operand" "")))
8524    (set (match_operand:DI 3 "register_operand" "")
8525         (mod:DI (match_dup 1) (match_dup 2)))
8526    (clobber (reg:CC FLAGS_REG))]
8527   "TARGET_64BIT && reload_completed"
8528   [(parallel [(set (match_dup 3)
8529                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8530               (clobber (reg:CC FLAGS_REG))])
8531    (parallel [(set (match_dup 0)
8532                    (div:DI (reg:DI 0) (match_dup 2)))
8533               (set (match_dup 3)
8534                    (mod:DI (reg:DI 0) (match_dup 2)))
8535               (use (match_dup 3))
8536               (clobber (reg:CC FLAGS_REG))])]
8537 {
8538   /* Avoid use of cltd in favor of a mov+shift.  */
8539   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8540     {
8541       if (true_regnum (operands[1]))
8542         emit_move_insn (operands[0], operands[1]);
8543       else
8544         emit_move_insn (operands[3], operands[1]);
8545       operands[4] = operands[3];
8546     }
8547   else
8548     {
8549       gcc_assert (!true_regnum (operands[1]));
8550       operands[4] = operands[1];
8551     }
8552 })
8553
8554
8555 (define_expand "divmodsi4"
8556   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8557                    (div:SI (match_operand:SI 1 "register_operand" "")
8558                            (match_operand:SI 2 "nonimmediate_operand" "")))
8559               (set (match_operand:SI 3 "register_operand" "")
8560                    (mod:SI (match_dup 1) (match_dup 2)))
8561               (clobber (reg:CC FLAGS_REG))])]
8562   ""
8563   "")
8564
8565 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8566 ;; Penalize eax case slightly because it results in worse scheduling
8567 ;; of code.
8568 (define_insn "*divmodsi4_nocltd"
8569   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8570         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8571                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8572    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8573         (mod:SI (match_dup 2) (match_dup 3)))
8574    (clobber (reg:CC FLAGS_REG))]
8575   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8576   "#"
8577   [(set_attr "type" "multi")])
8578
8579 (define_insn "*divmodsi4_cltd"
8580   [(set (match_operand:SI 0 "register_operand" "=a")
8581         (div:SI (match_operand:SI 2 "register_operand" "a")
8582                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8583    (set (match_operand:SI 1 "register_operand" "=&d")
8584         (mod:SI (match_dup 2) (match_dup 3)))
8585    (clobber (reg:CC FLAGS_REG))]
8586   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8587   "#"
8588   [(set_attr "type" "multi")])
8589
8590 (define_insn "*divmodsi_noext"
8591   [(set (match_operand:SI 0 "register_operand" "=a")
8592         (div:SI (match_operand:SI 1 "register_operand" "0")
8593                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8594    (set (match_operand:SI 3 "register_operand" "=d")
8595         (mod:SI (match_dup 1) (match_dup 2)))
8596    (use (match_operand:SI 4 "register_operand" "3"))
8597    (clobber (reg:CC FLAGS_REG))]
8598   ""
8599   "idiv{l}\t%2"
8600   [(set_attr "type" "idiv")
8601    (set_attr "mode" "SI")])
8602
8603 (define_split
8604   [(set (match_operand:SI 0 "register_operand" "")
8605         (div:SI (match_operand:SI 1 "register_operand" "")
8606                 (match_operand:SI 2 "nonimmediate_operand" "")))
8607    (set (match_operand:SI 3 "register_operand" "")
8608         (mod:SI (match_dup 1) (match_dup 2)))
8609    (clobber (reg:CC FLAGS_REG))]
8610   "reload_completed"
8611   [(parallel [(set (match_dup 3)
8612                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8613               (clobber (reg:CC FLAGS_REG))])
8614    (parallel [(set (match_dup 0)
8615                    (div:SI (reg:SI 0) (match_dup 2)))
8616               (set (match_dup 3)
8617                    (mod:SI (reg:SI 0) (match_dup 2)))
8618               (use (match_dup 3))
8619               (clobber (reg:CC FLAGS_REG))])]
8620 {
8621   /* Avoid use of cltd in favor of a mov+shift.  */
8622   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8623     {
8624       if (true_regnum (operands[1]))
8625         emit_move_insn (operands[0], operands[1]);
8626       else
8627         emit_move_insn (operands[3], operands[1]);
8628       operands[4] = operands[3];
8629     }
8630   else
8631     {
8632       gcc_assert (!true_regnum (operands[1]));
8633       operands[4] = operands[1];
8634     }
8635 })
8636 ;; %%% Split me.
8637 (define_insn "divmodhi4"
8638   [(set (match_operand:HI 0 "register_operand" "=a")
8639         (div:HI (match_operand:HI 1 "register_operand" "0")
8640                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8641    (set (match_operand:HI 3 "register_operand" "=&d")
8642         (mod:HI (match_dup 1) (match_dup 2)))
8643    (clobber (reg:CC FLAGS_REG))]
8644   "TARGET_HIMODE_MATH"
8645   "cwtd\;idiv{w}\t%2"
8646   [(set_attr "type" "multi")
8647    (set_attr "length_immediate" "0")
8648    (set_attr "mode" "SI")])
8649
8650 (define_insn "udivmoddi4"
8651   [(set (match_operand:DI 0 "register_operand" "=a")
8652         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8653                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8654    (set (match_operand:DI 3 "register_operand" "=&d")
8655         (umod:DI (match_dup 1) (match_dup 2)))
8656    (clobber (reg:CC FLAGS_REG))]
8657   "TARGET_64BIT"
8658   "xor{q}\t%3, %3\;div{q}\t%2"
8659   [(set_attr "type" "multi")
8660    (set_attr "length_immediate" "0")
8661    (set_attr "mode" "DI")])
8662
8663 (define_insn "*udivmoddi4_noext"
8664   [(set (match_operand:DI 0 "register_operand" "=a")
8665         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8666                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8667    (set (match_operand:DI 3 "register_operand" "=d")
8668         (umod:DI (match_dup 1) (match_dup 2)))
8669    (use (match_dup 3))
8670    (clobber (reg:CC FLAGS_REG))]
8671   "TARGET_64BIT"
8672   "div{q}\t%2"
8673   [(set_attr "type" "idiv")
8674    (set_attr "mode" "DI")])
8675
8676 (define_split
8677   [(set (match_operand:DI 0 "register_operand" "")
8678         (udiv:DI (match_operand:DI 1 "register_operand" "")
8679                  (match_operand:DI 2 "nonimmediate_operand" "")))
8680    (set (match_operand:DI 3 "register_operand" "")
8681         (umod:DI (match_dup 1) (match_dup 2)))
8682    (clobber (reg:CC FLAGS_REG))]
8683   "TARGET_64BIT && reload_completed"
8684   [(set (match_dup 3) (const_int 0))
8685    (parallel [(set (match_dup 0)
8686                    (udiv:DI (match_dup 1) (match_dup 2)))
8687               (set (match_dup 3)
8688                    (umod:DI (match_dup 1) (match_dup 2)))
8689               (use (match_dup 3))
8690               (clobber (reg:CC FLAGS_REG))])]
8691   "")
8692
8693 (define_insn "udivmodsi4"
8694   [(set (match_operand:SI 0 "register_operand" "=a")
8695         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8696                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8697    (set (match_operand:SI 3 "register_operand" "=&d")
8698         (umod:SI (match_dup 1) (match_dup 2)))
8699    (clobber (reg:CC FLAGS_REG))]
8700   ""
8701   "xor{l}\t%3, %3\;div{l}\t%2"
8702   [(set_attr "type" "multi")
8703    (set_attr "length_immediate" "0")
8704    (set_attr "mode" "SI")])
8705
8706 (define_insn "*udivmodsi4_noext"
8707   [(set (match_operand:SI 0 "register_operand" "=a")
8708         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8709                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8710    (set (match_operand:SI 3 "register_operand" "=d")
8711         (umod:SI (match_dup 1) (match_dup 2)))
8712    (use (match_dup 3))
8713    (clobber (reg:CC FLAGS_REG))]
8714   ""
8715   "div{l}\t%2"
8716   [(set_attr "type" "idiv")
8717    (set_attr "mode" "SI")])
8718
8719 (define_split
8720   [(set (match_operand:SI 0 "register_operand" "")
8721         (udiv:SI (match_operand:SI 1 "register_operand" "")
8722                  (match_operand:SI 2 "nonimmediate_operand" "")))
8723    (set (match_operand:SI 3 "register_operand" "")
8724         (umod:SI (match_dup 1) (match_dup 2)))
8725    (clobber (reg:CC FLAGS_REG))]
8726   "reload_completed"
8727   [(set (match_dup 3) (const_int 0))
8728    (parallel [(set (match_dup 0)
8729                    (udiv:SI (match_dup 1) (match_dup 2)))
8730               (set (match_dup 3)
8731                    (umod:SI (match_dup 1) (match_dup 2)))
8732               (use (match_dup 3))
8733               (clobber (reg:CC FLAGS_REG))])]
8734   "")
8735
8736 (define_expand "udivmodhi4"
8737   [(set (match_dup 4) (const_int 0))
8738    (parallel [(set (match_operand:HI 0 "register_operand" "")
8739                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8740                             (match_operand:HI 2 "nonimmediate_operand" "")))
8741               (set (match_operand:HI 3 "register_operand" "")
8742                    (umod:HI (match_dup 1) (match_dup 2)))
8743               (use (match_dup 4))
8744               (clobber (reg:CC FLAGS_REG))])]
8745   "TARGET_HIMODE_MATH"
8746   "operands[4] = gen_reg_rtx (HImode);")
8747
8748 (define_insn "*udivmodhi_noext"
8749   [(set (match_operand:HI 0 "register_operand" "=a")
8750         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8751                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8752    (set (match_operand:HI 3 "register_operand" "=d")
8753         (umod:HI (match_dup 1) (match_dup 2)))
8754    (use (match_operand:HI 4 "register_operand" "3"))
8755    (clobber (reg:CC FLAGS_REG))]
8756   ""
8757   "div{w}\t%2"
8758   [(set_attr "type" "idiv")
8759    (set_attr "mode" "HI")])
8760
8761 ;; We cannot use div/idiv for double division, because it causes
8762 ;; "division by zero" on the overflow and that's not what we expect
8763 ;; from truncate.  Because true (non truncating) double division is
8764 ;; never generated, we can't create this insn anyway.
8765 ;
8766 ;(define_insn ""
8767 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8768 ;       (truncate:SI
8769 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8770 ;                  (zero_extend:DI
8771 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8772 ;   (set (match_operand:SI 3 "register_operand" "=d")
8773 ;       (truncate:SI
8774 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8775 ;   (clobber (reg:CC FLAGS_REG))]
8776 ;  ""
8777 ;  "div{l}\t{%2, %0|%0, %2}"
8778 ;  [(set_attr "type" "idiv")])
8779 \f
8780 ;;- Logical AND instructions
8781
8782 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8783 ;; Note that this excludes ah.
8784
8785 (define_insn "*testdi_1_rex64"
8786   [(set (reg FLAGS_REG)
8787         (compare
8788           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8789                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8790           (const_int 0)))]
8791   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8792    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8793   "@
8794    test{l}\t{%k1, %k0|%k0, %k1}
8795    test{l}\t{%k1, %k0|%k0, %k1}
8796    test{q}\t{%1, %0|%0, %1}
8797    test{q}\t{%1, %0|%0, %1}
8798    test{q}\t{%1, %0|%0, %1}"
8799   [(set_attr "type" "test")
8800    (set_attr "modrm" "0,1,0,1,1")
8801    (set_attr "mode" "SI,SI,DI,DI,DI")
8802    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8803
8804 (define_insn "testsi_1"
8805   [(set (reg FLAGS_REG)
8806         (compare
8807           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8808                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8809           (const_int 0)))]
8810   "ix86_match_ccmode (insn, CCNOmode)
8811    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8812   "test{l}\t{%1, %0|%0, %1}"
8813   [(set_attr "type" "test")
8814    (set_attr "modrm" "0,1,1")
8815    (set_attr "mode" "SI")
8816    (set_attr "pent_pair" "uv,np,uv")])
8817
8818 (define_expand "testsi_ccno_1"
8819   [(set (reg:CCNO FLAGS_REG)
8820         (compare:CCNO
8821           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8822                   (match_operand:SI 1 "nonmemory_operand" ""))
8823           (const_int 0)))]
8824   ""
8825   "")
8826
8827 (define_insn "*testhi_1"
8828   [(set (reg FLAGS_REG)
8829         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8830                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8831                  (const_int 0)))]
8832   "ix86_match_ccmode (insn, CCNOmode)
8833    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8834   "test{w}\t{%1, %0|%0, %1}"
8835   [(set_attr "type" "test")
8836    (set_attr "modrm" "0,1,1")
8837    (set_attr "mode" "HI")
8838    (set_attr "pent_pair" "uv,np,uv")])
8839
8840 (define_expand "testqi_ccz_1"
8841   [(set (reg:CCZ FLAGS_REG)
8842         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8843                              (match_operand:QI 1 "nonmemory_operand" ""))
8844                  (const_int 0)))]
8845   ""
8846   "")
8847
8848 (define_insn "*testqi_1_maybe_si"
8849   [(set (reg FLAGS_REG)
8850         (compare
8851           (and:QI
8852             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8853             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8854           (const_int 0)))]
8855    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8856     && ix86_match_ccmode (insn,
8857                          CONST_INT_P (operands[1])
8858                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8859 {
8860   if (which_alternative == 3)
8861     {
8862       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8863         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8864       return "test{l}\t{%1, %k0|%k0, %1}";
8865     }
8866   return "test{b}\t{%1, %0|%0, %1}";
8867 }
8868   [(set_attr "type" "test")
8869    (set_attr "modrm" "0,1,1,1")
8870    (set_attr "mode" "QI,QI,QI,SI")
8871    (set_attr "pent_pair" "uv,np,uv,np")])
8872
8873 (define_insn "*testqi_1"
8874   [(set (reg FLAGS_REG)
8875         (compare
8876           (and:QI
8877             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8878             (match_operand:QI 1 "general_operand" "n,n,qn"))
8879           (const_int 0)))]
8880   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8881    && ix86_match_ccmode (insn, CCNOmode)"
8882   "test{b}\t{%1, %0|%0, %1}"
8883   [(set_attr "type" "test")
8884    (set_attr "modrm" "0,1,1")
8885    (set_attr "mode" "QI")
8886    (set_attr "pent_pair" "uv,np,uv")])
8887
8888 (define_expand "testqi_ext_ccno_0"
8889   [(set (reg:CCNO FLAGS_REG)
8890         (compare:CCNO
8891           (and:SI
8892             (zero_extract:SI
8893               (match_operand 0 "ext_register_operand" "")
8894               (const_int 8)
8895               (const_int 8))
8896             (match_operand 1 "const_int_operand" ""))
8897           (const_int 0)))]
8898   ""
8899   "")
8900
8901 (define_insn "*testqi_ext_0"
8902   [(set (reg FLAGS_REG)
8903         (compare
8904           (and:SI
8905             (zero_extract:SI
8906               (match_operand 0 "ext_register_operand" "Q")
8907               (const_int 8)
8908               (const_int 8))
8909             (match_operand 1 "const_int_operand" "n"))
8910           (const_int 0)))]
8911   "ix86_match_ccmode (insn, CCNOmode)"
8912   "test{b}\t{%1, %h0|%h0, %1}"
8913   [(set_attr "type" "test")
8914    (set_attr "mode" "QI")
8915    (set_attr "length_immediate" "1")
8916    (set_attr "pent_pair" "np")])
8917
8918 (define_insn "*testqi_ext_1"
8919   [(set (reg FLAGS_REG)
8920         (compare
8921           (and:SI
8922             (zero_extract:SI
8923               (match_operand 0 "ext_register_operand" "Q")
8924               (const_int 8)
8925               (const_int 8))
8926             (zero_extend:SI
8927               (match_operand:QI 1 "general_operand" "Qm")))
8928           (const_int 0)))]
8929   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8930    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8931   "test{b}\t{%1, %h0|%h0, %1}"
8932   [(set_attr "type" "test")
8933    (set_attr "mode" "QI")])
8934
8935 (define_insn "*testqi_ext_1_rex64"
8936   [(set (reg FLAGS_REG)
8937         (compare
8938           (and:SI
8939             (zero_extract:SI
8940               (match_operand 0 "ext_register_operand" "Q")
8941               (const_int 8)
8942               (const_int 8))
8943             (zero_extend:SI
8944               (match_operand:QI 1 "register_operand" "Q")))
8945           (const_int 0)))]
8946   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8947   "test{b}\t{%1, %h0|%h0, %1}"
8948   [(set_attr "type" "test")
8949    (set_attr "mode" "QI")])
8950
8951 (define_insn "*testqi_ext_2"
8952   [(set (reg FLAGS_REG)
8953         (compare
8954           (and:SI
8955             (zero_extract:SI
8956               (match_operand 0 "ext_register_operand" "Q")
8957               (const_int 8)
8958               (const_int 8))
8959             (zero_extract:SI
8960               (match_operand 1 "ext_register_operand" "Q")
8961               (const_int 8)
8962               (const_int 8)))
8963           (const_int 0)))]
8964   "ix86_match_ccmode (insn, CCNOmode)"
8965   "test{b}\t{%h1, %h0|%h0, %h1}"
8966   [(set_attr "type" "test")
8967    (set_attr "mode" "QI")])
8968
8969 ;; Combine likes to form bit extractions for some tests.  Humor it.
8970 (define_insn "*testqi_ext_3"
8971   [(set (reg FLAGS_REG)
8972         (compare (zero_extract:SI
8973                    (match_operand 0 "nonimmediate_operand" "rm")
8974                    (match_operand:SI 1 "const_int_operand" "")
8975                    (match_operand:SI 2 "const_int_operand" ""))
8976                  (const_int 0)))]
8977   "ix86_match_ccmode (insn, CCNOmode)
8978    && INTVAL (operands[1]) > 0
8979    && INTVAL (operands[2]) >= 0
8980    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8981    && (GET_MODE (operands[0]) == SImode
8982        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8983        || GET_MODE (operands[0]) == HImode
8984        || GET_MODE (operands[0]) == QImode)"
8985   "#")
8986
8987 (define_insn "*testqi_ext_3_rex64"
8988   [(set (reg FLAGS_REG)
8989         (compare (zero_extract:DI
8990                    (match_operand 0 "nonimmediate_operand" "rm")
8991                    (match_operand:DI 1 "const_int_operand" "")
8992                    (match_operand:DI 2 "const_int_operand" ""))
8993                  (const_int 0)))]
8994   "TARGET_64BIT
8995    && ix86_match_ccmode (insn, CCNOmode)
8996    && INTVAL (operands[1]) > 0
8997    && INTVAL (operands[2]) >= 0
8998    /* Ensure that resulting mask is zero or sign extended operand.  */
8999    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9000        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9001            && INTVAL (operands[1]) > 32))
9002    && (GET_MODE (operands[0]) == SImode
9003        || GET_MODE (operands[0]) == DImode
9004        || GET_MODE (operands[0]) == HImode
9005        || GET_MODE (operands[0]) == QImode)"
9006   "#")
9007
9008 (define_split
9009   [(set (match_operand 0 "flags_reg_operand" "")
9010         (match_operator 1 "compare_operator"
9011           [(zero_extract
9012              (match_operand 2 "nonimmediate_operand" "")
9013              (match_operand 3 "const_int_operand" "")
9014              (match_operand 4 "const_int_operand" ""))
9015            (const_int 0)]))]
9016   "ix86_match_ccmode (insn, CCNOmode)"
9017   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9018 {
9019   rtx val = operands[2];
9020   HOST_WIDE_INT len = INTVAL (operands[3]);
9021   HOST_WIDE_INT pos = INTVAL (operands[4]);
9022   HOST_WIDE_INT mask;
9023   enum machine_mode mode, submode;
9024
9025   mode = GET_MODE (val);
9026   if (MEM_P (val))
9027     {
9028       /* ??? Combine likes to put non-volatile mem extractions in QImode
9029          no matter the size of the test.  So find a mode that works.  */
9030       if (! MEM_VOLATILE_P (val))
9031         {
9032           mode = smallest_mode_for_size (pos + len, MODE_INT);
9033           val = adjust_address (val, mode, 0);
9034         }
9035     }
9036   else if (GET_CODE (val) == SUBREG
9037            && (submode = GET_MODE (SUBREG_REG (val)),
9038                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9039            && pos + len <= GET_MODE_BITSIZE (submode)
9040            && GET_MODE_CLASS (submode) == MODE_INT)
9041     {
9042       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9043       mode = submode;
9044       val = SUBREG_REG (val);
9045     }
9046   else if (mode == HImode && pos + len <= 8)
9047     {
9048       /* Small HImode tests can be converted to QImode.  */
9049       mode = QImode;
9050       val = gen_lowpart (QImode, val);
9051     }
9052
9053   if (len == HOST_BITS_PER_WIDE_INT)
9054     mask = -1;
9055   else
9056     mask = ((HOST_WIDE_INT)1 << len) - 1;
9057   mask <<= pos;
9058
9059   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9060 })
9061
9062 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9063 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9064 ;; this is relatively important trick.
9065 ;; Do the conversion only post-reload to avoid limiting of the register class
9066 ;; to QI regs.
9067 (define_split
9068   [(set (match_operand 0 "flags_reg_operand" "")
9069         (match_operator 1 "compare_operator"
9070           [(and (match_operand 2 "register_operand" "")
9071                 (match_operand 3 "const_int_operand" ""))
9072            (const_int 0)]))]
9073    "reload_completed
9074     && QI_REG_P (operands[2])
9075     && GET_MODE (operands[2]) != QImode
9076     && ((ix86_match_ccmode (insn, CCZmode)
9077          && !(INTVAL (operands[3]) & ~(255 << 8)))
9078         || (ix86_match_ccmode (insn, CCNOmode)
9079             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9080   [(set (match_dup 0)
9081         (match_op_dup 1
9082           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9083                    (match_dup 3))
9084            (const_int 0)]))]
9085   "operands[2] = gen_lowpart (SImode, operands[2]);
9086    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9087
9088 (define_split
9089   [(set (match_operand 0 "flags_reg_operand" "")
9090         (match_operator 1 "compare_operator"
9091           [(and (match_operand 2 "nonimmediate_operand" "")
9092                 (match_operand 3 "const_int_operand" ""))
9093            (const_int 0)]))]
9094    "reload_completed
9095     && GET_MODE (operands[2]) != QImode
9096     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9097     && ((ix86_match_ccmode (insn, CCZmode)
9098          && !(INTVAL (operands[3]) & ~255))
9099         || (ix86_match_ccmode (insn, CCNOmode)
9100             && !(INTVAL (operands[3]) & ~127)))"
9101   [(set (match_dup 0)
9102         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9103                          (const_int 0)]))]
9104   "operands[2] = gen_lowpart (QImode, operands[2]);
9105    operands[3] = gen_lowpart (QImode, operands[3]);")
9106
9107
9108 ;; %%% This used to optimize known byte-wide and operations to memory,
9109 ;; and sometimes to QImode registers.  If this is considered useful,
9110 ;; it should be done with splitters.
9111
9112 (define_expand "anddi3"
9113   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9114         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9115                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9116   "TARGET_64BIT"
9117   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9118
9119 (define_insn "*anddi_1_rex64"
9120   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9121         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9122                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9123    (clobber (reg:CC FLAGS_REG))]
9124   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9125 {
9126   switch (get_attr_type (insn))
9127     {
9128     case TYPE_IMOVX:
9129       {
9130         enum machine_mode mode;
9131
9132         gcc_assert (CONST_INT_P (operands[2]));
9133         if (INTVAL (operands[2]) == 0xff)
9134           mode = QImode;
9135         else
9136           {
9137             gcc_assert (INTVAL (operands[2]) == 0xffff);
9138             mode = HImode;
9139           }
9140
9141         operands[1] = gen_lowpart (mode, operands[1]);
9142         if (mode == QImode)
9143           return "movz{bq|x}\t{%1,%0|%0, %1}";
9144         else
9145           return "movz{wq|x}\t{%1,%0|%0, %1}";
9146       }
9147
9148     default:
9149       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9150       if (get_attr_mode (insn) == MODE_SI)
9151         return "and{l}\t{%k2, %k0|%k0, %k2}";
9152       else
9153         return "and{q}\t{%2, %0|%0, %2}";
9154     }
9155 }
9156   [(set_attr "type" "alu,alu,alu,imovx")
9157    (set_attr "length_immediate" "*,*,*,0")
9158    (set_attr "mode" "SI,DI,DI,DI")])
9159
9160 (define_insn "*anddi_2"
9161   [(set (reg FLAGS_REG)
9162         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9163                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9164                  (const_int 0)))
9165    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9166         (and:DI (match_dup 1) (match_dup 2)))]
9167   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9168    && ix86_binary_operator_ok (AND, DImode, operands)"
9169   "@
9170    and{l}\t{%k2, %k0|%k0, %k2}
9171    and{q}\t{%2, %0|%0, %2}
9172    and{q}\t{%2, %0|%0, %2}"
9173   [(set_attr "type" "alu")
9174    (set_attr "mode" "SI,DI,DI")])
9175
9176 (define_expand "andsi3"
9177   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9178         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9179                 (match_operand:SI 2 "general_operand" "")))]
9180   ""
9181   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9182
9183 (define_insn "*andsi_1"
9184   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9185         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9186                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9187    (clobber (reg:CC FLAGS_REG))]
9188   "ix86_binary_operator_ok (AND, SImode, operands)"
9189 {
9190   switch (get_attr_type (insn))
9191     {
9192     case TYPE_IMOVX:
9193       {
9194         enum machine_mode mode;
9195
9196         gcc_assert (CONST_INT_P (operands[2]));
9197         if (INTVAL (operands[2]) == 0xff)
9198           mode = QImode;
9199         else
9200           {
9201             gcc_assert (INTVAL (operands[2]) == 0xffff);
9202             mode = HImode;
9203           }
9204
9205         operands[1] = gen_lowpart (mode, operands[1]);
9206         if (mode == QImode)
9207           return "movz{bl|x}\t{%1,%0|%0, %1}";
9208         else
9209           return "movz{wl|x}\t{%1,%0|%0, %1}";
9210       }
9211
9212     default:
9213       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9214       return "and{l}\t{%2, %0|%0, %2}";
9215     }
9216 }
9217   [(set_attr "type" "alu,alu,imovx")
9218    (set_attr "length_immediate" "*,*,0")
9219    (set_attr "mode" "SI")])
9220
9221 (define_split
9222   [(set (match_operand 0 "register_operand" "")
9223         (and (match_dup 0)
9224              (const_int -65536)))
9225    (clobber (reg:CC FLAGS_REG))]
9226   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9227   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9228   "operands[1] = gen_lowpart (HImode, operands[0]);")
9229
9230 (define_split
9231   [(set (match_operand 0 "ext_register_operand" "")
9232         (and (match_dup 0)
9233              (const_int -256)))
9234    (clobber (reg:CC FLAGS_REG))]
9235   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9236   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9237   "operands[1] = gen_lowpart (QImode, operands[0]);")
9238
9239 (define_split
9240   [(set (match_operand 0 "ext_register_operand" "")
9241         (and (match_dup 0)
9242              (const_int -65281)))
9243    (clobber (reg:CC FLAGS_REG))]
9244   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9245   [(parallel [(set (zero_extract:SI (match_dup 0)
9246                                     (const_int 8)
9247                                     (const_int 8))
9248                    (xor:SI
9249                      (zero_extract:SI (match_dup 0)
9250                                       (const_int 8)
9251                                       (const_int 8))
9252                      (zero_extract:SI (match_dup 0)
9253                                       (const_int 8)
9254                                       (const_int 8))))
9255               (clobber (reg:CC FLAGS_REG))])]
9256   "operands[0] = gen_lowpart (SImode, operands[0]);")
9257
9258 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9259 (define_insn "*andsi_1_zext"
9260   [(set (match_operand:DI 0 "register_operand" "=r")
9261         (zero_extend:DI
9262           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9263                   (match_operand:SI 2 "general_operand" "g"))))
9264    (clobber (reg:CC FLAGS_REG))]
9265   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9266   "and{l}\t{%2, %k0|%k0, %2}"
9267   [(set_attr "type" "alu")
9268    (set_attr "mode" "SI")])
9269
9270 (define_insn "*andsi_2"
9271   [(set (reg FLAGS_REG)
9272         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9273                          (match_operand:SI 2 "general_operand" "g,ri"))
9274                  (const_int 0)))
9275    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9276         (and:SI (match_dup 1) (match_dup 2)))]
9277   "ix86_match_ccmode (insn, CCNOmode)
9278    && ix86_binary_operator_ok (AND, SImode, operands)"
9279   "and{l}\t{%2, %0|%0, %2}"
9280   [(set_attr "type" "alu")
9281    (set_attr "mode" "SI")])
9282
9283 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9284 (define_insn "*andsi_2_zext"
9285   [(set (reg FLAGS_REG)
9286         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9287                          (match_operand:SI 2 "general_operand" "g"))
9288                  (const_int 0)))
9289    (set (match_operand:DI 0 "register_operand" "=r")
9290         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9291   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9292    && ix86_binary_operator_ok (AND, SImode, operands)"
9293   "and{l}\t{%2, %k0|%k0, %2}"
9294   [(set_attr "type" "alu")
9295    (set_attr "mode" "SI")])
9296
9297 (define_expand "andhi3"
9298   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9299         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9300                 (match_operand:HI 2 "general_operand" "")))]
9301   "TARGET_HIMODE_MATH"
9302   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9303
9304 (define_insn "*andhi_1"
9305   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9306         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9307                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9308    (clobber (reg:CC FLAGS_REG))]
9309   "ix86_binary_operator_ok (AND, HImode, operands)"
9310 {
9311   switch (get_attr_type (insn))
9312     {
9313     case TYPE_IMOVX:
9314       gcc_assert (CONST_INT_P (operands[2]));
9315       gcc_assert (INTVAL (operands[2]) == 0xff);
9316       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9317
9318     default:
9319       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9320
9321       return "and{w}\t{%2, %0|%0, %2}";
9322     }
9323 }
9324   [(set_attr "type" "alu,alu,imovx")
9325    (set_attr "length_immediate" "*,*,0")
9326    (set_attr "mode" "HI,HI,SI")])
9327
9328 (define_insn "*andhi_2"
9329   [(set (reg FLAGS_REG)
9330         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9331                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9332                  (const_int 0)))
9333    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9334         (and:HI (match_dup 1) (match_dup 2)))]
9335   "ix86_match_ccmode (insn, CCNOmode)
9336    && ix86_binary_operator_ok (AND, HImode, operands)"
9337   "and{w}\t{%2, %0|%0, %2}"
9338   [(set_attr "type" "alu")
9339    (set_attr "mode" "HI")])
9340
9341 (define_expand "andqi3"
9342   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9343         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9344                 (match_operand:QI 2 "general_operand" "")))]
9345   "TARGET_QIMODE_MATH"
9346   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9347
9348 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9349 (define_insn "*andqi_1"
9350   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9351         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9352                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9353    (clobber (reg:CC FLAGS_REG))]
9354   "ix86_binary_operator_ok (AND, QImode, operands)"
9355   "@
9356    and{b}\t{%2, %0|%0, %2}
9357    and{b}\t{%2, %0|%0, %2}
9358    and{l}\t{%k2, %k0|%k0, %k2}"
9359   [(set_attr "type" "alu")
9360    (set_attr "mode" "QI,QI,SI")])
9361
9362 (define_insn "*andqi_1_slp"
9363   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9364         (and:QI (match_dup 0)
9365                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9366    (clobber (reg:CC FLAGS_REG))]
9367   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9368    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9369   "and{b}\t{%1, %0|%0, %1}"
9370   [(set_attr "type" "alu1")
9371    (set_attr "mode" "QI")])
9372
9373 (define_insn "*andqi_2_maybe_si"
9374   [(set (reg FLAGS_REG)
9375         (compare (and:QI
9376                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9377                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9378                  (const_int 0)))
9379    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9380         (and:QI (match_dup 1) (match_dup 2)))]
9381   "ix86_binary_operator_ok (AND, QImode, operands)
9382    && ix86_match_ccmode (insn,
9383                          CONST_INT_P (operands[2])
9384                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9385 {
9386   if (which_alternative == 2)
9387     {
9388       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9389         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9390       return "and{l}\t{%2, %k0|%k0, %2}";
9391     }
9392   return "and{b}\t{%2, %0|%0, %2}";
9393 }
9394   [(set_attr "type" "alu")
9395    (set_attr "mode" "QI,QI,SI")])
9396
9397 (define_insn "*andqi_2"
9398   [(set (reg FLAGS_REG)
9399         (compare (and:QI
9400                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9401                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9402                  (const_int 0)))
9403    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9404         (and:QI (match_dup 1) (match_dup 2)))]
9405   "ix86_match_ccmode (insn, CCNOmode)
9406    && ix86_binary_operator_ok (AND, QImode, operands)"
9407   "and{b}\t{%2, %0|%0, %2}"
9408   [(set_attr "type" "alu")
9409    (set_attr "mode" "QI")])
9410
9411 (define_insn "*andqi_2_slp"
9412   [(set (reg FLAGS_REG)
9413         (compare (and:QI
9414                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9415                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9416                  (const_int 0)))
9417    (set (strict_low_part (match_dup 0))
9418         (and:QI (match_dup 0) (match_dup 1)))]
9419   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9420    && ix86_match_ccmode (insn, CCNOmode)
9421    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9422   "and{b}\t{%1, %0|%0, %1}"
9423   [(set_attr "type" "alu1")
9424    (set_attr "mode" "QI")])
9425
9426 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9427 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9428 ;; for a QImode operand, which of course failed.
9429
9430 (define_insn "andqi_ext_0"
9431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9432                          (const_int 8)
9433                          (const_int 8))
9434         (and:SI
9435           (zero_extract:SI
9436             (match_operand 1 "ext_register_operand" "0")
9437             (const_int 8)
9438             (const_int 8))
9439           (match_operand 2 "const_int_operand" "n")))
9440    (clobber (reg:CC FLAGS_REG))]
9441   ""
9442   "and{b}\t{%2, %h0|%h0, %2}"
9443   [(set_attr "type" "alu")
9444    (set_attr "length_immediate" "1")
9445    (set_attr "mode" "QI")])
9446
9447 ;; Generated by peephole translating test to and.  This shows up
9448 ;; often in fp comparisons.
9449
9450 (define_insn "*andqi_ext_0_cc"
9451   [(set (reg FLAGS_REG)
9452         (compare
9453           (and:SI
9454             (zero_extract:SI
9455               (match_operand 1 "ext_register_operand" "0")
9456               (const_int 8)
9457               (const_int 8))
9458             (match_operand 2 "const_int_operand" "n"))
9459           (const_int 0)))
9460    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9461                          (const_int 8)
9462                          (const_int 8))
9463         (and:SI
9464           (zero_extract:SI
9465             (match_dup 1)
9466             (const_int 8)
9467             (const_int 8))
9468           (match_dup 2)))]
9469   "ix86_match_ccmode (insn, CCNOmode)"
9470   "and{b}\t{%2, %h0|%h0, %2}"
9471   [(set_attr "type" "alu")
9472    (set_attr "length_immediate" "1")
9473    (set_attr "mode" "QI")])
9474
9475 (define_insn "*andqi_ext_1"
9476   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9477                          (const_int 8)
9478                          (const_int 8))
9479         (and:SI
9480           (zero_extract:SI
9481             (match_operand 1 "ext_register_operand" "0")
9482             (const_int 8)
9483             (const_int 8))
9484           (zero_extend:SI
9485             (match_operand:QI 2 "general_operand" "Qm"))))
9486    (clobber (reg:CC FLAGS_REG))]
9487   "!TARGET_64BIT"
9488   "and{b}\t{%2, %h0|%h0, %2}"
9489   [(set_attr "type" "alu")
9490    (set_attr "length_immediate" "0")
9491    (set_attr "mode" "QI")])
9492
9493 (define_insn "*andqi_ext_1_rex64"
9494   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9495                          (const_int 8)
9496                          (const_int 8))
9497         (and:SI
9498           (zero_extract:SI
9499             (match_operand 1 "ext_register_operand" "0")
9500             (const_int 8)
9501             (const_int 8))
9502           (zero_extend:SI
9503             (match_operand 2 "ext_register_operand" "Q"))))
9504    (clobber (reg:CC FLAGS_REG))]
9505   "TARGET_64BIT"
9506   "and{b}\t{%2, %h0|%h0, %2}"
9507   [(set_attr "type" "alu")
9508    (set_attr "length_immediate" "0")
9509    (set_attr "mode" "QI")])
9510
9511 (define_insn "*andqi_ext_2"
9512   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9513                          (const_int 8)
9514                          (const_int 8))
9515         (and:SI
9516           (zero_extract:SI
9517             (match_operand 1 "ext_register_operand" "%0")
9518             (const_int 8)
9519             (const_int 8))
9520           (zero_extract:SI
9521             (match_operand 2 "ext_register_operand" "Q")
9522             (const_int 8)
9523             (const_int 8))))
9524    (clobber (reg:CC FLAGS_REG))]
9525   ""
9526   "and{b}\t{%h2, %h0|%h0, %h2}"
9527   [(set_attr "type" "alu")
9528    (set_attr "length_immediate" "0")
9529    (set_attr "mode" "QI")])
9530
9531 ;; Convert wide AND instructions with immediate operand to shorter QImode
9532 ;; equivalents when possible.
9533 ;; Don't do the splitting with memory operands, since it introduces risk
9534 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9535 ;; for size, but that can (should?) be handled by generic code instead.
9536 (define_split
9537   [(set (match_operand 0 "register_operand" "")
9538         (and (match_operand 1 "register_operand" "")
9539              (match_operand 2 "const_int_operand" "")))
9540    (clobber (reg:CC FLAGS_REG))]
9541    "reload_completed
9542     && QI_REG_P (operands[0])
9543     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9544     && !(~INTVAL (operands[2]) & ~(255 << 8))
9545     && GET_MODE (operands[0]) != QImode"
9546   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9547                    (and:SI (zero_extract:SI (match_dup 1)
9548                                             (const_int 8) (const_int 8))
9549                            (match_dup 2)))
9550               (clobber (reg:CC FLAGS_REG))])]
9551   "operands[0] = gen_lowpart (SImode, operands[0]);
9552    operands[1] = gen_lowpart (SImode, operands[1]);
9553    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9554
9555 ;; Since AND can be encoded with sign extended immediate, this is only
9556 ;; profitable when 7th bit is not set.
9557 (define_split
9558   [(set (match_operand 0 "register_operand" "")
9559         (and (match_operand 1 "general_operand" "")
9560              (match_operand 2 "const_int_operand" "")))
9561    (clobber (reg:CC FLAGS_REG))]
9562    "reload_completed
9563     && ANY_QI_REG_P (operands[0])
9564     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9565     && !(~INTVAL (operands[2]) & ~255)
9566     && !(INTVAL (operands[2]) & 128)
9567     && GET_MODE (operands[0]) != QImode"
9568   [(parallel [(set (strict_low_part (match_dup 0))
9569                    (and:QI (match_dup 1)
9570                            (match_dup 2)))
9571               (clobber (reg:CC FLAGS_REG))])]
9572   "operands[0] = gen_lowpart (QImode, operands[0]);
9573    operands[1] = gen_lowpart (QImode, operands[1]);
9574    operands[2] = gen_lowpart (QImode, operands[2]);")
9575 \f
9576 ;; Logical inclusive OR instructions
9577
9578 ;; %%% This used to optimize known byte-wide and operations to memory.
9579 ;; If this is considered useful, it should be done with splitters.
9580
9581 (define_expand "iordi3"
9582   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9583         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9584                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9585   "TARGET_64BIT"
9586   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9587
9588 (define_insn "*iordi_1_rex64"
9589   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9590         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9591                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9592    (clobber (reg:CC FLAGS_REG))]
9593   "TARGET_64BIT
9594    && ix86_binary_operator_ok (IOR, DImode, operands)"
9595   "or{q}\t{%2, %0|%0, %2}"
9596   [(set_attr "type" "alu")
9597    (set_attr "mode" "DI")])
9598
9599 (define_insn "*iordi_2_rex64"
9600   [(set (reg FLAGS_REG)
9601         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9602                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9603                  (const_int 0)))
9604    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9605         (ior:DI (match_dup 1) (match_dup 2)))]
9606   "TARGET_64BIT
9607    && ix86_match_ccmode (insn, CCNOmode)
9608    && ix86_binary_operator_ok (IOR, DImode, operands)"
9609   "or{q}\t{%2, %0|%0, %2}"
9610   [(set_attr "type" "alu")
9611    (set_attr "mode" "DI")])
9612
9613 (define_insn "*iordi_3_rex64"
9614   [(set (reg FLAGS_REG)
9615         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9616                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9617                  (const_int 0)))
9618    (clobber (match_scratch:DI 0 "=r"))]
9619   "TARGET_64BIT
9620    && ix86_match_ccmode (insn, CCNOmode)
9621    && ix86_binary_operator_ok (IOR, DImode, operands)"
9622   "or{q}\t{%2, %0|%0, %2}"
9623   [(set_attr "type" "alu")
9624    (set_attr "mode" "DI")])
9625
9626
9627 (define_expand "iorsi3"
9628   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9629         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9630                 (match_operand:SI 2 "general_operand" "")))]
9631   ""
9632   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9633
9634 (define_insn "*iorsi_1"
9635   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9636         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9637                 (match_operand:SI 2 "general_operand" "ri,g")))
9638    (clobber (reg:CC FLAGS_REG))]
9639   "ix86_binary_operator_ok (IOR, SImode, operands)"
9640   "or{l}\t{%2, %0|%0, %2}"
9641   [(set_attr "type" "alu")
9642    (set_attr "mode" "SI")])
9643
9644 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9645 (define_insn "*iorsi_1_zext"
9646   [(set (match_operand:DI 0 "register_operand" "=r")
9647         (zero_extend:DI
9648           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9649                   (match_operand:SI 2 "general_operand" "g"))))
9650    (clobber (reg:CC FLAGS_REG))]
9651   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9652   "or{l}\t{%2, %k0|%k0, %2}"
9653   [(set_attr "type" "alu")
9654    (set_attr "mode" "SI")])
9655
9656 (define_insn "*iorsi_1_zext_imm"
9657   [(set (match_operand:DI 0 "register_operand" "=r")
9658         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9659                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9660    (clobber (reg:CC FLAGS_REG))]
9661   "TARGET_64BIT"
9662   "or{l}\t{%2, %k0|%k0, %2}"
9663   [(set_attr "type" "alu")
9664    (set_attr "mode" "SI")])
9665
9666 (define_insn "*iorsi_2"
9667   [(set (reg FLAGS_REG)
9668         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9669                          (match_operand:SI 2 "general_operand" "g,ri"))
9670                  (const_int 0)))
9671    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9672         (ior:SI (match_dup 1) (match_dup 2)))]
9673   "ix86_match_ccmode (insn, CCNOmode)
9674    && ix86_binary_operator_ok (IOR, SImode, operands)"
9675   "or{l}\t{%2, %0|%0, %2}"
9676   [(set_attr "type" "alu")
9677    (set_attr "mode" "SI")])
9678
9679 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9680 ;; ??? Special case for immediate operand is missing - it is tricky.
9681 (define_insn "*iorsi_2_zext"
9682   [(set (reg FLAGS_REG)
9683         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9684                          (match_operand:SI 2 "general_operand" "g"))
9685                  (const_int 0)))
9686    (set (match_operand:DI 0 "register_operand" "=r")
9687         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9688   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9689    && ix86_binary_operator_ok (IOR, SImode, operands)"
9690   "or{l}\t{%2, %k0|%k0, %2}"
9691   [(set_attr "type" "alu")
9692    (set_attr "mode" "SI")])
9693
9694 (define_insn "*iorsi_2_zext_imm"
9695   [(set (reg FLAGS_REG)
9696         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9697                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9698                  (const_int 0)))
9699    (set (match_operand:DI 0 "register_operand" "=r")
9700         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9701   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9702    && ix86_binary_operator_ok (IOR, SImode, operands)"
9703   "or{l}\t{%2, %k0|%k0, %2}"
9704   [(set_attr "type" "alu")
9705    (set_attr "mode" "SI")])
9706
9707 (define_insn "*iorsi_3"
9708   [(set (reg FLAGS_REG)
9709         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9710                          (match_operand:SI 2 "general_operand" "g"))
9711                  (const_int 0)))
9712    (clobber (match_scratch:SI 0 "=r"))]
9713   "ix86_match_ccmode (insn, CCNOmode)
9714    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9715   "or{l}\t{%2, %0|%0, %2}"
9716   [(set_attr "type" "alu")
9717    (set_attr "mode" "SI")])
9718
9719 (define_expand "iorhi3"
9720   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9721         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9722                 (match_operand:HI 2 "general_operand" "")))]
9723   "TARGET_HIMODE_MATH"
9724   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9725
9726 (define_insn "*iorhi_1"
9727   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9728         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9729                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9730    (clobber (reg:CC FLAGS_REG))]
9731   "ix86_binary_operator_ok (IOR, HImode, operands)"
9732   "or{w}\t{%2, %0|%0, %2}"
9733   [(set_attr "type" "alu")
9734    (set_attr "mode" "HI")])
9735
9736 (define_insn "*iorhi_2"
9737   [(set (reg FLAGS_REG)
9738         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9739                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9740                  (const_int 0)))
9741    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9742         (ior:HI (match_dup 1) (match_dup 2)))]
9743   "ix86_match_ccmode (insn, CCNOmode)
9744    && ix86_binary_operator_ok (IOR, HImode, operands)"
9745   "or{w}\t{%2, %0|%0, %2}"
9746   [(set_attr "type" "alu")
9747    (set_attr "mode" "HI")])
9748
9749 (define_insn "*iorhi_3"
9750   [(set (reg FLAGS_REG)
9751         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9752                          (match_operand:HI 2 "general_operand" "rmn"))
9753                  (const_int 0)))
9754    (clobber (match_scratch:HI 0 "=r"))]
9755   "ix86_match_ccmode (insn, CCNOmode)
9756    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9757   "or{w}\t{%2, %0|%0, %2}"
9758   [(set_attr "type" "alu")
9759    (set_attr "mode" "HI")])
9760
9761 (define_expand "iorqi3"
9762   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9763         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9764                 (match_operand:QI 2 "general_operand" "")))]
9765   "TARGET_QIMODE_MATH"
9766   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9767
9768 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9769 (define_insn "*iorqi_1"
9770   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9771         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9772                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9773    (clobber (reg:CC FLAGS_REG))]
9774   "ix86_binary_operator_ok (IOR, QImode, operands)"
9775   "@
9776    or{b}\t{%2, %0|%0, %2}
9777    or{b}\t{%2, %0|%0, %2}
9778    or{l}\t{%k2, %k0|%k0, %k2}"
9779   [(set_attr "type" "alu")
9780    (set_attr "mode" "QI,QI,SI")])
9781
9782 (define_insn "*iorqi_1_slp"
9783   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9784         (ior:QI (match_dup 0)
9785                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9786    (clobber (reg:CC FLAGS_REG))]
9787   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9788    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9789   "or{b}\t{%1, %0|%0, %1}"
9790   [(set_attr "type" "alu1")
9791    (set_attr "mode" "QI")])
9792
9793 (define_insn "*iorqi_2"
9794   [(set (reg FLAGS_REG)
9795         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9796                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9797                  (const_int 0)))
9798    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9799         (ior:QI (match_dup 1) (match_dup 2)))]
9800   "ix86_match_ccmode (insn, CCNOmode)
9801    && ix86_binary_operator_ok (IOR, QImode, operands)"
9802   "or{b}\t{%2, %0|%0, %2}"
9803   [(set_attr "type" "alu")
9804    (set_attr "mode" "QI")])
9805
9806 (define_insn "*iorqi_2_slp"
9807   [(set (reg FLAGS_REG)
9808         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9809                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9810                  (const_int 0)))
9811    (set (strict_low_part (match_dup 0))
9812         (ior:QI (match_dup 0) (match_dup 1)))]
9813   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9814    && ix86_match_ccmode (insn, CCNOmode)
9815    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9816   "or{b}\t{%1, %0|%0, %1}"
9817   [(set_attr "type" "alu1")
9818    (set_attr "mode" "QI")])
9819
9820 (define_insn "*iorqi_3"
9821   [(set (reg FLAGS_REG)
9822         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9823                          (match_operand:QI 2 "general_operand" "qmn"))
9824                  (const_int 0)))
9825    (clobber (match_scratch:QI 0 "=q"))]
9826   "ix86_match_ccmode (insn, CCNOmode)
9827    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9828   "or{b}\t{%2, %0|%0, %2}"
9829   [(set_attr "type" "alu")
9830    (set_attr "mode" "QI")])
9831
9832 (define_insn "*iorqi_ext_0"
9833   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9834                          (const_int 8)
9835                          (const_int 8))
9836         (ior:SI
9837           (zero_extract:SI
9838             (match_operand 1 "ext_register_operand" "0")
9839             (const_int 8)
9840             (const_int 8))
9841           (match_operand 2 "const_int_operand" "n")))
9842    (clobber (reg:CC FLAGS_REG))]
9843   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9844   "or{b}\t{%2, %h0|%h0, %2}"
9845   [(set_attr "type" "alu")
9846    (set_attr "length_immediate" "1")
9847    (set_attr "mode" "QI")])
9848
9849 (define_insn "*iorqi_ext_1"
9850   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9851                          (const_int 8)
9852                          (const_int 8))
9853         (ior:SI
9854           (zero_extract:SI
9855             (match_operand 1 "ext_register_operand" "0")
9856             (const_int 8)
9857             (const_int 8))
9858           (zero_extend:SI
9859             (match_operand:QI 2 "general_operand" "Qm"))))
9860    (clobber (reg:CC FLAGS_REG))]
9861   "!TARGET_64BIT
9862    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9863   "or{b}\t{%2, %h0|%h0, %2}"
9864   [(set_attr "type" "alu")
9865    (set_attr "length_immediate" "0")
9866    (set_attr "mode" "QI")])
9867
9868 (define_insn "*iorqi_ext_1_rex64"
9869   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9870                          (const_int 8)
9871                          (const_int 8))
9872         (ior:SI
9873           (zero_extract:SI
9874             (match_operand 1 "ext_register_operand" "0")
9875             (const_int 8)
9876             (const_int 8))
9877           (zero_extend:SI
9878             (match_operand 2 "ext_register_operand" "Q"))))
9879    (clobber (reg:CC FLAGS_REG))]
9880   "TARGET_64BIT
9881    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9882   "or{b}\t{%2, %h0|%h0, %2}"
9883   [(set_attr "type" "alu")
9884    (set_attr "length_immediate" "0")
9885    (set_attr "mode" "QI")])
9886
9887 (define_insn "*iorqi_ext_2"
9888   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9889                          (const_int 8)
9890                          (const_int 8))
9891         (ior:SI
9892           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9893                            (const_int 8)
9894                            (const_int 8))
9895           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9896                            (const_int 8)
9897                            (const_int 8))))
9898    (clobber (reg:CC FLAGS_REG))]
9899   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9900   "or{b}\t{%h2, %h0|%h0, %h2}"
9901   [(set_attr "type" "alu")
9902    (set_attr "length_immediate" "0")
9903    (set_attr "mode" "QI")])
9904
9905 (define_split
9906   [(set (match_operand 0 "register_operand" "")
9907         (ior (match_operand 1 "register_operand" "")
9908              (match_operand 2 "const_int_operand" "")))
9909    (clobber (reg:CC FLAGS_REG))]
9910    "reload_completed
9911     && QI_REG_P (operands[0])
9912     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9913     && !(INTVAL (operands[2]) & ~(255 << 8))
9914     && GET_MODE (operands[0]) != QImode"
9915   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9916                    (ior:SI (zero_extract:SI (match_dup 1)
9917                                             (const_int 8) (const_int 8))
9918                            (match_dup 2)))
9919               (clobber (reg:CC FLAGS_REG))])]
9920   "operands[0] = gen_lowpart (SImode, operands[0]);
9921    operands[1] = gen_lowpart (SImode, operands[1]);
9922    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9923
9924 ;; Since OR can be encoded with sign extended immediate, this is only
9925 ;; profitable when 7th bit is set.
9926 (define_split
9927   [(set (match_operand 0 "register_operand" "")
9928         (ior (match_operand 1 "general_operand" "")
9929              (match_operand 2 "const_int_operand" "")))
9930    (clobber (reg:CC FLAGS_REG))]
9931    "reload_completed
9932     && ANY_QI_REG_P (operands[0])
9933     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9934     && !(INTVAL (operands[2]) & ~255)
9935     && (INTVAL (operands[2]) & 128)
9936     && GET_MODE (operands[0]) != QImode"
9937   [(parallel [(set (strict_low_part (match_dup 0))
9938                    (ior:QI (match_dup 1)
9939                            (match_dup 2)))
9940               (clobber (reg:CC FLAGS_REG))])]
9941   "operands[0] = gen_lowpart (QImode, operands[0]);
9942    operands[1] = gen_lowpart (QImode, operands[1]);
9943    operands[2] = gen_lowpart (QImode, operands[2]);")
9944 \f
9945 ;; Logical XOR instructions
9946
9947 ;; %%% This used to optimize known byte-wide and operations to memory.
9948 ;; If this is considered useful, it should be done with splitters.
9949
9950 (define_expand "xordi3"
9951   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9952         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9953                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9954   "TARGET_64BIT"
9955   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9956
9957 (define_insn "*xordi_1_rex64"
9958   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9959         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9960                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9961    (clobber (reg:CC FLAGS_REG))]
9962   "TARGET_64BIT
9963    && ix86_binary_operator_ok (XOR, DImode, operands)"
9964   "xor{q}\t{%2, %0|%0, %2}"
9965   [(set_attr "type" "alu")
9966    (set_attr "mode" "DI")])
9967
9968 (define_insn "*xordi_2_rex64"
9969   [(set (reg FLAGS_REG)
9970         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9971                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9972                  (const_int 0)))
9973    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9974         (xor:DI (match_dup 1) (match_dup 2)))]
9975   "TARGET_64BIT
9976    && ix86_match_ccmode (insn, CCNOmode)
9977    && ix86_binary_operator_ok (XOR, DImode, operands)"
9978   "xor{q}\t{%2, %0|%0, %2}"
9979   [(set_attr "type" "alu")
9980    (set_attr "mode" "DI")])
9981
9982 (define_insn "*xordi_3_rex64"
9983   [(set (reg FLAGS_REG)
9984         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9985                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9986                  (const_int 0)))
9987    (clobber (match_scratch:DI 0 "=r"))]
9988   "TARGET_64BIT
9989    && ix86_match_ccmode (insn, CCNOmode)
9990    && ix86_binary_operator_ok (XOR, DImode, operands)"
9991   "xor{q}\t{%2, %0|%0, %2}"
9992   [(set_attr "type" "alu")
9993    (set_attr "mode" "DI")])
9994
9995 (define_expand "xorsi3"
9996   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9997         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9998                 (match_operand:SI 2 "general_operand" "")))]
9999   ""
10000   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10001
10002 (define_insn "*xorsi_1"
10003   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10004         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10005                 (match_operand:SI 2 "general_operand" "ri,rm")))
10006    (clobber (reg:CC FLAGS_REG))]
10007   "ix86_binary_operator_ok (XOR, SImode, operands)"
10008   "xor{l}\t{%2, %0|%0, %2}"
10009   [(set_attr "type" "alu")
10010    (set_attr "mode" "SI")])
10011
10012 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10013 ;; Add speccase for immediates
10014 (define_insn "*xorsi_1_zext"
10015   [(set (match_operand:DI 0 "register_operand" "=r")
10016         (zero_extend:DI
10017           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10018                   (match_operand:SI 2 "general_operand" "g"))))
10019    (clobber (reg:CC FLAGS_REG))]
10020   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10021   "xor{l}\t{%2, %k0|%k0, %2}"
10022   [(set_attr "type" "alu")
10023    (set_attr "mode" "SI")])
10024
10025 (define_insn "*xorsi_1_zext_imm"
10026   [(set (match_operand:DI 0 "register_operand" "=r")
10027         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10028                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10029    (clobber (reg:CC FLAGS_REG))]
10030   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10031   "xor{l}\t{%2, %k0|%k0, %2}"
10032   [(set_attr "type" "alu")
10033    (set_attr "mode" "SI")])
10034
10035 (define_insn "*xorsi_2"
10036   [(set (reg FLAGS_REG)
10037         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10038                          (match_operand:SI 2 "general_operand" "g,ri"))
10039                  (const_int 0)))
10040    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10041         (xor:SI (match_dup 1) (match_dup 2)))]
10042   "ix86_match_ccmode (insn, CCNOmode)
10043    && ix86_binary_operator_ok (XOR, SImode, operands)"
10044   "xor{l}\t{%2, %0|%0, %2}"
10045   [(set_attr "type" "alu")
10046    (set_attr "mode" "SI")])
10047
10048 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10049 ;; ??? Special case for immediate operand is missing - it is tricky.
10050 (define_insn "*xorsi_2_zext"
10051   [(set (reg FLAGS_REG)
10052         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10053                          (match_operand:SI 2 "general_operand" "g"))
10054                  (const_int 0)))
10055    (set (match_operand:DI 0 "register_operand" "=r")
10056         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10057   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10058    && ix86_binary_operator_ok (XOR, SImode, operands)"
10059   "xor{l}\t{%2, %k0|%k0, %2}"
10060   [(set_attr "type" "alu")
10061    (set_attr "mode" "SI")])
10062
10063 (define_insn "*xorsi_2_zext_imm"
10064   [(set (reg FLAGS_REG)
10065         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10066                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10067                  (const_int 0)))
10068    (set (match_operand:DI 0 "register_operand" "=r")
10069         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10070   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10071    && ix86_binary_operator_ok (XOR, SImode, operands)"
10072   "xor{l}\t{%2, %k0|%k0, %2}"
10073   [(set_attr "type" "alu")
10074    (set_attr "mode" "SI")])
10075
10076 (define_insn "*xorsi_3"
10077   [(set (reg FLAGS_REG)
10078         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10079                          (match_operand:SI 2 "general_operand" "g"))
10080                  (const_int 0)))
10081    (clobber (match_scratch:SI 0 "=r"))]
10082   "ix86_match_ccmode (insn, CCNOmode)
10083    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10084   "xor{l}\t{%2, %0|%0, %2}"
10085   [(set_attr "type" "alu")
10086    (set_attr "mode" "SI")])
10087
10088 (define_expand "xorhi3"
10089   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10090         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10091                 (match_operand:HI 2 "general_operand" "")))]
10092   "TARGET_HIMODE_MATH"
10093   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10094
10095 (define_insn "*xorhi_1"
10096   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10097         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10098                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10099    (clobber (reg:CC FLAGS_REG))]
10100   "ix86_binary_operator_ok (XOR, HImode, operands)"
10101   "xor{w}\t{%2, %0|%0, %2}"
10102   [(set_attr "type" "alu")
10103    (set_attr "mode" "HI")])
10104
10105 (define_insn "*xorhi_2"
10106   [(set (reg FLAGS_REG)
10107         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10108                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10109                  (const_int 0)))
10110    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10111         (xor:HI (match_dup 1) (match_dup 2)))]
10112   "ix86_match_ccmode (insn, CCNOmode)
10113    && ix86_binary_operator_ok (XOR, HImode, operands)"
10114   "xor{w}\t{%2, %0|%0, %2}"
10115   [(set_attr "type" "alu")
10116    (set_attr "mode" "HI")])
10117
10118 (define_insn "*xorhi_3"
10119   [(set (reg FLAGS_REG)
10120         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10121                          (match_operand:HI 2 "general_operand" "rmn"))
10122                  (const_int 0)))
10123    (clobber (match_scratch:HI 0 "=r"))]
10124   "ix86_match_ccmode (insn, CCNOmode)
10125    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10126   "xor{w}\t{%2, %0|%0, %2}"
10127   [(set_attr "type" "alu")
10128    (set_attr "mode" "HI")])
10129
10130 (define_expand "xorqi3"
10131   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10132         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10133                 (match_operand:QI 2 "general_operand" "")))]
10134   "TARGET_QIMODE_MATH"
10135   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10136
10137 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10138 (define_insn "*xorqi_1"
10139   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10140         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10141                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10142    (clobber (reg:CC FLAGS_REG))]
10143   "ix86_binary_operator_ok (XOR, QImode, operands)"
10144   "@
10145    xor{b}\t{%2, %0|%0, %2}
10146    xor{b}\t{%2, %0|%0, %2}
10147    xor{l}\t{%k2, %k0|%k0, %k2}"
10148   [(set_attr "type" "alu")
10149    (set_attr "mode" "QI,QI,SI")])
10150
10151 (define_insn "*xorqi_1_slp"
10152   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10153         (xor:QI (match_dup 0)
10154                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10155    (clobber (reg:CC FLAGS_REG))]
10156   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10157    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10158   "xor{b}\t{%1, %0|%0, %1}"
10159   [(set_attr "type" "alu1")
10160    (set_attr "mode" "QI")])
10161
10162 (define_insn "*xorqi_ext_0"
10163   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10164                          (const_int 8)
10165                          (const_int 8))
10166         (xor:SI
10167           (zero_extract:SI
10168             (match_operand 1 "ext_register_operand" "0")
10169             (const_int 8)
10170             (const_int 8))
10171           (match_operand 2 "const_int_operand" "n")))
10172    (clobber (reg:CC FLAGS_REG))]
10173   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10174   "xor{b}\t{%2, %h0|%h0, %2}"
10175   [(set_attr "type" "alu")
10176    (set_attr "length_immediate" "1")
10177    (set_attr "mode" "QI")])
10178
10179 (define_insn "*xorqi_ext_1"
10180   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10181                          (const_int 8)
10182                          (const_int 8))
10183         (xor:SI
10184           (zero_extract:SI
10185             (match_operand 1 "ext_register_operand" "0")
10186             (const_int 8)
10187             (const_int 8))
10188           (zero_extend:SI
10189             (match_operand:QI 2 "general_operand" "Qm"))))
10190    (clobber (reg:CC FLAGS_REG))]
10191   "!TARGET_64BIT
10192    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10193   "xor{b}\t{%2, %h0|%h0, %2}"
10194   [(set_attr "type" "alu")
10195    (set_attr "length_immediate" "0")
10196    (set_attr "mode" "QI")])
10197
10198 (define_insn "*xorqi_ext_1_rex64"
10199   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10200                          (const_int 8)
10201                          (const_int 8))
10202         (xor:SI
10203           (zero_extract:SI
10204             (match_operand 1 "ext_register_operand" "0")
10205             (const_int 8)
10206             (const_int 8))
10207           (zero_extend:SI
10208             (match_operand 2 "ext_register_operand" "Q"))))
10209    (clobber (reg:CC FLAGS_REG))]
10210   "TARGET_64BIT
10211    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10212   "xor{b}\t{%2, %h0|%h0, %2}"
10213   [(set_attr "type" "alu")
10214    (set_attr "length_immediate" "0")
10215    (set_attr "mode" "QI")])
10216
10217 (define_insn "*xorqi_ext_2"
10218   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10219                          (const_int 8)
10220                          (const_int 8))
10221         (xor:SI
10222           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10223                            (const_int 8)
10224                            (const_int 8))
10225           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10226                            (const_int 8)
10227                            (const_int 8))))
10228    (clobber (reg:CC FLAGS_REG))]
10229   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10230   "xor{b}\t{%h2, %h0|%h0, %h2}"
10231   [(set_attr "type" "alu")
10232    (set_attr "length_immediate" "0")
10233    (set_attr "mode" "QI")])
10234
10235 (define_insn "*xorqi_cc_1"
10236   [(set (reg FLAGS_REG)
10237         (compare
10238           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10239                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10240           (const_int 0)))
10241    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10242         (xor:QI (match_dup 1) (match_dup 2)))]
10243   "ix86_match_ccmode (insn, CCNOmode)
10244    && ix86_binary_operator_ok (XOR, QImode, operands)"
10245   "xor{b}\t{%2, %0|%0, %2}"
10246   [(set_attr "type" "alu")
10247    (set_attr "mode" "QI")])
10248
10249 (define_insn "*xorqi_2_slp"
10250   [(set (reg FLAGS_REG)
10251         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10252                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10253                  (const_int 0)))
10254    (set (strict_low_part (match_dup 0))
10255         (xor:QI (match_dup 0) (match_dup 1)))]
10256   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10257    && ix86_match_ccmode (insn, CCNOmode)
10258    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10259   "xor{b}\t{%1, %0|%0, %1}"
10260   [(set_attr "type" "alu1")
10261    (set_attr "mode" "QI")])
10262
10263 (define_insn "*xorqi_cc_2"
10264   [(set (reg FLAGS_REG)
10265         (compare
10266           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10267                   (match_operand:QI 2 "general_operand" "qmn"))
10268           (const_int 0)))
10269    (clobber (match_scratch:QI 0 "=q"))]
10270   "ix86_match_ccmode (insn, CCNOmode)
10271    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10272   "xor{b}\t{%2, %0|%0, %2}"
10273   [(set_attr "type" "alu")
10274    (set_attr "mode" "QI")])
10275
10276 (define_insn "*xorqi_cc_ext_1"
10277   [(set (reg FLAGS_REG)
10278         (compare
10279           (xor:SI
10280             (zero_extract:SI
10281               (match_operand 1 "ext_register_operand" "0")
10282               (const_int 8)
10283               (const_int 8))
10284             (match_operand:QI 2 "general_operand" "qmn"))
10285           (const_int 0)))
10286    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10287                          (const_int 8)
10288                          (const_int 8))
10289         (xor:SI
10290           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10291           (match_dup 2)))]
10292   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10293   "xor{b}\t{%2, %h0|%h0, %2}"
10294   [(set_attr "type" "alu")
10295    (set_attr "mode" "QI")])
10296
10297 (define_insn "*xorqi_cc_ext_1_rex64"
10298   [(set (reg FLAGS_REG)
10299         (compare
10300           (xor:SI
10301             (zero_extract:SI
10302               (match_operand 1 "ext_register_operand" "0")
10303               (const_int 8)
10304               (const_int 8))
10305             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10306           (const_int 0)))
10307    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10308                          (const_int 8)
10309                          (const_int 8))
10310         (xor:SI
10311           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10312           (match_dup 2)))]
10313   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10314   "xor{b}\t{%2, %h0|%h0, %2}"
10315   [(set_attr "type" "alu")
10316    (set_attr "mode" "QI")])
10317
10318 (define_expand "xorqi_cc_ext_1"
10319   [(parallel [
10320      (set (reg:CCNO FLAGS_REG)
10321           (compare:CCNO
10322             (xor:SI
10323               (zero_extract:SI
10324                 (match_operand 1 "ext_register_operand" "")
10325                 (const_int 8)
10326                 (const_int 8))
10327               (match_operand:QI 2 "general_operand" ""))
10328             (const_int 0)))
10329      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10330                            (const_int 8)
10331                            (const_int 8))
10332           (xor:SI
10333             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10334             (match_dup 2)))])]
10335   ""
10336   "")
10337
10338 (define_split
10339   [(set (match_operand 0 "register_operand" "")
10340         (xor (match_operand 1 "register_operand" "")
10341              (match_operand 2 "const_int_operand" "")))
10342    (clobber (reg:CC FLAGS_REG))]
10343    "reload_completed
10344     && QI_REG_P (operands[0])
10345     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10346     && !(INTVAL (operands[2]) & ~(255 << 8))
10347     && GET_MODE (operands[0]) != QImode"
10348   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10349                    (xor:SI (zero_extract:SI (match_dup 1)
10350                                             (const_int 8) (const_int 8))
10351                            (match_dup 2)))
10352               (clobber (reg:CC FLAGS_REG))])]
10353   "operands[0] = gen_lowpart (SImode, operands[0]);
10354    operands[1] = gen_lowpart (SImode, operands[1]);
10355    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10356
10357 ;; Since XOR can be encoded with sign extended immediate, this is only
10358 ;; profitable when 7th bit is set.
10359 (define_split
10360   [(set (match_operand 0 "register_operand" "")
10361         (xor (match_operand 1 "general_operand" "")
10362              (match_operand 2 "const_int_operand" "")))
10363    (clobber (reg:CC FLAGS_REG))]
10364    "reload_completed
10365     && ANY_QI_REG_P (operands[0])
10366     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10367     && !(INTVAL (operands[2]) & ~255)
10368     && (INTVAL (operands[2]) & 128)
10369     && GET_MODE (operands[0]) != QImode"
10370   [(parallel [(set (strict_low_part (match_dup 0))
10371                    (xor:QI (match_dup 1)
10372                            (match_dup 2)))
10373               (clobber (reg:CC FLAGS_REG))])]
10374   "operands[0] = gen_lowpart (QImode, operands[0]);
10375    operands[1] = gen_lowpart (QImode, operands[1]);
10376    operands[2] = gen_lowpart (QImode, operands[2]);")
10377 \f
10378 ;; Negation instructions
10379
10380 (define_expand "negti2"
10381   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10382         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10383   "TARGET_64BIT"
10384   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10385
10386 (define_insn "*negti2_1"
10387   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10388         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10389    (clobber (reg:CC FLAGS_REG))]
10390   "TARGET_64BIT
10391    && ix86_unary_operator_ok (NEG, TImode, operands)"
10392   "#")
10393
10394 (define_split
10395   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10396         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10397    (clobber (reg:CC FLAGS_REG))]
10398   "TARGET_64BIT && reload_completed"
10399   [(parallel
10400     [(set (reg:CCZ FLAGS_REG)
10401           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10402      (set (match_dup 0) (neg:DI (match_dup 1)))])
10403    (parallel
10404     [(set (match_dup 2)
10405           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10406                             (match_dup 3))
10407                    (const_int 0)))
10408      (clobber (reg:CC FLAGS_REG))])
10409    (parallel
10410     [(set (match_dup 2)
10411           (neg:DI (match_dup 2)))
10412      (clobber (reg:CC FLAGS_REG))])]
10413   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10414
10415 (define_expand "negdi2"
10416   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10417         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10418   ""
10419   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10420
10421 (define_insn "*negdi2_1"
10422   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10423         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10424    (clobber (reg:CC FLAGS_REG))]
10425   "!TARGET_64BIT
10426    && ix86_unary_operator_ok (NEG, DImode, operands)"
10427   "#")
10428
10429 (define_split
10430   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10431         (neg:DI (match_operand:DI 1 "general_operand" "")))
10432    (clobber (reg:CC FLAGS_REG))]
10433   "!TARGET_64BIT && reload_completed"
10434   [(parallel
10435     [(set (reg:CCZ FLAGS_REG)
10436           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10437      (set (match_dup 0) (neg:SI (match_dup 1)))])
10438    (parallel
10439     [(set (match_dup 2)
10440           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10441                             (match_dup 3))
10442                    (const_int 0)))
10443      (clobber (reg:CC FLAGS_REG))])
10444    (parallel
10445     [(set (match_dup 2)
10446           (neg:SI (match_dup 2)))
10447      (clobber (reg:CC FLAGS_REG))])]
10448   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10449
10450 (define_insn "*negdi2_1_rex64"
10451   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10452         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10453    (clobber (reg:CC FLAGS_REG))]
10454   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10455   "neg{q}\t%0"
10456   [(set_attr "type" "negnot")
10457    (set_attr "mode" "DI")])
10458
10459 ;; The problem with neg is that it does not perform (compare x 0),
10460 ;; it really performs (compare 0 x), which leaves us with the zero
10461 ;; flag being the only useful item.
10462
10463 (define_insn "*negdi2_cmpz_rex64"
10464   [(set (reg:CCZ FLAGS_REG)
10465         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10466                      (const_int 0)))
10467    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10468         (neg:DI (match_dup 1)))]
10469   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10470   "neg{q}\t%0"
10471   [(set_attr "type" "negnot")
10472    (set_attr "mode" "DI")])
10473
10474
10475 (define_expand "negsi2"
10476   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10477         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10478   ""
10479   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10480
10481 (define_insn "*negsi2_1"
10482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10483         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10484    (clobber (reg:CC FLAGS_REG))]
10485   "ix86_unary_operator_ok (NEG, SImode, operands)"
10486   "neg{l}\t%0"
10487   [(set_attr "type" "negnot")
10488    (set_attr "mode" "SI")])
10489
10490 ;; Combine is quite creative about this pattern.
10491 (define_insn "*negsi2_1_zext"
10492   [(set (match_operand:DI 0 "register_operand" "=r")
10493         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10494                                         (const_int 32)))
10495                      (const_int 32)))
10496    (clobber (reg:CC FLAGS_REG))]
10497   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10498   "neg{l}\t%k0"
10499   [(set_attr "type" "negnot")
10500    (set_attr "mode" "SI")])
10501
10502 ;; The problem with neg is that it does not perform (compare x 0),
10503 ;; it really performs (compare 0 x), which leaves us with the zero
10504 ;; flag being the only useful item.
10505
10506 (define_insn "*negsi2_cmpz"
10507   [(set (reg:CCZ FLAGS_REG)
10508         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10509                      (const_int 0)))
10510    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10511         (neg:SI (match_dup 1)))]
10512   "ix86_unary_operator_ok (NEG, SImode, operands)"
10513   "neg{l}\t%0"
10514   [(set_attr "type" "negnot")
10515    (set_attr "mode" "SI")])
10516
10517 (define_insn "*negsi2_cmpz_zext"
10518   [(set (reg:CCZ FLAGS_REG)
10519         (compare:CCZ (lshiftrt:DI
10520                        (neg:DI (ashift:DI
10521                                  (match_operand:DI 1 "register_operand" "0")
10522                                  (const_int 32)))
10523                        (const_int 32))
10524                      (const_int 0)))
10525    (set (match_operand:DI 0 "register_operand" "=r")
10526         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10527                                         (const_int 32)))
10528                      (const_int 32)))]
10529   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10530   "neg{l}\t%k0"
10531   [(set_attr "type" "negnot")
10532    (set_attr "mode" "SI")])
10533
10534 (define_expand "neghi2"
10535   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10536         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10537   "TARGET_HIMODE_MATH"
10538   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10539
10540 (define_insn "*neghi2_1"
10541   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10542         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10543    (clobber (reg:CC FLAGS_REG))]
10544   "ix86_unary_operator_ok (NEG, HImode, operands)"
10545   "neg{w}\t%0"
10546   [(set_attr "type" "negnot")
10547    (set_attr "mode" "HI")])
10548
10549 (define_insn "*neghi2_cmpz"
10550   [(set (reg:CCZ FLAGS_REG)
10551         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10552                      (const_int 0)))
10553    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10554         (neg:HI (match_dup 1)))]
10555   "ix86_unary_operator_ok (NEG, HImode, operands)"
10556   "neg{w}\t%0"
10557   [(set_attr "type" "negnot")
10558    (set_attr "mode" "HI")])
10559
10560 (define_expand "negqi2"
10561   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10562         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10563   "TARGET_QIMODE_MATH"
10564   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10565
10566 (define_insn "*negqi2_1"
10567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10568         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10569    (clobber (reg:CC FLAGS_REG))]
10570   "ix86_unary_operator_ok (NEG, QImode, operands)"
10571   "neg{b}\t%0"
10572   [(set_attr "type" "negnot")
10573    (set_attr "mode" "QI")])
10574
10575 (define_insn "*negqi2_cmpz"
10576   [(set (reg:CCZ FLAGS_REG)
10577         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10578                      (const_int 0)))
10579    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10580         (neg:QI (match_dup 1)))]
10581   "ix86_unary_operator_ok (NEG, QImode, operands)"
10582   "neg{b}\t%0"
10583   [(set_attr "type" "negnot")
10584    (set_attr "mode" "QI")])
10585
10586 ;; Changing of sign for FP values is doable using integer unit too.
10587
10588 (define_expand "<code><mode>2"
10589   [(set (match_operand:X87MODEF 0 "register_operand" "")
10590         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10591   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10592   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10593
10594 (define_insn "*absneg<mode>2_mixed"
10595   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10596         (match_operator:MODEF 3 "absneg_operator"
10597           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10598    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10599    (clobber (reg:CC FLAGS_REG))]
10600   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10601   "#")
10602
10603 (define_insn "*absneg<mode>2_sse"
10604   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10605         (match_operator:MODEF 3 "absneg_operator"
10606           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10607    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10608    (clobber (reg:CC FLAGS_REG))]
10609   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10610   "#")
10611
10612 (define_insn "*absneg<mode>2_i387"
10613   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10614         (match_operator:X87MODEF 3 "absneg_operator"
10615           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10616    (use (match_operand 2 "" ""))
10617    (clobber (reg:CC FLAGS_REG))]
10618   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10619   "#")
10620
10621 (define_expand "<code>tf2"
10622   [(set (match_operand:TF 0 "register_operand" "")
10623         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10624   "TARGET_SSE2"
10625   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10626
10627 (define_insn "*absnegtf2_sse"
10628   [(set (match_operand:TF 0 "register_operand" "=x,x")
10629         (match_operator:TF 3 "absneg_operator"
10630           [(match_operand:TF 1 "register_operand" "0,x")]))
10631    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10632    (clobber (reg:CC FLAGS_REG))]
10633   "TARGET_SSE2"
10634   "#")
10635
10636 ;; Splitters for fp abs and neg.
10637
10638 (define_split
10639   [(set (match_operand 0 "fp_register_operand" "")
10640         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10641    (use (match_operand 2 "" ""))
10642    (clobber (reg:CC FLAGS_REG))]
10643   "reload_completed"
10644   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10645
10646 (define_split
10647   [(set (match_operand 0 "register_operand" "")
10648         (match_operator 3 "absneg_operator"
10649           [(match_operand 1 "register_operand" "")]))
10650    (use (match_operand 2 "nonimmediate_operand" ""))
10651    (clobber (reg:CC FLAGS_REG))]
10652   "reload_completed && SSE_REG_P (operands[0])"
10653   [(set (match_dup 0) (match_dup 3))]
10654 {
10655   enum machine_mode mode = GET_MODE (operands[0]);
10656   enum machine_mode vmode = GET_MODE (operands[2]);
10657   rtx tmp;
10658
10659   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10660   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10661   if (operands_match_p (operands[0], operands[2]))
10662     {
10663       tmp = operands[1];
10664       operands[1] = operands[2];
10665       operands[2] = tmp;
10666     }
10667   if (GET_CODE (operands[3]) == ABS)
10668     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10669   else
10670     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10671   operands[3] = tmp;
10672 })
10673
10674 (define_split
10675   [(set (match_operand:SF 0 "register_operand" "")
10676         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10677    (use (match_operand:V4SF 2 "" ""))
10678    (clobber (reg:CC FLAGS_REG))]
10679   "reload_completed"
10680   [(parallel [(set (match_dup 0) (match_dup 1))
10681               (clobber (reg:CC FLAGS_REG))])]
10682 {
10683   rtx tmp;
10684   operands[0] = gen_lowpart (SImode, operands[0]);
10685   if (GET_CODE (operands[1]) == ABS)
10686     {
10687       tmp = gen_int_mode (0x7fffffff, SImode);
10688       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10689     }
10690   else
10691     {
10692       tmp = gen_int_mode (0x80000000, SImode);
10693       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10694     }
10695   operands[1] = tmp;
10696 })
10697
10698 (define_split
10699   [(set (match_operand:DF 0 "register_operand" "")
10700         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10701    (use (match_operand 2 "" ""))
10702    (clobber (reg:CC FLAGS_REG))]
10703   "reload_completed"
10704   [(parallel [(set (match_dup 0) (match_dup 1))
10705               (clobber (reg:CC FLAGS_REG))])]
10706 {
10707   rtx tmp;
10708   if (TARGET_64BIT)
10709     {
10710       tmp = gen_lowpart (DImode, operands[0]);
10711       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10712       operands[0] = tmp;
10713
10714       if (GET_CODE (operands[1]) == ABS)
10715         tmp = const0_rtx;
10716       else
10717         tmp = gen_rtx_NOT (DImode, tmp);
10718     }
10719   else
10720     {
10721       operands[0] = gen_highpart (SImode, operands[0]);
10722       if (GET_CODE (operands[1]) == ABS)
10723         {
10724           tmp = gen_int_mode (0x7fffffff, SImode);
10725           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10726         }
10727       else
10728         {
10729           tmp = gen_int_mode (0x80000000, SImode);
10730           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10731         }
10732     }
10733   operands[1] = tmp;
10734 })
10735
10736 (define_split
10737   [(set (match_operand:XF 0 "register_operand" "")
10738         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10739    (use (match_operand 2 "" ""))
10740    (clobber (reg:CC FLAGS_REG))]
10741   "reload_completed"
10742   [(parallel [(set (match_dup 0) (match_dup 1))
10743               (clobber (reg:CC FLAGS_REG))])]
10744 {
10745   rtx tmp;
10746   operands[0] = gen_rtx_REG (SImode,
10747                              true_regnum (operands[0])
10748                              + (TARGET_64BIT ? 1 : 2));
10749   if (GET_CODE (operands[1]) == ABS)
10750     {
10751       tmp = GEN_INT (0x7fff);
10752       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10753     }
10754   else
10755     {
10756       tmp = GEN_INT (0x8000);
10757       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10758     }
10759   operands[1] = tmp;
10760 })
10761
10762 ;; Conditionalize these after reload. If they match before reload, we
10763 ;; lose the clobber and ability to use integer instructions.
10764
10765 (define_insn "*<code><mode>2_1"
10766   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10767         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10768   "TARGET_80387
10769    && (reload_completed
10770        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10771   "f<absnegprefix>"
10772   [(set_attr "type" "fsgn")
10773    (set_attr "mode" "<MODE>")])
10774
10775 (define_insn "*<code>extendsfdf2"
10776   [(set (match_operand:DF 0 "register_operand" "=f")
10777         (absneg:DF (float_extend:DF
10778                      (match_operand:SF 1 "register_operand" "0"))))]
10779   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10780   "f<absnegprefix>"
10781   [(set_attr "type" "fsgn")
10782    (set_attr "mode" "DF")])
10783
10784 (define_insn "*<code>extendsfxf2"
10785   [(set (match_operand:XF 0 "register_operand" "=f")
10786         (absneg:XF (float_extend:XF
10787                      (match_operand:SF 1 "register_operand" "0"))))]
10788   "TARGET_80387"
10789   "f<absnegprefix>"
10790   [(set_attr "type" "fsgn")
10791    (set_attr "mode" "XF")])
10792
10793 (define_insn "*<code>extenddfxf2"
10794   [(set (match_operand:XF 0 "register_operand" "=f")
10795         (absneg:XF (float_extend:XF
10796                       (match_operand:DF 1 "register_operand" "0"))))]
10797   "TARGET_80387"
10798   "f<absnegprefix>"
10799   [(set_attr "type" "fsgn")
10800    (set_attr "mode" "XF")])
10801
10802 ;; Copysign instructions
10803
10804 (define_mode_iterator CSGNMODE [SF DF TF])
10805 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10806
10807 (define_expand "copysign<mode>3"
10808   [(match_operand:CSGNMODE 0 "register_operand" "")
10809    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10810    (match_operand:CSGNMODE 2 "register_operand" "")]
10811   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10812    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10813 {
10814   ix86_expand_copysign (operands);
10815   DONE;
10816 })
10817
10818 (define_insn_and_split "copysign<mode>3_const"
10819   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10820         (unspec:CSGNMODE
10821           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10822            (match_operand:CSGNMODE 2 "register_operand" "0")
10823            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10824           UNSPEC_COPYSIGN))]
10825   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10826    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10827   "#"
10828   "&& reload_completed"
10829   [(const_int 0)]
10830 {
10831   ix86_split_copysign_const (operands);
10832   DONE;
10833 })
10834
10835 (define_insn "copysign<mode>3_var"
10836   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10837         (unspec:CSGNMODE
10838           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10839            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10840            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10841            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10842           UNSPEC_COPYSIGN))
10843    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10844   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10845    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10846   "#")
10847
10848 (define_split
10849   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10850         (unspec:CSGNMODE
10851           [(match_operand:CSGNMODE 2 "register_operand" "")
10852            (match_operand:CSGNMODE 3 "register_operand" "")
10853            (match_operand:<CSGNVMODE> 4 "" "")
10854            (match_operand:<CSGNVMODE> 5 "" "")]
10855           UNSPEC_COPYSIGN))
10856    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10857   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10858     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10859    && reload_completed"
10860   [(const_int 0)]
10861 {
10862   ix86_split_copysign_var (operands);
10863   DONE;
10864 })
10865 \f
10866 ;; One complement instructions
10867
10868 (define_expand "one_cmpldi2"
10869   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10870         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10871   "TARGET_64BIT"
10872   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10873
10874 (define_insn "*one_cmpldi2_1_rex64"
10875   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10876         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10877   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10878   "not{q}\t%0"
10879   [(set_attr "type" "negnot")
10880    (set_attr "mode" "DI")])
10881
10882 (define_insn "*one_cmpldi2_2_rex64"
10883   [(set (reg FLAGS_REG)
10884         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10885                  (const_int 0)))
10886    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10887         (not:DI (match_dup 1)))]
10888   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10889    && ix86_unary_operator_ok (NOT, DImode, operands)"
10890   "#"
10891   [(set_attr "type" "alu1")
10892    (set_attr "mode" "DI")])
10893
10894 (define_split
10895   [(set (match_operand 0 "flags_reg_operand" "")
10896         (match_operator 2 "compare_operator"
10897           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10898            (const_int 0)]))
10899    (set (match_operand:DI 1 "nonimmediate_operand" "")
10900         (not:DI (match_dup 3)))]
10901   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10902   [(parallel [(set (match_dup 0)
10903                    (match_op_dup 2
10904                      [(xor:DI (match_dup 3) (const_int -1))
10905                       (const_int 0)]))
10906               (set (match_dup 1)
10907                    (xor:DI (match_dup 3) (const_int -1)))])]
10908   "")
10909
10910 (define_expand "one_cmplsi2"
10911   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10912         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10913   ""
10914   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10915
10916 (define_insn "*one_cmplsi2_1"
10917   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10918         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10919   "ix86_unary_operator_ok (NOT, SImode, operands)"
10920   "not{l}\t%0"
10921   [(set_attr "type" "negnot")
10922    (set_attr "mode" "SI")])
10923
10924 ;; ??? Currently never generated - xor is used instead.
10925 (define_insn "*one_cmplsi2_1_zext"
10926   [(set (match_operand:DI 0 "register_operand" "=r")
10927         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10928   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10929   "not{l}\t%k0"
10930   [(set_attr "type" "negnot")
10931    (set_attr "mode" "SI")])
10932
10933 (define_insn "*one_cmplsi2_2"
10934   [(set (reg FLAGS_REG)
10935         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10936                  (const_int 0)))
10937    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10938         (not:SI (match_dup 1)))]
10939   "ix86_match_ccmode (insn, CCNOmode)
10940    && ix86_unary_operator_ok (NOT, SImode, operands)"
10941   "#"
10942   [(set_attr "type" "alu1")
10943    (set_attr "mode" "SI")])
10944
10945 (define_split
10946   [(set (match_operand 0 "flags_reg_operand" "")
10947         (match_operator 2 "compare_operator"
10948           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10949            (const_int 0)]))
10950    (set (match_operand:SI 1 "nonimmediate_operand" "")
10951         (not:SI (match_dup 3)))]
10952   "ix86_match_ccmode (insn, CCNOmode)"
10953   [(parallel [(set (match_dup 0)
10954                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10955                                     (const_int 0)]))
10956               (set (match_dup 1)
10957                    (xor:SI (match_dup 3) (const_int -1)))])]
10958   "")
10959
10960 ;; ??? Currently never generated - xor is used instead.
10961 (define_insn "*one_cmplsi2_2_zext"
10962   [(set (reg FLAGS_REG)
10963         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10964                  (const_int 0)))
10965    (set (match_operand:DI 0 "register_operand" "=r")
10966         (zero_extend:DI (not:SI (match_dup 1))))]
10967   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10968    && ix86_unary_operator_ok (NOT, SImode, operands)"
10969   "#"
10970   [(set_attr "type" "alu1")
10971    (set_attr "mode" "SI")])
10972
10973 (define_split
10974   [(set (match_operand 0 "flags_reg_operand" "")
10975         (match_operator 2 "compare_operator"
10976           [(not:SI (match_operand:SI 3 "register_operand" ""))
10977            (const_int 0)]))
10978    (set (match_operand:DI 1 "register_operand" "")
10979         (zero_extend:DI (not:SI (match_dup 3))))]
10980   "ix86_match_ccmode (insn, CCNOmode)"
10981   [(parallel [(set (match_dup 0)
10982                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10983                                     (const_int 0)]))
10984               (set (match_dup 1)
10985                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10986   "")
10987
10988 (define_expand "one_cmplhi2"
10989   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10990         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10991   "TARGET_HIMODE_MATH"
10992   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10993
10994 (define_insn "*one_cmplhi2_1"
10995   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10996         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10997   "ix86_unary_operator_ok (NOT, HImode, operands)"
10998   "not{w}\t%0"
10999   [(set_attr "type" "negnot")
11000    (set_attr "mode" "HI")])
11001
11002 (define_insn "*one_cmplhi2_2"
11003   [(set (reg FLAGS_REG)
11004         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11005                  (const_int 0)))
11006    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11007         (not:HI (match_dup 1)))]
11008   "ix86_match_ccmode (insn, CCNOmode)
11009    && ix86_unary_operator_ok (NEG, HImode, operands)"
11010   "#"
11011   [(set_attr "type" "alu1")
11012    (set_attr "mode" "HI")])
11013
11014 (define_split
11015   [(set (match_operand 0 "flags_reg_operand" "")
11016         (match_operator 2 "compare_operator"
11017           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11018            (const_int 0)]))
11019    (set (match_operand:HI 1 "nonimmediate_operand" "")
11020         (not:HI (match_dup 3)))]
11021   "ix86_match_ccmode (insn, CCNOmode)"
11022   [(parallel [(set (match_dup 0)
11023                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11024                                     (const_int 0)]))
11025               (set (match_dup 1)
11026                    (xor:HI (match_dup 3) (const_int -1)))])]
11027   "")
11028
11029 ;; %%% Potential partial reg stall on alternative 1.  What to do?
11030 (define_expand "one_cmplqi2"
11031   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11032         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11033   "TARGET_QIMODE_MATH"
11034   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11035
11036 (define_insn "*one_cmplqi2_1"
11037   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11038         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11039   "ix86_unary_operator_ok (NOT, QImode, operands)"
11040   "@
11041    not{b}\t%0
11042    not{l}\t%k0"
11043   [(set_attr "type" "negnot")
11044    (set_attr "mode" "QI,SI")])
11045
11046 (define_insn "*one_cmplqi2_2"
11047   [(set (reg FLAGS_REG)
11048         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11049                  (const_int 0)))
11050    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11051         (not:QI (match_dup 1)))]
11052   "ix86_match_ccmode (insn, CCNOmode)
11053    && ix86_unary_operator_ok (NOT, QImode, operands)"
11054   "#"
11055   [(set_attr "type" "alu1")
11056    (set_attr "mode" "QI")])
11057
11058 (define_split
11059   [(set (match_operand 0 "flags_reg_operand" "")
11060         (match_operator 2 "compare_operator"
11061           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11062            (const_int 0)]))
11063    (set (match_operand:QI 1 "nonimmediate_operand" "")
11064         (not:QI (match_dup 3)))]
11065   "ix86_match_ccmode (insn, CCNOmode)"
11066   [(parallel [(set (match_dup 0)
11067                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11068                                     (const_int 0)]))
11069               (set (match_dup 1)
11070                    (xor:QI (match_dup 3) (const_int -1)))])]
11071   "")
11072 \f
11073 ;; Arithmetic shift instructions
11074
11075 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11076 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11077 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11078 ;; from the assembler input.
11079 ;;
11080 ;; This instruction shifts the target reg/mem as usual, but instead of
11081 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11082 ;; is a left shift double, bits are taken from the high order bits of
11083 ;; reg, else if the insn is a shift right double, bits are taken from the
11084 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11085 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11086 ;;
11087 ;; Since sh[lr]d does not change the `reg' operand, that is done
11088 ;; separately, making all shifts emit pairs of shift double and normal
11089 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11090 ;; support a 63 bit shift, each shift where the count is in a reg expands
11091 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11092 ;;
11093 ;; If the shift count is a constant, we need never emit more than one
11094 ;; shift pair, instead using moves and sign extension for counts greater
11095 ;; than 31.
11096
11097 (define_expand "ashlti3"
11098   [(set (match_operand:TI 0 "register_operand" "")
11099         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11100                    (match_operand:QI 2 "nonmemory_operand" "")))]
11101   "TARGET_64BIT"
11102   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11103
11104 ;; This pattern must be defined before *ashlti3_1 to prevent
11105 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11106
11107 (define_insn "*avx_ashlti3"
11108   [(set (match_operand:TI 0 "register_operand" "=x")
11109         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11110                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11111   "TARGET_AVX"
11112 {
11113   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11114   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11115 }
11116   [(set_attr "type" "sseishft")
11117    (set_attr "prefix" "vex")
11118    (set_attr "mode" "TI")])
11119
11120 (define_insn "sse2_ashlti3"
11121   [(set (match_operand:TI 0 "register_operand" "=x")
11122         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11123                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11124   "TARGET_SSE2"
11125 {
11126   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11127   return "pslldq\t{%2, %0|%0, %2}";
11128 }
11129   [(set_attr "type" "sseishft")
11130    (set_attr "prefix_data16" "1")
11131    (set_attr "mode" "TI")])
11132
11133 (define_insn "*ashlti3_1"
11134   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11135         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11136                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11137    (clobber (reg:CC FLAGS_REG))]
11138   "TARGET_64BIT"
11139   "#"
11140   [(set_attr "type" "multi")])
11141
11142 (define_peephole2
11143   [(match_scratch:DI 3 "r")
11144    (parallel [(set (match_operand:TI 0 "register_operand" "")
11145                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11146                               (match_operand:QI 2 "nonmemory_operand" "")))
11147               (clobber (reg:CC FLAGS_REG))])
11148    (match_dup 3)]
11149   "TARGET_64BIT"
11150   [(const_int 0)]
11151   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11152
11153 (define_split
11154   [(set (match_operand:TI 0 "register_operand" "")
11155         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11156                    (match_operand:QI 2 "nonmemory_operand" "")))
11157    (clobber (reg:CC FLAGS_REG))]
11158   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11159                     ? epilogue_completed : reload_completed)"
11160   [(const_int 0)]
11161   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11162
11163 (define_insn "x86_64_shld"
11164   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11165         (ior:DI (ashift:DI (match_dup 0)
11166                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11167                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11168                   (minus:QI (const_int 64) (match_dup 2)))))
11169    (clobber (reg:CC FLAGS_REG))]
11170   "TARGET_64BIT"
11171   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11172   [(set_attr "type" "ishift")
11173    (set_attr "prefix_0f" "1")
11174    (set_attr "mode" "DI")
11175    (set_attr "athlon_decode" "vector")
11176    (set_attr "amdfam10_decode" "vector")])
11177
11178 (define_expand "x86_64_shift_adj_1"
11179   [(set (reg:CCZ FLAGS_REG)
11180         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11181                              (const_int 64))
11182                      (const_int 0)))
11183    (set (match_operand:DI 0 "register_operand" "")
11184         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11185                          (match_operand:DI 1 "register_operand" "")
11186                          (match_dup 0)))
11187    (set (match_dup 1)
11188         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11189                          (match_operand:DI 3 "register_operand" "r")
11190                          (match_dup 1)))]
11191   "TARGET_64BIT"
11192   "")
11193
11194 (define_expand "x86_64_shift_adj_2"
11195   [(use (match_operand:DI 0 "register_operand" ""))
11196    (use (match_operand:DI 1 "register_operand" ""))
11197    (use (match_operand:QI 2 "register_operand" ""))]
11198   "TARGET_64BIT"
11199 {
11200   rtx label = gen_label_rtx ();
11201   rtx tmp;
11202
11203   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11204
11205   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11206   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11207   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11208                               gen_rtx_LABEL_REF (VOIDmode, label),
11209                               pc_rtx);
11210   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11211   JUMP_LABEL (tmp) = label;
11212
11213   emit_move_insn (operands[0], operands[1]);
11214   ix86_expand_clear (operands[1]);
11215
11216   emit_label (label);
11217   LABEL_NUSES (label) = 1;
11218
11219   DONE;
11220 })
11221
11222 (define_expand "ashldi3"
11223   [(set (match_operand:DI 0 "shiftdi_operand" "")
11224         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11225                    (match_operand:QI 2 "nonmemory_operand" "")))]
11226   ""
11227   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11228
11229 (define_insn "*ashldi3_1_rex64"
11230   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11231         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11232                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11233    (clobber (reg:CC FLAGS_REG))]
11234   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11235 {
11236   switch (get_attr_type (insn))
11237     {
11238     case TYPE_ALU:
11239       gcc_assert (operands[2] == const1_rtx);
11240       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11241       return "add{q}\t%0, %0";
11242
11243     case TYPE_LEA:
11244       gcc_assert (CONST_INT_P (operands[2]));
11245       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11246       operands[1] = gen_rtx_MULT (DImode, operands[1],
11247                                   GEN_INT (1 << INTVAL (operands[2])));
11248       return "lea{q}\t{%a1, %0|%0, %a1}";
11249
11250     default:
11251       if (REG_P (operands[2]))
11252         return "sal{q}\t{%b2, %0|%0, %b2}";
11253       else if (operands[2] == const1_rtx
11254                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11255         return "sal{q}\t%0";
11256       else
11257         return "sal{q}\t{%2, %0|%0, %2}";
11258     }
11259 }
11260   [(set (attr "type")
11261      (cond [(eq_attr "alternative" "1")
11262               (const_string "lea")
11263             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11264                           (const_int 0))
11265                       (match_operand 0 "register_operand" ""))
11266                  (match_operand 2 "const1_operand" ""))
11267               (const_string "alu")
11268            ]
11269            (const_string "ishift")))
11270    (set_attr "mode" "DI")])
11271
11272 ;; Convert lea to the lea pattern to avoid flags dependency.
11273 (define_split
11274   [(set (match_operand:DI 0 "register_operand" "")
11275         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11276                    (match_operand:QI 2 "immediate_operand" "")))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && reload_completed
11279    && true_regnum (operands[0]) != true_regnum (operands[1])"
11280   [(set (match_dup 0)
11281         (mult:DI (match_dup 1)
11282                  (match_dup 2)))]
11283   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11284
11285 ;; This pattern can't accept a variable shift count, since shifts by
11286 ;; zero don't affect the flags.  We assume that shifts by constant
11287 ;; zero are optimized away.
11288 (define_insn "*ashldi3_cmp_rex64"
11289   [(set (reg FLAGS_REG)
11290         (compare
11291           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11292                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11293           (const_int 0)))
11294    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11295         (ashift:DI (match_dup 1) (match_dup 2)))]
11296   "TARGET_64BIT
11297    && (optimize_function_for_size_p (cfun)
11298        || !TARGET_PARTIAL_FLAG_REG_STALL
11299        || (operands[2] == const1_rtx
11300            && (TARGET_SHIFT1
11301                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11302    && ix86_match_ccmode (insn, CCGOCmode)
11303    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11304 {
11305   switch (get_attr_type (insn))
11306     {
11307     case TYPE_ALU:
11308       gcc_assert (operands[2] == const1_rtx);
11309       return "add{q}\t%0, %0";
11310
11311     default:
11312       if (REG_P (operands[2]))
11313         return "sal{q}\t{%b2, %0|%0, %b2}";
11314       else if (operands[2] == const1_rtx
11315                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11316         return "sal{q}\t%0";
11317       else
11318         return "sal{q}\t{%2, %0|%0, %2}";
11319     }
11320 }
11321   [(set (attr "type")
11322      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11323                           (const_int 0))
11324                       (match_operand 0 "register_operand" ""))
11325                  (match_operand 2 "const1_operand" ""))
11326               (const_string "alu")
11327            ]
11328            (const_string "ishift")))
11329    (set_attr "mode" "DI")])
11330
11331 (define_insn "*ashldi3_cconly_rex64"
11332   [(set (reg FLAGS_REG)
11333         (compare
11334           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11335                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11336           (const_int 0)))
11337    (clobber (match_scratch:DI 0 "=r"))]
11338   "TARGET_64BIT
11339    && (optimize_function_for_size_p (cfun)
11340        || !TARGET_PARTIAL_FLAG_REG_STALL
11341        || (operands[2] == const1_rtx
11342            && (TARGET_SHIFT1
11343                || TARGET_DOUBLE_WITH_ADD)))
11344    && ix86_match_ccmode (insn, CCGOCmode)
11345    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11346 {
11347   switch (get_attr_type (insn))
11348     {
11349     case TYPE_ALU:
11350       gcc_assert (operands[2] == const1_rtx);
11351       return "add{q}\t%0, %0";
11352
11353     default:
11354       if (REG_P (operands[2]))
11355         return "sal{q}\t{%b2, %0|%0, %b2}";
11356       else if (operands[2] == const1_rtx
11357                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11358         return "sal{q}\t%0";
11359       else
11360         return "sal{q}\t{%2, %0|%0, %2}";
11361     }
11362 }
11363   [(set (attr "type")
11364      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11365                           (const_int 0))
11366                       (match_operand 0 "register_operand" ""))
11367                  (match_operand 2 "const1_operand" ""))
11368               (const_string "alu")
11369            ]
11370            (const_string "ishift")))
11371    (set_attr "mode" "DI")])
11372
11373 (define_insn "*ashldi3_1"
11374   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11375         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11376                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11377    (clobber (reg:CC FLAGS_REG))]
11378   "!TARGET_64BIT"
11379   "#"
11380   [(set_attr "type" "multi")])
11381
11382 ;; By default we don't ask for a scratch register, because when DImode
11383 ;; values are manipulated, registers are already at a premium.  But if
11384 ;; we have one handy, we won't turn it away.
11385 (define_peephole2
11386   [(match_scratch:SI 3 "r")
11387    (parallel [(set (match_operand:DI 0 "register_operand" "")
11388                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11389                               (match_operand:QI 2 "nonmemory_operand" "")))
11390               (clobber (reg:CC FLAGS_REG))])
11391    (match_dup 3)]
11392   "!TARGET_64BIT && TARGET_CMOVE"
11393   [(const_int 0)]
11394   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11395
11396 (define_split
11397   [(set (match_operand:DI 0 "register_operand" "")
11398         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11399                    (match_operand:QI 2 "nonmemory_operand" "")))
11400    (clobber (reg:CC FLAGS_REG))]
11401   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11402                      ? epilogue_completed : reload_completed)"
11403   [(const_int 0)]
11404   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11405
11406 (define_insn "x86_shld"
11407   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11408         (ior:SI (ashift:SI (match_dup 0)
11409                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11410                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11411                   (minus:QI (const_int 32) (match_dup 2)))))
11412    (clobber (reg:CC FLAGS_REG))]
11413   ""
11414   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11415   [(set_attr "type" "ishift")
11416    (set_attr "prefix_0f" "1")
11417    (set_attr "mode" "SI")
11418    (set_attr "pent_pair" "np")
11419    (set_attr "athlon_decode" "vector")
11420    (set_attr "amdfam10_decode" "vector")])
11421
11422 (define_expand "x86_shift_adj_1"
11423   [(set (reg:CCZ FLAGS_REG)
11424         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11425                              (const_int 32))
11426                      (const_int 0)))
11427    (set (match_operand:SI 0 "register_operand" "")
11428         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11429                          (match_operand:SI 1 "register_operand" "")
11430                          (match_dup 0)))
11431    (set (match_dup 1)
11432         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11433                          (match_operand:SI 3 "register_operand" "r")
11434                          (match_dup 1)))]
11435   "TARGET_CMOVE"
11436   "")
11437
11438 (define_expand "x86_shift_adj_2"
11439   [(use (match_operand:SI 0 "register_operand" ""))
11440    (use (match_operand:SI 1 "register_operand" ""))
11441    (use (match_operand:QI 2 "register_operand" ""))]
11442   ""
11443 {
11444   rtx label = gen_label_rtx ();
11445   rtx tmp;
11446
11447   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11448
11449   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11450   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11451   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11452                               gen_rtx_LABEL_REF (VOIDmode, label),
11453                               pc_rtx);
11454   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11455   JUMP_LABEL (tmp) = label;
11456
11457   emit_move_insn (operands[0], operands[1]);
11458   ix86_expand_clear (operands[1]);
11459
11460   emit_label (label);
11461   LABEL_NUSES (label) = 1;
11462
11463   DONE;
11464 })
11465
11466 (define_expand "ashlsi3"
11467   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11468         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11469                    (match_operand:QI 2 "nonmemory_operand" "")))]
11470   ""
11471   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11472
11473 (define_insn "*ashlsi3_1"
11474   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11475         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11476                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11477    (clobber (reg:CC FLAGS_REG))]
11478   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11479 {
11480   switch (get_attr_type (insn))
11481     {
11482     case TYPE_ALU:
11483       gcc_assert (operands[2] == const1_rtx);
11484       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11485       return "add{l}\t%0, %0";
11486
11487     case TYPE_LEA:
11488       return "#";
11489
11490     default:
11491       if (REG_P (operands[2]))
11492         return "sal{l}\t{%b2, %0|%0, %b2}";
11493       else if (operands[2] == const1_rtx
11494                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11495         return "sal{l}\t%0";
11496       else
11497         return "sal{l}\t{%2, %0|%0, %2}";
11498     }
11499 }
11500   [(set (attr "type")
11501      (cond [(eq_attr "alternative" "1")
11502               (const_string "lea")
11503             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11504                           (const_int 0))
11505                       (match_operand 0 "register_operand" ""))
11506                  (match_operand 2 "const1_operand" ""))
11507               (const_string "alu")
11508            ]
11509            (const_string "ishift")))
11510    (set_attr "mode" "SI")])
11511
11512 ;; Convert lea to the lea pattern to avoid flags dependency.
11513 (define_split
11514   [(set (match_operand 0 "register_operand" "")
11515         (ashift (match_operand 1 "index_register_operand" "")
11516                 (match_operand:QI 2 "const_int_operand" "")))
11517    (clobber (reg:CC FLAGS_REG))]
11518   "reload_completed
11519    && true_regnum (operands[0]) != true_regnum (operands[1])
11520    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11521   [(const_int 0)]
11522 {
11523   rtx pat;
11524   enum machine_mode mode = GET_MODE (operands[0]);
11525
11526   if (GET_MODE_SIZE (mode) < 4)
11527     operands[0] = gen_lowpart (SImode, operands[0]);
11528   if (mode != Pmode)
11529     operands[1] = gen_lowpart (Pmode, operands[1]);
11530   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11531
11532   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11533   if (Pmode != SImode)
11534     pat = gen_rtx_SUBREG (SImode, pat, 0);
11535   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11536   DONE;
11537 })
11538
11539 ;; Rare case of shifting RSP is handled by generating move and shift
11540 (define_split
11541   [(set (match_operand 0 "register_operand" "")
11542         (ashift (match_operand 1 "register_operand" "")
11543                 (match_operand:QI 2 "const_int_operand" "")))
11544    (clobber (reg:CC FLAGS_REG))]
11545   "reload_completed
11546    && true_regnum (operands[0]) != true_regnum (operands[1])"
11547   [(const_int 0)]
11548 {
11549   rtx pat, clob;
11550   emit_move_insn (operands[0], operands[1]);
11551   pat = gen_rtx_SET (VOIDmode, operands[0],
11552                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11553                                      operands[0], operands[2]));
11554   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11555   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11556   DONE;
11557 })
11558
11559 (define_insn "*ashlsi3_1_zext"
11560   [(set (match_operand:DI 0 "register_operand" "=r,r")
11561         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11562                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11563    (clobber (reg:CC FLAGS_REG))]
11564   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11565 {
11566   switch (get_attr_type (insn))
11567     {
11568     case TYPE_ALU:
11569       gcc_assert (operands[2] == const1_rtx);
11570       return "add{l}\t%k0, %k0";
11571
11572     case TYPE_LEA:
11573       return "#";
11574
11575     default:
11576       if (REG_P (operands[2]))
11577         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11578       else if (operands[2] == const1_rtx
11579                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11580         return "sal{l}\t%k0";
11581       else
11582         return "sal{l}\t{%2, %k0|%k0, %2}";
11583     }
11584 }
11585   [(set (attr "type")
11586      (cond [(eq_attr "alternative" "1")
11587               (const_string "lea")
11588             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11589                      (const_int 0))
11590                  (match_operand 2 "const1_operand" ""))
11591               (const_string "alu")
11592            ]
11593            (const_string "ishift")))
11594    (set_attr "mode" "SI")])
11595
11596 ;; Convert lea to the lea pattern to avoid flags dependency.
11597 (define_split
11598   [(set (match_operand:DI 0 "register_operand" "")
11599         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11600                                 (match_operand:QI 2 "const_int_operand" ""))))
11601    (clobber (reg:CC FLAGS_REG))]
11602   "TARGET_64BIT && reload_completed
11603    && true_regnum (operands[0]) != true_regnum (operands[1])"
11604   [(set (match_dup 0) (zero_extend:DI
11605                         (subreg:SI (mult:DI (match_dup 1)
11606                                             (match_dup 2)) 0)))]
11607 {
11608   operands[1] = gen_lowpart (Pmode, operands[1]);
11609   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11610 })
11611
11612 ;; This pattern can't accept a variable shift count, since shifts by
11613 ;; zero don't affect the flags.  We assume that shifts by constant
11614 ;; zero are optimized away.
11615 (define_insn "*ashlsi3_cmp"
11616   [(set (reg FLAGS_REG)
11617         (compare
11618           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11619                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11620           (const_int 0)))
11621    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11622         (ashift:SI (match_dup 1) (match_dup 2)))]
11623    "(optimize_function_for_size_p (cfun)
11624      || !TARGET_PARTIAL_FLAG_REG_STALL
11625      || (operands[2] == const1_rtx
11626          && (TARGET_SHIFT1
11627              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11628    && ix86_match_ccmode (insn, CCGOCmode)
11629    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11630 {
11631   switch (get_attr_type (insn))
11632     {
11633     case TYPE_ALU:
11634       gcc_assert (operands[2] == const1_rtx);
11635       return "add{l}\t%0, %0";
11636
11637     default:
11638       if (REG_P (operands[2]))
11639         return "sal{l}\t{%b2, %0|%0, %b2}";
11640       else if (operands[2] == const1_rtx
11641                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11642         return "sal{l}\t%0";
11643       else
11644         return "sal{l}\t{%2, %0|%0, %2}";
11645     }
11646 }
11647   [(set (attr "type")
11648      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11649                           (const_int 0))
11650                       (match_operand 0 "register_operand" ""))
11651                  (match_operand 2 "const1_operand" ""))
11652               (const_string "alu")
11653            ]
11654            (const_string "ishift")))
11655    (set_attr "mode" "SI")])
11656
11657 (define_insn "*ashlsi3_cconly"
11658   [(set (reg FLAGS_REG)
11659         (compare
11660           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11661                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11662           (const_int 0)))
11663    (clobber (match_scratch:SI 0 "=r"))]
11664   "(optimize_function_for_size_p (cfun)
11665     || !TARGET_PARTIAL_FLAG_REG_STALL
11666     || (operands[2] == const1_rtx
11667         && (TARGET_SHIFT1
11668             || TARGET_DOUBLE_WITH_ADD)))
11669    && ix86_match_ccmode (insn, CCGOCmode)
11670    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11671 {
11672   switch (get_attr_type (insn))
11673     {
11674     case TYPE_ALU:
11675       gcc_assert (operands[2] == const1_rtx);
11676       return "add{l}\t%0, %0";
11677
11678     default:
11679       if (REG_P (operands[2]))
11680         return "sal{l}\t{%b2, %0|%0, %b2}";
11681       else if (operands[2] == const1_rtx
11682                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11683         return "sal{l}\t%0";
11684       else
11685         return "sal{l}\t{%2, %0|%0, %2}";
11686     }
11687 }
11688   [(set (attr "type")
11689      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11690                           (const_int 0))
11691                       (match_operand 0 "register_operand" ""))
11692                  (match_operand 2 "const1_operand" ""))
11693               (const_string "alu")
11694            ]
11695            (const_string "ishift")))
11696    (set_attr "mode" "SI")])
11697
11698 (define_insn "*ashlsi3_cmp_zext"
11699   [(set (reg FLAGS_REG)
11700         (compare
11701           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11702                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11703           (const_int 0)))
11704    (set (match_operand:DI 0 "register_operand" "=r")
11705         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11706   "TARGET_64BIT
11707    && (optimize_function_for_size_p (cfun)
11708        || !TARGET_PARTIAL_FLAG_REG_STALL
11709        || (operands[2] == const1_rtx
11710            && (TARGET_SHIFT1
11711                || TARGET_DOUBLE_WITH_ADD)))
11712    && ix86_match_ccmode (insn, CCGOCmode)
11713    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11714 {
11715   switch (get_attr_type (insn))
11716     {
11717     case TYPE_ALU:
11718       gcc_assert (operands[2] == const1_rtx);
11719       return "add{l}\t%k0, %k0";
11720
11721     default:
11722       if (REG_P (operands[2]))
11723         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11724       else if (operands[2] == const1_rtx
11725                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11726         return "sal{l}\t%k0";
11727       else
11728         return "sal{l}\t{%2, %k0|%k0, %2}";
11729     }
11730 }
11731   [(set (attr "type")
11732      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11733                      (const_int 0))
11734                  (match_operand 2 "const1_operand" ""))
11735               (const_string "alu")
11736            ]
11737            (const_string "ishift")))
11738    (set_attr "mode" "SI")])
11739
11740 (define_expand "ashlhi3"
11741   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11742         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11743                    (match_operand:QI 2 "nonmemory_operand" "")))]
11744   "TARGET_HIMODE_MATH"
11745   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11746
11747 (define_insn "*ashlhi3_1_lea"
11748   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11749         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11750                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11751    (clobber (reg:CC FLAGS_REG))]
11752   "!TARGET_PARTIAL_REG_STALL
11753    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11754 {
11755   switch (get_attr_type (insn))
11756     {
11757     case TYPE_LEA:
11758       return "#";
11759     case TYPE_ALU:
11760       gcc_assert (operands[2] == const1_rtx);
11761       return "add{w}\t%0, %0";
11762
11763     default:
11764       if (REG_P (operands[2]))
11765         return "sal{w}\t{%b2, %0|%0, %b2}";
11766       else if (operands[2] == const1_rtx
11767                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11768         return "sal{w}\t%0";
11769       else
11770         return "sal{w}\t{%2, %0|%0, %2}";
11771     }
11772 }
11773   [(set (attr "type")
11774      (cond [(eq_attr "alternative" "1")
11775               (const_string "lea")
11776             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11777                           (const_int 0))
11778                       (match_operand 0 "register_operand" ""))
11779                  (match_operand 2 "const1_operand" ""))
11780               (const_string "alu")
11781            ]
11782            (const_string "ishift")))
11783    (set_attr "mode" "HI,SI")])
11784
11785 (define_insn "*ashlhi3_1"
11786   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11787         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11788                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11789    (clobber (reg:CC FLAGS_REG))]
11790   "TARGET_PARTIAL_REG_STALL
11791    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11792 {
11793   switch (get_attr_type (insn))
11794     {
11795     case TYPE_ALU:
11796       gcc_assert (operands[2] == const1_rtx);
11797       return "add{w}\t%0, %0";
11798
11799     default:
11800       if (REG_P (operands[2]))
11801         return "sal{w}\t{%b2, %0|%0, %b2}";
11802       else if (operands[2] == const1_rtx
11803                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11804         return "sal{w}\t%0";
11805       else
11806         return "sal{w}\t{%2, %0|%0, %2}";
11807     }
11808 }
11809   [(set (attr "type")
11810      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11811                           (const_int 0))
11812                       (match_operand 0 "register_operand" ""))
11813                  (match_operand 2 "const1_operand" ""))
11814               (const_string "alu")
11815            ]
11816            (const_string "ishift")))
11817    (set_attr "mode" "HI")])
11818
11819 ;; This pattern can't accept a variable shift count, since shifts by
11820 ;; zero don't affect the flags.  We assume that shifts by constant
11821 ;; zero are optimized away.
11822 (define_insn "*ashlhi3_cmp"
11823   [(set (reg FLAGS_REG)
11824         (compare
11825           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11826                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11827           (const_int 0)))
11828    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11829         (ashift:HI (match_dup 1) (match_dup 2)))]
11830   "(optimize_function_for_size_p (cfun)
11831     || !TARGET_PARTIAL_FLAG_REG_STALL
11832     || (operands[2] == const1_rtx
11833         && (TARGET_SHIFT1
11834             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11835    && ix86_match_ccmode (insn, CCGOCmode)
11836    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11837 {
11838   switch (get_attr_type (insn))
11839     {
11840     case TYPE_ALU:
11841       gcc_assert (operands[2] == const1_rtx);
11842       return "add{w}\t%0, %0";
11843
11844     default:
11845       if (REG_P (operands[2]))
11846         return "sal{w}\t{%b2, %0|%0, %b2}";
11847       else if (operands[2] == const1_rtx
11848                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11849         return "sal{w}\t%0";
11850       else
11851         return "sal{w}\t{%2, %0|%0, %2}";
11852     }
11853 }
11854   [(set (attr "type")
11855      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11856                           (const_int 0))
11857                       (match_operand 0 "register_operand" ""))
11858                  (match_operand 2 "const1_operand" ""))
11859               (const_string "alu")
11860            ]
11861            (const_string "ishift")))
11862    (set_attr "mode" "HI")])
11863
11864 (define_insn "*ashlhi3_cconly"
11865   [(set (reg FLAGS_REG)
11866         (compare
11867           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11868                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11869           (const_int 0)))
11870    (clobber (match_scratch:HI 0 "=r"))]
11871   "(optimize_function_for_size_p (cfun)
11872     || !TARGET_PARTIAL_FLAG_REG_STALL
11873     || (operands[2] == const1_rtx
11874         && (TARGET_SHIFT1
11875             || TARGET_DOUBLE_WITH_ADD)))
11876    && ix86_match_ccmode (insn, CCGOCmode)
11877    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11878 {
11879   switch (get_attr_type (insn))
11880     {
11881     case TYPE_ALU:
11882       gcc_assert (operands[2] == const1_rtx);
11883       return "add{w}\t%0, %0";
11884
11885     default:
11886       if (REG_P (operands[2]))
11887         return "sal{w}\t{%b2, %0|%0, %b2}";
11888       else if (operands[2] == const1_rtx
11889                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11890         return "sal{w}\t%0";
11891       else
11892         return "sal{w}\t{%2, %0|%0, %2}";
11893     }
11894 }
11895   [(set (attr "type")
11896      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11897                           (const_int 0))
11898                       (match_operand 0 "register_operand" ""))
11899                  (match_operand 2 "const1_operand" ""))
11900               (const_string "alu")
11901            ]
11902            (const_string "ishift")))
11903    (set_attr "mode" "HI")])
11904
11905 (define_expand "ashlqi3"
11906   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11907         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11908                    (match_operand:QI 2 "nonmemory_operand" "")))]
11909   "TARGET_QIMODE_MATH"
11910   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11911
11912 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11913
11914 (define_insn "*ashlqi3_1_lea"
11915   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11916         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11917                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11918    (clobber (reg:CC FLAGS_REG))]
11919   "!TARGET_PARTIAL_REG_STALL
11920    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11921 {
11922   switch (get_attr_type (insn))
11923     {
11924     case TYPE_LEA:
11925       return "#";
11926     case TYPE_ALU:
11927       gcc_assert (operands[2] == const1_rtx);
11928       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11929         return "add{l}\t%k0, %k0";
11930       else
11931         return "add{b}\t%0, %0";
11932
11933     default:
11934       if (REG_P (operands[2]))
11935         {
11936           if (get_attr_mode (insn) == MODE_SI)
11937             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11938           else
11939             return "sal{b}\t{%b2, %0|%0, %b2}";
11940         }
11941       else if (operands[2] == const1_rtx
11942                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11943         {
11944           if (get_attr_mode (insn) == MODE_SI)
11945             return "sal{l}\t%0";
11946           else
11947             return "sal{b}\t%0";
11948         }
11949       else
11950         {
11951           if (get_attr_mode (insn) == MODE_SI)
11952             return "sal{l}\t{%2, %k0|%k0, %2}";
11953           else
11954             return "sal{b}\t{%2, %0|%0, %2}";
11955         }
11956     }
11957 }
11958   [(set (attr "type")
11959      (cond [(eq_attr "alternative" "2")
11960               (const_string "lea")
11961             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11962                           (const_int 0))
11963                       (match_operand 0 "register_operand" ""))
11964                  (match_operand 2 "const1_operand" ""))
11965               (const_string "alu")
11966            ]
11967            (const_string "ishift")))
11968    (set_attr "mode" "QI,SI,SI")])
11969
11970 (define_insn "*ashlqi3_1"
11971   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11972         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11973                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11974    (clobber (reg:CC FLAGS_REG))]
11975   "TARGET_PARTIAL_REG_STALL
11976    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11977 {
11978   switch (get_attr_type (insn))
11979     {
11980     case TYPE_ALU:
11981       gcc_assert (operands[2] == const1_rtx);
11982       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11983         return "add{l}\t%k0, %k0";
11984       else
11985         return "add{b}\t%0, %0";
11986
11987     default:
11988       if (REG_P (operands[2]))
11989         {
11990           if (get_attr_mode (insn) == MODE_SI)
11991             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11992           else
11993             return "sal{b}\t{%b2, %0|%0, %b2}";
11994         }
11995       else if (operands[2] == const1_rtx
11996                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11997         {
11998           if (get_attr_mode (insn) == MODE_SI)
11999             return "sal{l}\t%0";
12000           else
12001             return "sal{b}\t%0";
12002         }
12003       else
12004         {
12005           if (get_attr_mode (insn) == MODE_SI)
12006             return "sal{l}\t{%2, %k0|%k0, %2}";
12007           else
12008             return "sal{b}\t{%2, %0|%0, %2}";
12009         }
12010     }
12011 }
12012   [(set (attr "type")
12013      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12014                           (const_int 0))
12015                       (match_operand 0 "register_operand" ""))
12016                  (match_operand 2 "const1_operand" ""))
12017               (const_string "alu")
12018            ]
12019            (const_string "ishift")))
12020    (set_attr "mode" "QI,SI")])
12021
12022 ;; This pattern can't accept a variable shift count, since shifts by
12023 ;; zero don't affect the flags.  We assume that shifts by constant
12024 ;; zero are optimized away.
12025 (define_insn "*ashlqi3_cmp"
12026   [(set (reg FLAGS_REG)
12027         (compare
12028           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12029                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12030           (const_int 0)))
12031    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12032         (ashift:QI (match_dup 1) (match_dup 2)))]
12033   "(optimize_function_for_size_p (cfun)
12034     || !TARGET_PARTIAL_FLAG_REG_STALL
12035     || (operands[2] == const1_rtx
12036         && (TARGET_SHIFT1
12037             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12038    && ix86_match_ccmode (insn, CCGOCmode)
12039    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12040 {
12041   switch (get_attr_type (insn))
12042     {
12043     case TYPE_ALU:
12044       gcc_assert (operands[2] == const1_rtx);
12045       return "add{b}\t%0, %0";
12046
12047     default:
12048       if (REG_P (operands[2]))
12049         return "sal{b}\t{%b2, %0|%0, %b2}";
12050       else if (operands[2] == const1_rtx
12051                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12052         return "sal{b}\t%0";
12053       else
12054         return "sal{b}\t{%2, %0|%0, %2}";
12055     }
12056 }
12057   [(set (attr "type")
12058      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12059                           (const_int 0))
12060                       (match_operand 0 "register_operand" ""))
12061                  (match_operand 2 "const1_operand" ""))
12062               (const_string "alu")
12063            ]
12064            (const_string "ishift")))
12065    (set_attr "mode" "QI")])
12066
12067 (define_insn "*ashlqi3_cconly"
12068   [(set (reg FLAGS_REG)
12069         (compare
12070           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12071                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12072           (const_int 0)))
12073    (clobber (match_scratch:QI 0 "=q"))]
12074   "(optimize_function_for_size_p (cfun)
12075     || !TARGET_PARTIAL_FLAG_REG_STALL
12076     || (operands[2] == const1_rtx
12077         && (TARGET_SHIFT1
12078             || TARGET_DOUBLE_WITH_ADD)))
12079    && ix86_match_ccmode (insn, CCGOCmode)
12080    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12081 {
12082   switch (get_attr_type (insn))
12083     {
12084     case TYPE_ALU:
12085       gcc_assert (operands[2] == const1_rtx);
12086       return "add{b}\t%0, %0";
12087
12088     default:
12089       if (REG_P (operands[2]))
12090         return "sal{b}\t{%b2, %0|%0, %b2}";
12091       else if (operands[2] == const1_rtx
12092                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12093         return "sal{b}\t%0";
12094       else
12095         return "sal{b}\t{%2, %0|%0, %2}";
12096     }
12097 }
12098   [(set (attr "type")
12099      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12100                           (const_int 0))
12101                       (match_operand 0 "register_operand" ""))
12102                  (match_operand 2 "const1_operand" ""))
12103               (const_string "alu")
12104            ]
12105            (const_string "ishift")))
12106    (set_attr "mode" "QI")])
12107
12108 ;; See comment above `ashldi3' about how this works.
12109
12110 (define_expand "ashrti3"
12111   [(set (match_operand:TI 0 "register_operand" "")
12112         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12113                      (match_operand:QI 2 "nonmemory_operand" "")))]
12114   "TARGET_64BIT"
12115   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12116
12117 (define_insn "*ashrti3_1"
12118   [(set (match_operand:TI 0 "register_operand" "=r")
12119         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12120                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12121    (clobber (reg:CC FLAGS_REG))]
12122   "TARGET_64BIT"
12123   "#"
12124   [(set_attr "type" "multi")])
12125
12126 (define_peephole2
12127   [(match_scratch:DI 3 "r")
12128    (parallel [(set (match_operand:TI 0 "register_operand" "")
12129                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12130                                 (match_operand:QI 2 "nonmemory_operand" "")))
12131               (clobber (reg:CC FLAGS_REG))])
12132    (match_dup 3)]
12133   "TARGET_64BIT"
12134   [(const_int 0)]
12135   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12136
12137 (define_split
12138   [(set (match_operand:TI 0 "register_operand" "")
12139         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12140                      (match_operand:QI 2 "nonmemory_operand" "")))
12141    (clobber (reg:CC FLAGS_REG))]
12142   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12143                     ? epilogue_completed : reload_completed)"
12144   [(const_int 0)]
12145   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12146
12147 (define_insn "x86_64_shrd"
12148   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12149         (ior:DI (ashiftrt:DI (match_dup 0)
12150                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12151                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12152                   (minus:QI (const_int 64) (match_dup 2)))))
12153    (clobber (reg:CC FLAGS_REG))]
12154   "TARGET_64BIT"
12155   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12156   [(set_attr "type" "ishift")
12157    (set_attr "prefix_0f" "1")
12158    (set_attr "mode" "DI")
12159    (set_attr "athlon_decode" "vector")
12160    (set_attr "amdfam10_decode" "vector")])
12161
12162 (define_expand "ashrdi3"
12163   [(set (match_operand:DI 0 "shiftdi_operand" "")
12164         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12165                      (match_operand:QI 2 "nonmemory_operand" "")))]
12166   ""
12167   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12168
12169 (define_expand "x86_64_shift_adj_3"
12170   [(use (match_operand:DI 0 "register_operand" ""))
12171    (use (match_operand:DI 1 "register_operand" ""))
12172    (use (match_operand:QI 2 "register_operand" ""))]
12173   ""
12174 {
12175   rtx label = gen_label_rtx ();
12176   rtx tmp;
12177
12178   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12179
12180   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12181   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12182   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12183                               gen_rtx_LABEL_REF (VOIDmode, label),
12184                               pc_rtx);
12185   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12186   JUMP_LABEL (tmp) = label;
12187
12188   emit_move_insn (operands[0], operands[1]);
12189   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12190
12191   emit_label (label);
12192   LABEL_NUSES (label) = 1;
12193
12194   DONE;
12195 })
12196
12197 (define_insn "ashrdi3_63_rex64"
12198   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12199         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12200                      (match_operand:DI 2 "const_int_operand" "i,i")))
12201    (clobber (reg:CC FLAGS_REG))]
12202   "TARGET_64BIT && INTVAL (operands[2]) == 63
12203    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12204    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12205   "@
12206    {cqto|cqo}
12207    sar{q}\t{%2, %0|%0, %2}"
12208   [(set_attr "type" "imovx,ishift")
12209    (set_attr "prefix_0f" "0,*")
12210    (set_attr "length_immediate" "0,*")
12211    (set_attr "modrm" "0,1")
12212    (set_attr "mode" "DI")])
12213
12214 (define_insn "*ashrdi3_1_one_bit_rex64"
12215   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12216         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12217                      (match_operand:QI 2 "const1_operand" "")))
12218    (clobber (reg:CC FLAGS_REG))]
12219   "TARGET_64BIT
12220    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12221    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12222   "sar{q}\t%0"
12223   [(set_attr "type" "ishift")
12224    (set (attr "length")
12225      (if_then_else (match_operand:DI 0 "register_operand" "")
12226         (const_string "2")
12227         (const_string "*")))])
12228
12229 (define_insn "*ashrdi3_1_rex64"
12230   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12231         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12232                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12233    (clobber (reg:CC FLAGS_REG))]
12234   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12235   "@
12236    sar{q}\t{%2, %0|%0, %2}
12237    sar{q}\t{%b2, %0|%0, %b2}"
12238   [(set_attr "type" "ishift")
12239    (set_attr "mode" "DI")])
12240
12241 ;; This pattern can't accept a variable shift count, since shifts by
12242 ;; zero don't affect the flags.  We assume that shifts by constant
12243 ;; zero are optimized away.
12244 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12245   [(set (reg FLAGS_REG)
12246         (compare
12247           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12248                        (match_operand:QI 2 "const1_operand" ""))
12249           (const_int 0)))
12250    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12251         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12252   "TARGET_64BIT
12253    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12254    && ix86_match_ccmode (insn, CCGOCmode)
12255    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12256   "sar{q}\t%0"
12257   [(set_attr "type" "ishift")
12258    (set (attr "length")
12259      (if_then_else (match_operand:DI 0 "register_operand" "")
12260         (const_string "2")
12261         (const_string "*")))])
12262
12263 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const1_operand" ""))
12268           (const_int 0)))
12269    (clobber (match_scratch:DI 0 "=r"))]
12270   "TARGET_64BIT
12271    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12272    && ix86_match_ccmode (insn, CCGOCmode)
12273    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12274   "sar{q}\t%0"
12275   [(set_attr "type" "ishift")
12276    (set_attr "length" "2")])
12277
12278 ;; This pattern can't accept a variable shift count, since shifts by
12279 ;; zero don't affect the flags.  We assume that shifts by constant
12280 ;; zero are optimized away.
12281 (define_insn "*ashrdi3_cmp_rex64"
12282   [(set (reg FLAGS_REG)
12283         (compare
12284           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12285                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12286           (const_int 0)))
12287    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12288         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12289   "TARGET_64BIT
12290    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12291    && ix86_match_ccmode (insn, CCGOCmode)
12292    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12293   "sar{q}\t{%2, %0|%0, %2}"
12294   [(set_attr "type" "ishift")
12295    (set_attr "mode" "DI")])
12296
12297 (define_insn "*ashrdi3_cconly_rex64"
12298   [(set (reg FLAGS_REG)
12299         (compare
12300           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12301                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12302           (const_int 0)))
12303    (clobber (match_scratch:DI 0 "=r"))]
12304   "TARGET_64BIT
12305    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12306    && ix86_match_ccmode (insn, CCGOCmode)
12307    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12308   "sar{q}\t{%2, %0|%0, %2}"
12309   [(set_attr "type" "ishift")
12310    (set_attr "mode" "DI")])
12311
12312 (define_insn "*ashrdi3_1"
12313   [(set (match_operand:DI 0 "register_operand" "=r")
12314         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12315                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12316    (clobber (reg:CC FLAGS_REG))]
12317   "!TARGET_64BIT"
12318   "#"
12319   [(set_attr "type" "multi")])
12320
12321 ;; By default we don't ask for a scratch register, because when DImode
12322 ;; values are manipulated, registers are already at a premium.  But if
12323 ;; we have one handy, we won't turn it away.
12324 (define_peephole2
12325   [(match_scratch:SI 3 "r")
12326    (parallel [(set (match_operand:DI 0 "register_operand" "")
12327                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12328                                 (match_operand:QI 2 "nonmemory_operand" "")))
12329               (clobber (reg:CC FLAGS_REG))])
12330    (match_dup 3)]
12331   "!TARGET_64BIT && TARGET_CMOVE"
12332   [(const_int 0)]
12333   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12334
12335 (define_split
12336   [(set (match_operand:DI 0 "register_operand" "")
12337         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12338                      (match_operand:QI 2 "nonmemory_operand" "")))
12339    (clobber (reg:CC FLAGS_REG))]
12340   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12341                      ? epilogue_completed : reload_completed)"
12342   [(const_int 0)]
12343   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12344
12345 (define_insn "x86_shrd"
12346   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12347         (ior:SI (ashiftrt:SI (match_dup 0)
12348                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12349                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12350                   (minus:QI (const_int 32) (match_dup 2)))))
12351    (clobber (reg:CC FLAGS_REG))]
12352   ""
12353   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12354   [(set_attr "type" "ishift")
12355    (set_attr "prefix_0f" "1")
12356    (set_attr "pent_pair" "np")
12357    (set_attr "mode" "SI")])
12358
12359 (define_expand "x86_shift_adj_3"
12360   [(use (match_operand:SI 0 "register_operand" ""))
12361    (use (match_operand:SI 1 "register_operand" ""))
12362    (use (match_operand:QI 2 "register_operand" ""))]
12363   ""
12364 {
12365   rtx label = gen_label_rtx ();
12366   rtx tmp;
12367
12368   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12369
12370   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12371   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12372   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12373                               gen_rtx_LABEL_REF (VOIDmode, label),
12374                               pc_rtx);
12375   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12376   JUMP_LABEL (tmp) = label;
12377
12378   emit_move_insn (operands[0], operands[1]);
12379   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12380
12381   emit_label (label);
12382   LABEL_NUSES (label) = 1;
12383
12384   DONE;
12385 })
12386
12387 (define_expand "ashrsi3_31"
12388   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12389                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12390                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12391               (clobber (reg:CC FLAGS_REG))])]
12392   "")
12393
12394 (define_insn "*ashrsi3_31"
12395   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12396         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12397                      (match_operand:SI 2 "const_int_operand" "i,i")))
12398    (clobber (reg:CC FLAGS_REG))]
12399   "INTVAL (operands[2]) == 31
12400    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12401    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12402   "@
12403    {cltd|cdq}
12404    sar{l}\t{%2, %0|%0, %2}"
12405   [(set_attr "type" "imovx,ishift")
12406    (set_attr "prefix_0f" "0,*")
12407    (set_attr "length_immediate" "0,*")
12408    (set_attr "modrm" "0,1")
12409    (set_attr "mode" "SI")])
12410
12411 (define_insn "*ashrsi3_31_zext"
12412   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12413         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12414                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12417    && INTVAL (operands[2]) == 31
12418    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12419   "@
12420    {cltd|cdq}
12421    sar{l}\t{%2, %k0|%k0, %2}"
12422   [(set_attr "type" "imovx,ishift")
12423    (set_attr "prefix_0f" "0,*")
12424    (set_attr "length_immediate" "0,*")
12425    (set_attr "modrm" "0,1")
12426    (set_attr "mode" "SI")])
12427
12428 (define_expand "ashrsi3"
12429   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12430         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12431                      (match_operand:QI 2 "nonmemory_operand" "")))]
12432   ""
12433   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12434
12435 (define_insn "*ashrsi3_1_one_bit"
12436   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12437         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12438                      (match_operand:QI 2 "const1_operand" "")))
12439    (clobber (reg:CC FLAGS_REG))]
12440   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12441    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12442   "sar{l}\t%0"
12443   [(set_attr "type" "ishift")
12444    (set (attr "length")
12445      (if_then_else (match_operand:SI 0 "register_operand" "")
12446         (const_string "2")
12447         (const_string "*")))])
12448
12449 (define_insn "*ashrsi3_1_one_bit_zext"
12450   [(set (match_operand:DI 0 "register_operand" "=r")
12451         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12452                                      (match_operand:QI 2 "const1_operand" ""))))
12453    (clobber (reg:CC FLAGS_REG))]
12454   "TARGET_64BIT
12455    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12456    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12457   "sar{l}\t%k0"
12458   [(set_attr "type" "ishift")
12459    (set_attr "length" "2")])
12460
12461 (define_insn "*ashrsi3_1"
12462   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12463         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12464                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12465    (clobber (reg:CC FLAGS_REG))]
12466   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12467   "@
12468    sar{l}\t{%2, %0|%0, %2}
12469    sar{l}\t{%b2, %0|%0, %b2}"
12470   [(set_attr "type" "ishift")
12471    (set_attr "mode" "SI")])
12472
12473 (define_insn "*ashrsi3_1_zext"
12474   [(set (match_operand:DI 0 "register_operand" "=r,r")
12475         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12476                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12477    (clobber (reg:CC FLAGS_REG))]
12478   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12479   "@
12480    sar{l}\t{%2, %k0|%k0, %2}
12481    sar{l}\t{%b2, %k0|%k0, %b2}"
12482   [(set_attr "type" "ishift")
12483    (set_attr "mode" "SI")])
12484
12485 ;; This pattern can't accept a variable shift count, since shifts by
12486 ;; zero don't affect the flags.  We assume that shifts by constant
12487 ;; zero are optimized away.
12488 (define_insn "*ashrsi3_one_bit_cmp"
12489   [(set (reg FLAGS_REG)
12490         (compare
12491           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12492                        (match_operand:QI 2 "const1_operand" ""))
12493           (const_int 0)))
12494    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12495         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12496   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12497    && ix86_match_ccmode (insn, CCGOCmode)
12498    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12499   "sar{l}\t%0"
12500   [(set_attr "type" "ishift")
12501    (set (attr "length")
12502      (if_then_else (match_operand:SI 0 "register_operand" "")
12503         (const_string "2")
12504         (const_string "*")))])
12505
12506 (define_insn "*ashrsi3_one_bit_cconly"
12507   [(set (reg FLAGS_REG)
12508         (compare
12509           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510                        (match_operand:QI 2 "const1_operand" ""))
12511           (const_int 0)))
12512    (clobber (match_scratch:SI 0 "=r"))]
12513   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12514    && ix86_match_ccmode (insn, CCGOCmode)
12515    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12516   "sar{l}\t%0"
12517   [(set_attr "type" "ishift")
12518    (set_attr "length" "2")])
12519
12520 (define_insn "*ashrsi3_one_bit_cmp_zext"
12521   [(set (reg FLAGS_REG)
12522         (compare
12523           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12524                        (match_operand:QI 2 "const1_operand" ""))
12525           (const_int 0)))
12526    (set (match_operand:DI 0 "register_operand" "=r")
12527         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12528   "TARGET_64BIT
12529    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12530    && ix86_match_ccmode (insn, CCmode)
12531    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12532   "sar{l}\t%k0"
12533   [(set_attr "type" "ishift")
12534    (set_attr "length" "2")])
12535
12536 ;; This pattern can't accept a variable shift count, since shifts by
12537 ;; zero don't affect the flags.  We assume that shifts by constant
12538 ;; zero are optimized away.
12539 (define_insn "*ashrsi3_cmp"
12540   [(set (reg FLAGS_REG)
12541         (compare
12542           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12543                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12544           (const_int 0)))
12545    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12546         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12547   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12548    && ix86_match_ccmode (insn, CCGOCmode)
12549    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12550   "sar{l}\t{%2, %0|%0, %2}"
12551   [(set_attr "type" "ishift")
12552    (set_attr "mode" "SI")])
12553
12554 (define_insn "*ashrsi3_cconly"
12555   [(set (reg FLAGS_REG)
12556         (compare
12557           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12558                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12559           (const_int 0)))
12560    (clobber (match_scratch:SI 0 "=r"))]
12561   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12562    && ix86_match_ccmode (insn, CCGOCmode)
12563    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12564   "sar{l}\t{%2, %0|%0, %2}"
12565   [(set_attr "type" "ishift")
12566    (set_attr "mode" "SI")])
12567
12568 (define_insn "*ashrsi3_cmp_zext"
12569   [(set (reg FLAGS_REG)
12570         (compare
12571           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12572                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12573           (const_int 0)))
12574    (set (match_operand:DI 0 "register_operand" "=r")
12575         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12576   "TARGET_64BIT
12577    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12578    && ix86_match_ccmode (insn, CCGOCmode)
12579    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12580   "sar{l}\t{%2, %k0|%k0, %2}"
12581   [(set_attr "type" "ishift")
12582    (set_attr "mode" "SI")])
12583
12584 (define_expand "ashrhi3"
12585   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12586         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12587                      (match_operand:QI 2 "nonmemory_operand" "")))]
12588   "TARGET_HIMODE_MATH"
12589   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12590
12591 (define_insn "*ashrhi3_1_one_bit"
12592   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12593         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12594                      (match_operand:QI 2 "const1_operand" "")))
12595    (clobber (reg:CC FLAGS_REG))]
12596   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12597    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12598   "sar{w}\t%0"
12599   [(set_attr "type" "ishift")
12600    (set (attr "length")
12601      (if_then_else (match_operand 0 "register_operand" "")
12602         (const_string "2")
12603         (const_string "*")))])
12604
12605 (define_insn "*ashrhi3_1"
12606   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12607         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12608                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12609    (clobber (reg:CC FLAGS_REG))]
12610   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12611   "@
12612    sar{w}\t{%2, %0|%0, %2}
12613    sar{w}\t{%b2, %0|%0, %b2}"
12614   [(set_attr "type" "ishift")
12615    (set_attr "mode" "HI")])
12616
12617 ;; This pattern can't accept a variable shift count, since shifts by
12618 ;; zero don't affect the flags.  We assume that shifts by constant
12619 ;; zero are optimized away.
12620 (define_insn "*ashrhi3_one_bit_cmp"
12621   [(set (reg FLAGS_REG)
12622         (compare
12623           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12624                        (match_operand:QI 2 "const1_operand" ""))
12625           (const_int 0)))
12626    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12627         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12628   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12629    && ix86_match_ccmode (insn, CCGOCmode)
12630    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12631   "sar{w}\t%0"
12632   [(set_attr "type" "ishift")
12633    (set (attr "length")
12634      (if_then_else (match_operand 0 "register_operand" "")
12635         (const_string "2")
12636         (const_string "*")))])
12637
12638 (define_insn "*ashrhi3_one_bit_cconly"
12639   [(set (reg FLAGS_REG)
12640         (compare
12641           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12642                        (match_operand:QI 2 "const1_operand" ""))
12643           (const_int 0)))
12644    (clobber (match_scratch:HI 0 "=r"))]
12645   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12646    && ix86_match_ccmode (insn, CCGOCmode)
12647    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12648   "sar{w}\t%0"
12649   [(set_attr "type" "ishift")
12650    (set_attr "length" "2")])
12651
12652 ;; This pattern can't accept a variable shift count, since shifts by
12653 ;; zero don't affect the flags.  We assume that shifts by constant
12654 ;; zero are optimized away.
12655 (define_insn "*ashrhi3_cmp"
12656   [(set (reg FLAGS_REG)
12657         (compare
12658           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12659                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12660           (const_int 0)))
12661    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12662         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12663   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12664    && ix86_match_ccmode (insn, CCGOCmode)
12665    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12666   "sar{w}\t{%2, %0|%0, %2}"
12667   [(set_attr "type" "ishift")
12668    (set_attr "mode" "HI")])
12669
12670 (define_insn "*ashrhi3_cconly"
12671   [(set (reg FLAGS_REG)
12672         (compare
12673           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12674                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12675           (const_int 0)))
12676    (clobber (match_scratch:HI 0 "=r"))]
12677   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12678    && ix86_match_ccmode (insn, CCGOCmode)
12679    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12680   "sar{w}\t{%2, %0|%0, %2}"
12681   [(set_attr "type" "ishift")
12682    (set_attr "mode" "HI")])
12683
12684 (define_expand "ashrqi3"
12685   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12686         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12687                      (match_operand:QI 2 "nonmemory_operand" "")))]
12688   "TARGET_QIMODE_MATH"
12689   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12690
12691 (define_insn "*ashrqi3_1_one_bit"
12692   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12693         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12694                      (match_operand:QI 2 "const1_operand" "")))
12695    (clobber (reg:CC FLAGS_REG))]
12696   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12697    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12698   "sar{b}\t%0"
12699   [(set_attr "type" "ishift")
12700    (set (attr "length")
12701      (if_then_else (match_operand 0 "register_operand" "")
12702         (const_string "2")
12703         (const_string "*")))])
12704
12705 (define_insn "*ashrqi3_1_one_bit_slp"
12706   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12707         (ashiftrt:QI (match_dup 0)
12708                      (match_operand:QI 1 "const1_operand" "")))
12709    (clobber (reg:CC FLAGS_REG))]
12710   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12711    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12712    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12713   "sar{b}\t%0"
12714   [(set_attr "type" "ishift1")
12715    (set (attr "length")
12716      (if_then_else (match_operand 0 "register_operand" "")
12717         (const_string "2")
12718         (const_string "*")))])
12719
12720 (define_insn "*ashrqi3_1"
12721   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12722         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12723                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12724    (clobber (reg:CC FLAGS_REG))]
12725   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12726   "@
12727    sar{b}\t{%2, %0|%0, %2}
12728    sar{b}\t{%b2, %0|%0, %b2}"
12729   [(set_attr "type" "ishift")
12730    (set_attr "mode" "QI")])
12731
12732 (define_insn "*ashrqi3_1_slp"
12733   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12734         (ashiftrt:QI (match_dup 0)
12735                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12736    (clobber (reg:CC FLAGS_REG))]
12737   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12738    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12739   "@
12740    sar{b}\t{%1, %0|%0, %1}
12741    sar{b}\t{%b1, %0|%0, %b1}"
12742   [(set_attr "type" "ishift1")
12743    (set_attr "mode" "QI")])
12744
12745 ;; This pattern can't accept a variable shift count, since shifts by
12746 ;; zero don't affect the flags.  We assume that shifts by constant
12747 ;; zero are optimized away.
12748 (define_insn "*ashrqi3_one_bit_cmp"
12749   [(set (reg FLAGS_REG)
12750         (compare
12751           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12752                        (match_operand:QI 2 "const1_operand" "I"))
12753           (const_int 0)))
12754    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12755         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12756   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12757    && ix86_match_ccmode (insn, CCGOCmode)
12758    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12759   "sar{b}\t%0"
12760   [(set_attr "type" "ishift")
12761    (set (attr "length")
12762      (if_then_else (match_operand 0 "register_operand" "")
12763         (const_string "2")
12764         (const_string "*")))])
12765
12766 (define_insn "*ashrqi3_one_bit_cconly"
12767   [(set (reg FLAGS_REG)
12768         (compare
12769           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12770                        (match_operand:QI 2 "const1_operand" ""))
12771           (const_int 0)))
12772    (clobber (match_scratch:QI 0 "=q"))]
12773   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12774    && ix86_match_ccmode (insn, CCGOCmode)
12775    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12776   "sar{b}\t%0"
12777   [(set_attr "type" "ishift")
12778    (set_attr "length" "2")])
12779
12780 ;; This pattern can't accept a variable shift count, since shifts by
12781 ;; zero don't affect the flags.  We assume that shifts by constant
12782 ;; zero are optimized away.
12783 (define_insn "*ashrqi3_cmp"
12784   [(set (reg FLAGS_REG)
12785         (compare
12786           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12787                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12788           (const_int 0)))
12789    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12790         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12791   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12792    && ix86_match_ccmode (insn, CCGOCmode)
12793    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12794   "sar{b}\t{%2, %0|%0, %2}"
12795   [(set_attr "type" "ishift")
12796    (set_attr "mode" "QI")])
12797
12798 (define_insn "*ashrqi3_cconly"
12799   [(set (reg FLAGS_REG)
12800         (compare
12801           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12802                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12803           (const_int 0)))
12804    (clobber (match_scratch:QI 0 "=q"))]
12805   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12806    && ix86_match_ccmode (insn, CCGOCmode)
12807    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12808   "sar{b}\t{%2, %0|%0, %2}"
12809   [(set_attr "type" "ishift")
12810    (set_attr "mode" "QI")])
12811
12812 \f
12813 ;; Logical shift instructions
12814
12815 ;; See comment above `ashldi3' about how this works.
12816
12817 (define_expand "lshrti3"
12818   [(set (match_operand:TI 0 "register_operand" "")
12819         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12820                      (match_operand:QI 2 "nonmemory_operand" "")))]
12821   "TARGET_64BIT"
12822   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12823
12824 ;; This pattern must be defined before *lshrti3_1 to prevent
12825 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12826
12827 (define_insn "*avx_lshrti3"
12828   [(set (match_operand:TI 0 "register_operand" "=x")
12829         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12830                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12831   "TARGET_AVX"
12832 {
12833   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12834   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12835 }
12836   [(set_attr "type" "sseishft")
12837    (set_attr "prefix" "vex")
12838    (set_attr "mode" "TI")])
12839
12840 (define_insn "sse2_lshrti3"
12841   [(set (match_operand:TI 0 "register_operand" "=x")
12842         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12843                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12844   "TARGET_SSE2"
12845 {
12846   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12847   return "psrldq\t{%2, %0|%0, %2}";
12848 }
12849   [(set_attr "type" "sseishft")
12850    (set_attr "prefix_data16" "1")
12851    (set_attr "mode" "TI")])
12852
12853 (define_insn "*lshrti3_1"
12854   [(set (match_operand:TI 0 "register_operand" "=r")
12855         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12856                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12857    (clobber (reg:CC FLAGS_REG))]
12858   "TARGET_64BIT"
12859   "#"
12860   [(set_attr "type" "multi")])
12861
12862 (define_peephole2
12863   [(match_scratch:DI 3 "r")
12864    (parallel [(set (match_operand:TI 0 "register_operand" "")
12865                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12866                                 (match_operand:QI 2 "nonmemory_operand" "")))
12867               (clobber (reg:CC FLAGS_REG))])
12868    (match_dup 3)]
12869   "TARGET_64BIT"
12870   [(const_int 0)]
12871   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12872
12873 (define_split
12874   [(set (match_operand:TI 0 "register_operand" "")
12875         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12876                      (match_operand:QI 2 "nonmemory_operand" "")))
12877    (clobber (reg:CC FLAGS_REG))]
12878   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12879                     ? epilogue_completed : reload_completed)"
12880   [(const_int 0)]
12881   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12882
12883 (define_expand "lshrdi3"
12884   [(set (match_operand:DI 0 "shiftdi_operand" "")
12885         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12886                      (match_operand:QI 2 "nonmemory_operand" "")))]
12887   ""
12888   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12889
12890 (define_insn "*lshrdi3_1_one_bit_rex64"
12891   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12892         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12893                      (match_operand:QI 2 "const1_operand" "")))
12894    (clobber (reg:CC FLAGS_REG))]
12895   "TARGET_64BIT
12896    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12897    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12898   "shr{q}\t%0"
12899   [(set_attr "type" "ishift")
12900    (set (attr "length")
12901      (if_then_else (match_operand:DI 0 "register_operand" "")
12902         (const_string "2")
12903         (const_string "*")))])
12904
12905 (define_insn "*lshrdi3_1_rex64"
12906   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12907         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12908                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12909    (clobber (reg:CC FLAGS_REG))]
12910   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12911   "@
12912    shr{q}\t{%2, %0|%0, %2}
12913    shr{q}\t{%b2, %0|%0, %b2}"
12914   [(set_attr "type" "ishift")
12915    (set_attr "mode" "DI")])
12916
12917 ;; This pattern can't accept a variable shift count, since shifts by
12918 ;; zero don't affect the flags.  We assume that shifts by constant
12919 ;; zero are optimized away.
12920 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12921   [(set (reg FLAGS_REG)
12922         (compare
12923           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12924                        (match_operand:QI 2 "const1_operand" ""))
12925           (const_int 0)))
12926    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12927         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12928   "TARGET_64BIT
12929    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12930    && ix86_match_ccmode (insn, CCGOCmode)
12931    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12932   "shr{q}\t%0"
12933   [(set_attr "type" "ishift")
12934    (set (attr "length")
12935      (if_then_else (match_operand:DI 0 "register_operand" "")
12936         (const_string "2")
12937         (const_string "*")))])
12938
12939 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12940   [(set (reg FLAGS_REG)
12941         (compare
12942           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12943                        (match_operand:QI 2 "const1_operand" ""))
12944           (const_int 0)))
12945    (clobber (match_scratch:DI 0 "=r"))]
12946   "TARGET_64BIT
12947    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12948    && ix86_match_ccmode (insn, CCGOCmode)
12949    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12950   "shr{q}\t%0"
12951   [(set_attr "type" "ishift")
12952    (set_attr "length" "2")])
12953
12954 ;; This pattern can't accept a variable shift count, since shifts by
12955 ;; zero don't affect the flags.  We assume that shifts by constant
12956 ;; zero are optimized away.
12957 (define_insn "*lshrdi3_cmp_rex64"
12958   [(set (reg FLAGS_REG)
12959         (compare
12960           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12961                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12962           (const_int 0)))
12963    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12964         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12965   "TARGET_64BIT
12966    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12967    && ix86_match_ccmode (insn, CCGOCmode)
12968    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12969   "shr{q}\t{%2, %0|%0, %2}"
12970   [(set_attr "type" "ishift")
12971    (set_attr "mode" "DI")])
12972
12973 (define_insn "*lshrdi3_cconly_rex64"
12974   [(set (reg FLAGS_REG)
12975         (compare
12976           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12977                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12978           (const_int 0)))
12979    (clobber (match_scratch:DI 0 "=r"))]
12980   "TARGET_64BIT
12981    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12982    && ix86_match_ccmode (insn, CCGOCmode)
12983    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12984   "shr{q}\t{%2, %0|%0, %2}"
12985   [(set_attr "type" "ishift")
12986    (set_attr "mode" "DI")])
12987
12988 (define_insn "*lshrdi3_1"
12989   [(set (match_operand:DI 0 "register_operand" "=r")
12990         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12991                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12992    (clobber (reg:CC FLAGS_REG))]
12993   "!TARGET_64BIT"
12994   "#"
12995   [(set_attr "type" "multi")])
12996
12997 ;; By default we don't ask for a scratch register, because when DImode
12998 ;; values are manipulated, registers are already at a premium.  But if
12999 ;; we have one handy, we won't turn it away.
13000 (define_peephole2
13001   [(match_scratch:SI 3 "r")
13002    (parallel [(set (match_operand:DI 0 "register_operand" "")
13003                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13004                                 (match_operand:QI 2 "nonmemory_operand" "")))
13005               (clobber (reg:CC FLAGS_REG))])
13006    (match_dup 3)]
13007   "!TARGET_64BIT && TARGET_CMOVE"
13008   [(const_int 0)]
13009   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13010
13011 (define_split
13012   [(set (match_operand:DI 0 "register_operand" "")
13013         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13014                      (match_operand:QI 2 "nonmemory_operand" "")))
13015    (clobber (reg:CC FLAGS_REG))]
13016   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13017                      ? epilogue_completed : reload_completed)"
13018   [(const_int 0)]
13019   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13020
13021 (define_expand "lshrsi3"
13022   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13023         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13024                      (match_operand:QI 2 "nonmemory_operand" "")))]
13025   ""
13026   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13027
13028 (define_insn "*lshrsi3_1_one_bit"
13029   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13030         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13031                      (match_operand:QI 2 "const1_operand" "")))
13032    (clobber (reg:CC FLAGS_REG))]
13033   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13034    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13035   "shr{l}\t%0"
13036   [(set_attr "type" "ishift")
13037    (set (attr "length")
13038      (if_then_else (match_operand:SI 0 "register_operand" "")
13039         (const_string "2")
13040         (const_string "*")))])
13041
13042 (define_insn "*lshrsi3_1_one_bit_zext"
13043   [(set (match_operand:DI 0 "register_operand" "=r")
13044         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13045                      (match_operand:QI 2 "const1_operand" "")))
13046    (clobber (reg:CC FLAGS_REG))]
13047   "TARGET_64BIT
13048    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13049    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13050   "shr{l}\t%k0"
13051   [(set_attr "type" "ishift")
13052    (set_attr "length" "2")])
13053
13054 (define_insn "*lshrsi3_1"
13055   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13056         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13057                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13058    (clobber (reg:CC FLAGS_REG))]
13059   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13060   "@
13061    shr{l}\t{%2, %0|%0, %2}
13062    shr{l}\t{%b2, %0|%0, %b2}"
13063   [(set_attr "type" "ishift")
13064    (set_attr "mode" "SI")])
13065
13066 (define_insn "*lshrsi3_1_zext"
13067   [(set (match_operand:DI 0 "register_operand" "=r,r")
13068         (zero_extend:DI
13069           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13070                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13071    (clobber (reg:CC FLAGS_REG))]
13072   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13073   "@
13074    shr{l}\t{%2, %k0|%k0, %2}
13075    shr{l}\t{%b2, %k0|%k0, %b2}"
13076   [(set_attr "type" "ishift")
13077    (set_attr "mode" "SI")])
13078
13079 ;; This pattern can't accept a variable shift count, since shifts by
13080 ;; zero don't affect the flags.  We assume that shifts by constant
13081 ;; zero are optimized away.
13082 (define_insn "*lshrsi3_one_bit_cmp"
13083   [(set (reg FLAGS_REG)
13084         (compare
13085           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13086                        (match_operand:QI 2 "const1_operand" ""))
13087           (const_int 0)))
13088    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13089         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13090   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13091    && ix86_match_ccmode (insn, CCGOCmode)
13092    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13093   "shr{l}\t%0"
13094   [(set_attr "type" "ishift")
13095    (set (attr "length")
13096      (if_then_else (match_operand:SI 0 "register_operand" "")
13097         (const_string "2")
13098         (const_string "*")))])
13099
13100 (define_insn "*lshrsi3_one_bit_cconly"
13101   [(set (reg FLAGS_REG)
13102         (compare
13103           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13104                        (match_operand:QI 2 "const1_operand" ""))
13105           (const_int 0)))
13106    (clobber (match_scratch:SI 0 "=r"))]
13107   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13108    && ix86_match_ccmode (insn, CCGOCmode)
13109    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13110   "shr{l}\t%0"
13111   [(set_attr "type" "ishift")
13112    (set_attr "length" "2")])
13113
13114 (define_insn "*lshrsi3_cmp_one_bit_zext"
13115   [(set (reg FLAGS_REG)
13116         (compare
13117           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13118                        (match_operand:QI 2 "const1_operand" ""))
13119           (const_int 0)))
13120    (set (match_operand:DI 0 "register_operand" "=r")
13121         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13122   "TARGET_64BIT
13123    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13124    && ix86_match_ccmode (insn, CCGOCmode)
13125    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13126   "shr{l}\t%k0"
13127   [(set_attr "type" "ishift")
13128    (set_attr "length" "2")])
13129
13130 ;; This pattern can't accept a variable shift count, since shifts by
13131 ;; zero don't affect the flags.  We assume that shifts by constant
13132 ;; zero are optimized away.
13133 (define_insn "*lshrsi3_cmp"
13134   [(set (reg FLAGS_REG)
13135         (compare
13136           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13137                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13138           (const_int 0)))
13139    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13140         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13141   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13142    && ix86_match_ccmode (insn, CCGOCmode)
13143    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13144   "shr{l}\t{%2, %0|%0, %2}"
13145   [(set_attr "type" "ishift")
13146    (set_attr "mode" "SI")])
13147
13148 (define_insn "*lshrsi3_cconly"
13149   [(set (reg FLAGS_REG)
13150       (compare
13151         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13152                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13153         (const_int 0)))
13154    (clobber (match_scratch:SI 0 "=r"))]
13155   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13156    && ix86_match_ccmode (insn, CCGOCmode)
13157    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13158   "shr{l}\t{%2, %0|%0, %2}"
13159   [(set_attr "type" "ishift")
13160    (set_attr "mode" "SI")])
13161
13162 (define_insn "*lshrsi3_cmp_zext"
13163   [(set (reg FLAGS_REG)
13164         (compare
13165           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13166                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13167           (const_int 0)))
13168    (set (match_operand:DI 0 "register_operand" "=r")
13169         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13170   "TARGET_64BIT
13171    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13172    && ix86_match_ccmode (insn, CCGOCmode)
13173    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13174   "shr{l}\t{%2, %k0|%k0, %2}"
13175   [(set_attr "type" "ishift")
13176    (set_attr "mode" "SI")])
13177
13178 (define_expand "lshrhi3"
13179   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13180         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13181                      (match_operand:QI 2 "nonmemory_operand" "")))]
13182   "TARGET_HIMODE_MATH"
13183   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13184
13185 (define_insn "*lshrhi3_1_one_bit"
13186   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13187         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13188                      (match_operand:QI 2 "const1_operand" "")))
13189    (clobber (reg:CC FLAGS_REG))]
13190   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13191    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13192   "shr{w}\t%0"
13193   [(set_attr "type" "ishift")
13194    (set (attr "length")
13195      (if_then_else (match_operand 0 "register_operand" "")
13196         (const_string "2")
13197         (const_string "*")))])
13198
13199 (define_insn "*lshrhi3_1"
13200   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13201         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13202                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13203    (clobber (reg:CC FLAGS_REG))]
13204   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13205   "@
13206    shr{w}\t{%2, %0|%0, %2}
13207    shr{w}\t{%b2, %0|%0, %b2}"
13208   [(set_attr "type" "ishift")
13209    (set_attr "mode" "HI")])
13210
13211 ;; This pattern can't accept a variable shift count, since shifts by
13212 ;; zero don't affect the flags.  We assume that shifts by constant
13213 ;; zero are optimized away.
13214 (define_insn "*lshrhi3_one_bit_cmp"
13215   [(set (reg FLAGS_REG)
13216         (compare
13217           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13218                        (match_operand:QI 2 "const1_operand" ""))
13219           (const_int 0)))
13220    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13221         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13222   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13223    && ix86_match_ccmode (insn, CCGOCmode)
13224    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13225   "shr{w}\t%0"
13226   [(set_attr "type" "ishift")
13227    (set (attr "length")
13228      (if_then_else (match_operand:SI 0 "register_operand" "")
13229         (const_string "2")
13230         (const_string "*")))])
13231
13232 (define_insn "*lshrhi3_one_bit_cconly"
13233   [(set (reg FLAGS_REG)
13234         (compare
13235           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13236                        (match_operand:QI 2 "const1_operand" ""))
13237           (const_int 0)))
13238    (clobber (match_scratch:HI 0 "=r"))]
13239   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13240    && ix86_match_ccmode (insn, CCGOCmode)
13241    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13242   "shr{w}\t%0"
13243   [(set_attr "type" "ishift")
13244    (set_attr "length" "2")])
13245
13246 ;; This pattern can't accept a variable shift count, since shifts by
13247 ;; zero don't affect the flags.  We assume that shifts by constant
13248 ;; zero are optimized away.
13249 (define_insn "*lshrhi3_cmp"
13250   [(set (reg FLAGS_REG)
13251         (compare
13252           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13253                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13254           (const_int 0)))
13255    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13256         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13257   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13258    && ix86_match_ccmode (insn, CCGOCmode)
13259    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13260   "shr{w}\t{%2, %0|%0, %2}"
13261   [(set_attr "type" "ishift")
13262    (set_attr "mode" "HI")])
13263
13264 (define_insn "*lshrhi3_cconly"
13265   [(set (reg FLAGS_REG)
13266         (compare
13267           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13268                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13269           (const_int 0)))
13270    (clobber (match_scratch:HI 0 "=r"))]
13271   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13272    && ix86_match_ccmode (insn, CCGOCmode)
13273    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13274   "shr{w}\t{%2, %0|%0, %2}"
13275   [(set_attr "type" "ishift")
13276    (set_attr "mode" "HI")])
13277
13278 (define_expand "lshrqi3"
13279   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13280         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13281                      (match_operand:QI 2 "nonmemory_operand" "")))]
13282   "TARGET_QIMODE_MATH"
13283   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13284
13285 (define_insn "*lshrqi3_1_one_bit"
13286   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13287         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13288                      (match_operand:QI 2 "const1_operand" "")))
13289    (clobber (reg:CC FLAGS_REG))]
13290   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13291    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13292   "shr{b}\t%0"
13293   [(set_attr "type" "ishift")
13294    (set (attr "length")
13295      (if_then_else (match_operand 0 "register_operand" "")
13296         (const_string "2")
13297         (const_string "*")))])
13298
13299 (define_insn "*lshrqi3_1_one_bit_slp"
13300   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13301         (lshiftrt:QI (match_dup 0)
13302                      (match_operand:QI 1 "const1_operand" "")))
13303    (clobber (reg:CC FLAGS_REG))]
13304   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13305    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13306   "shr{b}\t%0"
13307   [(set_attr "type" "ishift1")
13308    (set (attr "length")
13309      (if_then_else (match_operand 0 "register_operand" "")
13310         (const_string "2")
13311         (const_string "*")))])
13312
13313 (define_insn "*lshrqi3_1"
13314   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13315         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13316                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13317    (clobber (reg:CC FLAGS_REG))]
13318   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13319   "@
13320    shr{b}\t{%2, %0|%0, %2}
13321    shr{b}\t{%b2, %0|%0, %b2}"
13322   [(set_attr "type" "ishift")
13323    (set_attr "mode" "QI")])
13324
13325 (define_insn "*lshrqi3_1_slp"
13326   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13327         (lshiftrt:QI (match_dup 0)
13328                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13329    (clobber (reg:CC FLAGS_REG))]
13330   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13331    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13332   "@
13333    shr{b}\t{%1, %0|%0, %1}
13334    shr{b}\t{%b1, %0|%0, %b1}"
13335   [(set_attr "type" "ishift1")
13336    (set_attr "mode" "QI")])
13337
13338 ;; This pattern can't accept a variable shift count, since shifts by
13339 ;; zero don't affect the flags.  We assume that shifts by constant
13340 ;; zero are optimized away.
13341 (define_insn "*lshrqi2_one_bit_cmp"
13342   [(set (reg FLAGS_REG)
13343         (compare
13344           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13345                        (match_operand:QI 2 "const1_operand" ""))
13346           (const_int 0)))
13347    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13348         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13349   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13350    && ix86_match_ccmode (insn, CCGOCmode)
13351    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13352   "shr{b}\t%0"
13353   [(set_attr "type" "ishift")
13354    (set (attr "length")
13355      (if_then_else (match_operand:SI 0 "register_operand" "")
13356         (const_string "2")
13357         (const_string "*")))])
13358
13359 (define_insn "*lshrqi2_one_bit_cconly"
13360   [(set (reg FLAGS_REG)
13361         (compare
13362           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13363                        (match_operand:QI 2 "const1_operand" ""))
13364           (const_int 0)))
13365    (clobber (match_scratch:QI 0 "=q"))]
13366   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13367    && ix86_match_ccmode (insn, CCGOCmode)
13368    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13369   "shr{b}\t%0"
13370   [(set_attr "type" "ishift")
13371    (set_attr "length" "2")])
13372
13373 ;; This pattern can't accept a variable shift count, since shifts by
13374 ;; zero don't affect the flags.  We assume that shifts by constant
13375 ;; zero are optimized away.
13376 (define_insn "*lshrqi2_cmp"
13377   [(set (reg FLAGS_REG)
13378         (compare
13379           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13380                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13381           (const_int 0)))
13382    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13383         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13384   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13385    && ix86_match_ccmode (insn, CCGOCmode)
13386    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13387   "shr{b}\t{%2, %0|%0, %2}"
13388   [(set_attr "type" "ishift")
13389    (set_attr "mode" "QI")])
13390
13391 (define_insn "*lshrqi2_cconly"
13392   [(set (reg FLAGS_REG)
13393         (compare
13394           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13395                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13396           (const_int 0)))
13397    (clobber (match_scratch:QI 0 "=q"))]
13398   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13399    && ix86_match_ccmode (insn, CCGOCmode)
13400    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13401   "shr{b}\t{%2, %0|%0, %2}"
13402   [(set_attr "type" "ishift")
13403    (set_attr "mode" "QI")])
13404 \f
13405 ;; Rotate instructions
13406
13407 (define_expand "rotldi3"
13408   [(set (match_operand:DI 0 "shiftdi_operand" "")
13409         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13410                    (match_operand:QI 2 "nonmemory_operand" "")))]
13411  ""
13412 {
13413   if (TARGET_64BIT)
13414     {
13415       ix86_expand_binary_operator (ROTATE, DImode, operands);
13416       DONE;
13417     }
13418   if (!const_1_to_31_operand (operands[2], VOIDmode))
13419     FAIL;
13420   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13421   DONE;
13422 })
13423
13424 ;; Implement rotation using two double-precision shift instructions
13425 ;; and a scratch register.
13426 (define_insn_and_split "ix86_rotldi3"
13427  [(set (match_operand:DI 0 "register_operand" "=r")
13428        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13429                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13430   (clobber (reg:CC FLAGS_REG))
13431   (clobber (match_scratch:SI 3 "=&r"))]
13432  "!TARGET_64BIT"
13433  ""
13434  "&& reload_completed"
13435  [(set (match_dup 3) (match_dup 4))
13436   (parallel
13437    [(set (match_dup 4)
13438          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13439                  (lshiftrt:SI (match_dup 5)
13440                               (minus:QI (const_int 32) (match_dup 2)))))
13441     (clobber (reg:CC FLAGS_REG))])
13442   (parallel
13443    [(set (match_dup 5)
13444          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13445                  (lshiftrt:SI (match_dup 3)
13446                               (minus:QI (const_int 32) (match_dup 2)))))
13447     (clobber (reg:CC FLAGS_REG))])]
13448  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13449
13450 (define_insn "*rotlsi3_1_one_bit_rex64"
13451   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13452         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13453                    (match_operand:QI 2 "const1_operand" "")))
13454    (clobber (reg:CC FLAGS_REG))]
13455   "TARGET_64BIT
13456    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13457    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13458   "rol{q}\t%0"
13459   [(set_attr "type" "rotate")
13460    (set (attr "length")
13461      (if_then_else (match_operand:DI 0 "register_operand" "")
13462         (const_string "2")
13463         (const_string "*")))])
13464
13465 (define_insn "*rotldi3_1_rex64"
13466   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13467         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13468                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13469    (clobber (reg:CC FLAGS_REG))]
13470   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13471   "@
13472    rol{q}\t{%2, %0|%0, %2}
13473    rol{q}\t{%b2, %0|%0, %b2}"
13474   [(set_attr "type" "rotate")
13475    (set_attr "mode" "DI")])
13476
13477 (define_expand "rotlsi3"
13478   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13479         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13480                    (match_operand:QI 2 "nonmemory_operand" "")))]
13481   ""
13482   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13483
13484 (define_insn "*rotlsi3_1_one_bit"
13485   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13486         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13487                    (match_operand:QI 2 "const1_operand" "")))
13488    (clobber (reg:CC FLAGS_REG))]
13489   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13490    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13491   "rol{l}\t%0"
13492   [(set_attr "type" "rotate")
13493    (set (attr "length")
13494      (if_then_else (match_operand:SI 0 "register_operand" "")
13495         (const_string "2")
13496         (const_string "*")))])
13497
13498 (define_insn "*rotlsi3_1_one_bit_zext"
13499   [(set (match_operand:DI 0 "register_operand" "=r")
13500         (zero_extend:DI
13501           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13502                      (match_operand:QI 2 "const1_operand" ""))))
13503    (clobber (reg:CC FLAGS_REG))]
13504   "TARGET_64BIT
13505    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13506    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13507   "rol{l}\t%k0"
13508   [(set_attr "type" "rotate")
13509    (set_attr "length" "2")])
13510
13511 (define_insn "*rotlsi3_1"
13512   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13513         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13514                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13515    (clobber (reg:CC FLAGS_REG))]
13516   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13517   "@
13518    rol{l}\t{%2, %0|%0, %2}
13519    rol{l}\t{%b2, %0|%0, %b2}"
13520   [(set_attr "type" "rotate")
13521    (set_attr "mode" "SI")])
13522
13523 (define_insn "*rotlsi3_1_zext"
13524   [(set (match_operand:DI 0 "register_operand" "=r,r")
13525         (zero_extend:DI
13526           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13527                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13528    (clobber (reg:CC FLAGS_REG))]
13529   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13530   "@
13531    rol{l}\t{%2, %k0|%k0, %2}
13532    rol{l}\t{%b2, %k0|%k0, %b2}"
13533   [(set_attr "type" "rotate")
13534    (set_attr "mode" "SI")])
13535
13536 (define_expand "rotlhi3"
13537   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13538         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13539                    (match_operand:QI 2 "nonmemory_operand" "")))]
13540   "TARGET_HIMODE_MATH"
13541   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13542
13543 (define_insn "*rotlhi3_1_one_bit"
13544   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13545         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13546                    (match_operand:QI 2 "const1_operand" "")))
13547    (clobber (reg:CC FLAGS_REG))]
13548   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13549    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13550   "rol{w}\t%0"
13551   [(set_attr "type" "rotate")
13552    (set (attr "length")
13553      (if_then_else (match_operand 0 "register_operand" "")
13554         (const_string "2")
13555         (const_string "*")))])
13556
13557 (define_insn "*rotlhi3_1"
13558   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13559         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13560                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13561    (clobber (reg:CC FLAGS_REG))]
13562   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13563   "@
13564    rol{w}\t{%2, %0|%0, %2}
13565    rol{w}\t{%b2, %0|%0, %b2}"
13566   [(set_attr "type" "rotate")
13567    (set_attr "mode" "HI")])
13568
13569 (define_split
13570  [(set (match_operand:HI 0 "register_operand" "")
13571        (rotate:HI (match_dup 0) (const_int 8)))
13572   (clobber (reg:CC FLAGS_REG))]
13573  "reload_completed"
13574  [(parallel [(set (strict_low_part (match_dup 0))
13575                   (bswap:HI (match_dup 0)))
13576              (clobber (reg:CC FLAGS_REG))])]
13577  "")
13578
13579 (define_expand "rotlqi3"
13580   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13581         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13582                    (match_operand:QI 2 "nonmemory_operand" "")))]
13583   "TARGET_QIMODE_MATH"
13584   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13585
13586 (define_insn "*rotlqi3_1_one_bit_slp"
13587   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13588         (rotate:QI (match_dup 0)
13589                    (match_operand:QI 1 "const1_operand" "")))
13590    (clobber (reg:CC FLAGS_REG))]
13591   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13592    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13593   "rol{b}\t%0"
13594   [(set_attr "type" "rotate1")
13595    (set (attr "length")
13596      (if_then_else (match_operand 0 "register_operand" "")
13597         (const_string "2")
13598         (const_string "*")))])
13599
13600 (define_insn "*rotlqi3_1_one_bit"
13601   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13602         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13603                    (match_operand:QI 2 "const1_operand" "")))
13604    (clobber (reg:CC FLAGS_REG))]
13605   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13606    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13607   "rol{b}\t%0"
13608   [(set_attr "type" "rotate")
13609    (set (attr "length")
13610      (if_then_else (match_operand 0 "register_operand" "")
13611         (const_string "2")
13612         (const_string "*")))])
13613
13614 (define_insn "*rotlqi3_1_slp"
13615   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13616         (rotate:QI (match_dup 0)
13617                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13618    (clobber (reg:CC FLAGS_REG))]
13619   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13620    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13621   "@
13622    rol{b}\t{%1, %0|%0, %1}
13623    rol{b}\t{%b1, %0|%0, %b1}"
13624   [(set_attr "type" "rotate1")
13625    (set_attr "mode" "QI")])
13626
13627 (define_insn "*rotlqi3_1"
13628   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13629         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13630                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13631    (clobber (reg:CC FLAGS_REG))]
13632   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13633   "@
13634    rol{b}\t{%2, %0|%0, %2}
13635    rol{b}\t{%b2, %0|%0, %b2}"
13636   [(set_attr "type" "rotate")
13637    (set_attr "mode" "QI")])
13638
13639 (define_expand "rotrdi3"
13640   [(set (match_operand:DI 0 "shiftdi_operand" "")
13641         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13642                    (match_operand:QI 2 "nonmemory_operand" "")))]
13643  ""
13644 {
13645   if (TARGET_64BIT)
13646     {
13647       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13648       DONE;
13649     }
13650   if (!const_1_to_31_operand (operands[2], VOIDmode))
13651     FAIL;
13652   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13653   DONE;
13654 })
13655
13656 ;; Implement rotation using two double-precision shift instructions
13657 ;; and a scratch register.
13658 (define_insn_and_split "ix86_rotrdi3"
13659  [(set (match_operand:DI 0 "register_operand" "=r")
13660        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13661                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13662   (clobber (reg:CC FLAGS_REG))
13663   (clobber (match_scratch:SI 3 "=&r"))]
13664  "!TARGET_64BIT"
13665  ""
13666  "&& reload_completed"
13667  [(set (match_dup 3) (match_dup 4))
13668   (parallel
13669    [(set (match_dup 4)
13670          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13671                  (ashift:SI (match_dup 5)
13672                             (minus:QI (const_int 32) (match_dup 2)))))
13673     (clobber (reg:CC FLAGS_REG))])
13674   (parallel
13675    [(set (match_dup 5)
13676          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13677                  (ashift:SI (match_dup 3)
13678                             (minus:QI (const_int 32) (match_dup 2)))))
13679     (clobber (reg:CC FLAGS_REG))])]
13680  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13681
13682 (define_insn "*rotrdi3_1_one_bit_rex64"
13683   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13684         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13685                      (match_operand:QI 2 "const1_operand" "")))
13686    (clobber (reg:CC FLAGS_REG))]
13687   "TARGET_64BIT
13688    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13689    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13690   "ror{q}\t%0"
13691   [(set_attr "type" "rotate")
13692    (set (attr "length")
13693      (if_then_else (match_operand:DI 0 "register_operand" "")
13694         (const_string "2")
13695         (const_string "*")))])
13696
13697 (define_insn "*rotrdi3_1_rex64"
13698   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13699         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13700                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13701    (clobber (reg:CC FLAGS_REG))]
13702   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13703   "@
13704    ror{q}\t{%2, %0|%0, %2}
13705    ror{q}\t{%b2, %0|%0, %b2}"
13706   [(set_attr "type" "rotate")
13707    (set_attr "mode" "DI")])
13708
13709 (define_expand "rotrsi3"
13710   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13711         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13712                      (match_operand:QI 2 "nonmemory_operand" "")))]
13713   ""
13714   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13715
13716 (define_insn "*rotrsi3_1_one_bit"
13717   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13718         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13719                      (match_operand:QI 2 "const1_operand" "")))
13720    (clobber (reg:CC FLAGS_REG))]
13721   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13722    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13723   "ror{l}\t%0"
13724   [(set_attr "type" "rotate")
13725    (set (attr "length")
13726      (if_then_else (match_operand:SI 0 "register_operand" "")
13727         (const_string "2")
13728         (const_string "*")))])
13729
13730 (define_insn "*rotrsi3_1_one_bit_zext"
13731   [(set (match_operand:DI 0 "register_operand" "=r")
13732         (zero_extend:DI
13733           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13734                        (match_operand:QI 2 "const1_operand" ""))))
13735    (clobber (reg:CC FLAGS_REG))]
13736   "TARGET_64BIT
13737    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13738    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13739   "ror{l}\t%k0"
13740   [(set_attr "type" "rotate")
13741    (set (attr "length")
13742      (if_then_else (match_operand:SI 0 "register_operand" "")
13743         (const_string "2")
13744         (const_string "*")))])
13745
13746 (define_insn "*rotrsi3_1"
13747   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13748         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13749                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13750    (clobber (reg:CC FLAGS_REG))]
13751   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13752   "@
13753    ror{l}\t{%2, %0|%0, %2}
13754    ror{l}\t{%b2, %0|%0, %b2}"
13755   [(set_attr "type" "rotate")
13756    (set_attr "mode" "SI")])
13757
13758 (define_insn "*rotrsi3_1_zext"
13759   [(set (match_operand:DI 0 "register_operand" "=r,r")
13760         (zero_extend:DI
13761           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13762                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13763    (clobber (reg:CC FLAGS_REG))]
13764   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13765   "@
13766    ror{l}\t{%2, %k0|%k0, %2}
13767    ror{l}\t{%b2, %k0|%k0, %b2}"
13768   [(set_attr "type" "rotate")
13769    (set_attr "mode" "SI")])
13770
13771 (define_expand "rotrhi3"
13772   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13773         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13774                      (match_operand:QI 2 "nonmemory_operand" "")))]
13775   "TARGET_HIMODE_MATH"
13776   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13777
13778 (define_insn "*rotrhi3_one_bit"
13779   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13780         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13781                      (match_operand:QI 2 "const1_operand" "")))
13782    (clobber (reg:CC FLAGS_REG))]
13783   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13784    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13785   "ror{w}\t%0"
13786   [(set_attr "type" "rotate")
13787    (set (attr "length")
13788      (if_then_else (match_operand 0 "register_operand" "")
13789         (const_string "2")
13790         (const_string "*")))])
13791
13792 (define_insn "*rotrhi3_1"
13793   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13794         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13795                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13796    (clobber (reg:CC FLAGS_REG))]
13797   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13798   "@
13799    ror{w}\t{%2, %0|%0, %2}
13800    ror{w}\t{%b2, %0|%0, %b2}"
13801   [(set_attr "type" "rotate")
13802    (set_attr "mode" "HI")])
13803
13804 (define_split
13805  [(set (match_operand:HI 0 "register_operand" "")
13806        (rotatert:HI (match_dup 0) (const_int 8)))
13807   (clobber (reg:CC FLAGS_REG))]
13808  "reload_completed"
13809  [(parallel [(set (strict_low_part (match_dup 0))
13810                   (bswap:HI (match_dup 0)))
13811              (clobber (reg:CC FLAGS_REG))])]
13812  "")
13813
13814 (define_expand "rotrqi3"
13815   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13816         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13817                      (match_operand:QI 2 "nonmemory_operand" "")))]
13818   "TARGET_QIMODE_MATH"
13819   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13820
13821 (define_insn "*rotrqi3_1_one_bit"
13822   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13823         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13824                      (match_operand:QI 2 "const1_operand" "")))
13825    (clobber (reg:CC FLAGS_REG))]
13826   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13827    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13828   "ror{b}\t%0"
13829   [(set_attr "type" "rotate")
13830    (set (attr "length")
13831      (if_then_else (match_operand 0 "register_operand" "")
13832         (const_string "2")
13833         (const_string "*")))])
13834
13835 (define_insn "*rotrqi3_1_one_bit_slp"
13836   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13837         (rotatert:QI (match_dup 0)
13838                      (match_operand:QI 1 "const1_operand" "")))
13839    (clobber (reg:CC FLAGS_REG))]
13840   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13841    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13842   "ror{b}\t%0"
13843   [(set_attr "type" "rotate1")
13844    (set (attr "length")
13845      (if_then_else (match_operand 0 "register_operand" "")
13846         (const_string "2")
13847         (const_string "*")))])
13848
13849 (define_insn "*rotrqi3_1"
13850   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13851         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13852                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13853    (clobber (reg:CC FLAGS_REG))]
13854   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13855   "@
13856    ror{b}\t{%2, %0|%0, %2}
13857    ror{b}\t{%b2, %0|%0, %b2}"
13858   [(set_attr "type" "rotate")
13859    (set_attr "mode" "QI")])
13860
13861 (define_insn "*rotrqi3_1_slp"
13862   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13863         (rotatert:QI (match_dup 0)
13864                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13865    (clobber (reg:CC FLAGS_REG))]
13866   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13867    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13868   "@
13869    ror{b}\t{%1, %0|%0, %1}
13870    ror{b}\t{%b1, %0|%0, %b1}"
13871   [(set_attr "type" "rotate1")
13872    (set_attr "mode" "QI")])
13873 \f
13874 ;; Bit set / bit test instructions
13875
13876 (define_expand "extv"
13877   [(set (match_operand:SI 0 "register_operand" "")
13878         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13879                          (match_operand:SI 2 "const8_operand" "")
13880                          (match_operand:SI 3 "const8_operand" "")))]
13881   ""
13882 {
13883   /* Handle extractions from %ah et al.  */
13884   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13885     FAIL;
13886
13887   /* From mips.md: extract_bit_field doesn't verify that our source
13888      matches the predicate, so check it again here.  */
13889   if (! ext_register_operand (operands[1], VOIDmode))
13890     FAIL;
13891 })
13892
13893 (define_expand "extzv"
13894   [(set (match_operand:SI 0 "register_operand" "")
13895         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13896                          (match_operand:SI 2 "const8_operand" "")
13897                          (match_operand:SI 3 "const8_operand" "")))]
13898   ""
13899 {
13900   /* Handle extractions from %ah et al.  */
13901   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13902     FAIL;
13903
13904   /* From mips.md: extract_bit_field doesn't verify that our source
13905      matches the predicate, so check it again here.  */
13906   if (! ext_register_operand (operands[1], VOIDmode))
13907     FAIL;
13908 })
13909
13910 (define_expand "insv"
13911   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13912                       (match_operand 1 "const8_operand" "")
13913                       (match_operand 2 "const8_operand" ""))
13914         (match_operand 3 "register_operand" ""))]
13915   ""
13916 {
13917   /* Handle insertions to %ah et al.  */
13918   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13919     FAIL;
13920
13921   /* From mips.md: insert_bit_field doesn't verify that our source
13922      matches the predicate, so check it again here.  */
13923   if (! ext_register_operand (operands[0], VOIDmode))
13924     FAIL;
13925
13926   if (TARGET_64BIT)
13927     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13928   else
13929     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13930
13931   DONE;
13932 })
13933
13934 ;; %%% bts, btr, btc, bt.
13935 ;; In general these instructions are *slow* when applied to memory,
13936 ;; since they enforce atomic operation.  When applied to registers,
13937 ;; it depends on the cpu implementation.  They're never faster than
13938 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13939 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13940 ;; within the instruction itself, so operating on bits in the high
13941 ;; 32-bits of a register becomes easier.
13942 ;;
13943 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13944 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13945 ;; negdf respectively, so they can never be disabled entirely.
13946
13947 (define_insn "*btsq"
13948   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13949                          (const_int 1)
13950                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13951         (const_int 1))
13952    (clobber (reg:CC FLAGS_REG))]
13953   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13954   "bts{q}\t{%1, %0|%0, %1}"
13955   [(set_attr "type" "alu1")])
13956
13957 (define_insn "*btrq"
13958   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13959                          (const_int 1)
13960                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13961         (const_int 0))
13962    (clobber (reg:CC FLAGS_REG))]
13963   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13964   "btr{q}\t{%1, %0|%0, %1}"
13965   [(set_attr "type" "alu1")])
13966
13967 (define_insn "*btcq"
13968   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13969                          (const_int 1)
13970                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13971         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13972    (clobber (reg:CC FLAGS_REG))]
13973   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13974   "btc{q}\t{%1, %0|%0, %1}"
13975   [(set_attr "type" "alu1")])
13976
13977 ;; Allow Nocona to avoid these instructions if a register is available.
13978
13979 (define_peephole2
13980   [(match_scratch:DI 2 "r")
13981    (parallel [(set (zero_extract:DI
13982                      (match_operand:DI 0 "register_operand" "")
13983                      (const_int 1)
13984                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13985                    (const_int 1))
13986               (clobber (reg:CC FLAGS_REG))])]
13987   "TARGET_64BIT && !TARGET_USE_BT"
13988   [(const_int 0)]
13989 {
13990   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13991   rtx op1;
13992
13993   if (HOST_BITS_PER_WIDE_INT >= 64)
13994     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13995   else if (i < HOST_BITS_PER_WIDE_INT)
13996     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13997   else
13998     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13999
14000   op1 = immed_double_const (lo, hi, DImode);
14001   if (i >= 31)
14002     {
14003       emit_move_insn (operands[2], op1);
14004       op1 = operands[2];
14005     }
14006
14007   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14008   DONE;
14009 })
14010
14011 (define_peephole2
14012   [(match_scratch:DI 2 "r")
14013    (parallel [(set (zero_extract:DI
14014                      (match_operand:DI 0 "register_operand" "")
14015                      (const_int 1)
14016                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14017                    (const_int 0))
14018               (clobber (reg:CC FLAGS_REG))])]
14019   "TARGET_64BIT && !TARGET_USE_BT"
14020   [(const_int 0)]
14021 {
14022   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14023   rtx op1;
14024
14025   if (HOST_BITS_PER_WIDE_INT >= 64)
14026     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14027   else if (i < HOST_BITS_PER_WIDE_INT)
14028     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14029   else
14030     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14031
14032   op1 = immed_double_const (~lo, ~hi, DImode);
14033   if (i >= 32)
14034     {
14035       emit_move_insn (operands[2], op1);
14036       op1 = operands[2];
14037     }
14038
14039   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14040   DONE;
14041 })
14042
14043 (define_peephole2
14044   [(match_scratch:DI 2 "r")
14045    (parallel [(set (zero_extract:DI
14046                      (match_operand:DI 0 "register_operand" "")
14047                      (const_int 1)
14048                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14049               (not:DI (zero_extract:DI
14050                         (match_dup 0) (const_int 1) (match_dup 1))))
14051               (clobber (reg:CC FLAGS_REG))])]
14052   "TARGET_64BIT && !TARGET_USE_BT"
14053   [(const_int 0)]
14054 {
14055   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14056   rtx op1;
14057
14058   if (HOST_BITS_PER_WIDE_INT >= 64)
14059     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14060   else if (i < HOST_BITS_PER_WIDE_INT)
14061     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14062   else
14063     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14064
14065   op1 = immed_double_const (lo, hi, DImode);
14066   if (i >= 31)
14067     {
14068       emit_move_insn (operands[2], op1);
14069       op1 = operands[2];
14070     }
14071
14072   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14073   DONE;
14074 })
14075
14076 (define_insn "*btdi_rex64"
14077   [(set (reg:CCC FLAGS_REG)
14078         (compare:CCC
14079           (zero_extract:DI
14080             (match_operand:DI 0 "register_operand" "r")
14081             (const_int 1)
14082             (match_operand:DI 1 "nonmemory_operand" "rN"))
14083           (const_int 0)))]
14084   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14085   "bt{q}\t{%1, %0|%0, %1}"
14086   [(set_attr "type" "alu1")])
14087
14088 (define_insn "*btsi"
14089   [(set (reg:CCC FLAGS_REG)
14090         (compare:CCC
14091           (zero_extract:SI
14092             (match_operand:SI 0 "register_operand" "r")
14093             (const_int 1)
14094             (match_operand:SI 1 "nonmemory_operand" "rN"))
14095           (const_int 0)))]
14096   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14097   "bt{l}\t{%1, %0|%0, %1}"
14098   [(set_attr "type" "alu1")])
14099 \f
14100 ;; Store-flag instructions.
14101
14102 ;; For all sCOND expanders, also expand the compare or test insn that
14103 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14104
14105 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14106 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14107 ;; way, which can later delete the movzx if only QImode is needed.
14108
14109 (define_expand "s<code>"
14110   [(set (match_operand:QI 0 "register_operand" "")
14111         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14112   ""
14113   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14114
14115 (define_expand "s<code>"
14116   [(set (match_operand:QI 0 "register_operand" "")
14117         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14118   "TARGET_80387 || TARGET_SSE"
14119   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14120
14121 (define_insn "*setcc_1"
14122   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14123         (match_operator:QI 1 "ix86_comparison_operator"
14124           [(reg FLAGS_REG) (const_int 0)]))]
14125   ""
14126   "set%C1\t%0"
14127   [(set_attr "type" "setcc")
14128    (set_attr "mode" "QI")])
14129
14130 (define_insn "*setcc_2"
14131   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14132         (match_operator:QI 1 "ix86_comparison_operator"
14133           [(reg FLAGS_REG) (const_int 0)]))]
14134   ""
14135   "set%C1\t%0"
14136   [(set_attr "type" "setcc")
14137    (set_attr "mode" "QI")])
14138
14139 ;; In general it is not safe to assume too much about CCmode registers,
14140 ;; so simplify-rtx stops when it sees a second one.  Under certain
14141 ;; conditions this is safe on x86, so help combine not create
14142 ;;
14143 ;;      seta    %al
14144 ;;      testb   %al, %al
14145 ;;      sete    %al
14146
14147 (define_split
14148   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14149         (ne:QI (match_operator 1 "ix86_comparison_operator"
14150                  [(reg FLAGS_REG) (const_int 0)])
14151             (const_int 0)))]
14152   ""
14153   [(set (match_dup 0) (match_dup 1))]
14154 {
14155   PUT_MODE (operands[1], QImode);
14156 })
14157
14158 (define_split
14159   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14160         (ne:QI (match_operator 1 "ix86_comparison_operator"
14161                  [(reg FLAGS_REG) (const_int 0)])
14162             (const_int 0)))]
14163   ""
14164   [(set (match_dup 0) (match_dup 1))]
14165 {
14166   PUT_MODE (operands[1], QImode);
14167 })
14168
14169 (define_split
14170   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14171         (eq:QI (match_operator 1 "ix86_comparison_operator"
14172                  [(reg FLAGS_REG) (const_int 0)])
14173             (const_int 0)))]
14174   ""
14175   [(set (match_dup 0) (match_dup 1))]
14176 {
14177   rtx new_op1 = copy_rtx (operands[1]);
14178   operands[1] = new_op1;
14179   PUT_MODE (new_op1, QImode);
14180   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14181                                              GET_MODE (XEXP (new_op1, 0))));
14182
14183   /* Make sure that (a) the CCmode we have for the flags is strong
14184      enough for the reversed compare or (b) we have a valid FP compare.  */
14185   if (! ix86_comparison_operator (new_op1, VOIDmode))
14186     FAIL;
14187 })
14188
14189 (define_split
14190   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14191         (eq:QI (match_operator 1 "ix86_comparison_operator"
14192                  [(reg FLAGS_REG) (const_int 0)])
14193             (const_int 0)))]
14194   ""
14195   [(set (match_dup 0) (match_dup 1))]
14196 {
14197   rtx new_op1 = copy_rtx (operands[1]);
14198   operands[1] = new_op1;
14199   PUT_MODE (new_op1, QImode);
14200   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14201                                              GET_MODE (XEXP (new_op1, 0))));
14202
14203   /* Make sure that (a) the CCmode we have for the flags is strong
14204      enough for the reversed compare or (b) we have a valid FP compare.  */
14205   if (! ix86_comparison_operator (new_op1, VOIDmode))
14206     FAIL;
14207 })
14208
14209 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14210 ;; subsequent logical operations are used to imitate conditional moves.
14211 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14212 ;; it directly.
14213
14214 (define_insn "*avx_setcc<mode>"
14215   [(set (match_operand:MODEF 0 "register_operand" "=x")
14216         (match_operator:MODEF 1 "avx_comparison_float_operator"
14217           [(match_operand:MODEF 2 "register_operand" "x")
14218            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14219   "TARGET_AVX"
14220   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14221   [(set_attr "type" "ssecmp")
14222    (set_attr "prefix" "vex")
14223    (set_attr "mode" "<MODE>")])
14224
14225 (define_insn "*sse_setcc<mode>"
14226   [(set (match_operand:MODEF 0 "register_operand" "=x")
14227         (match_operator:MODEF 1 "sse_comparison_operator"
14228           [(match_operand:MODEF 2 "register_operand" "0")
14229            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14230   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14231   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14232   [(set_attr "type" "ssecmp")
14233    (set_attr "mode" "<MODE>")])
14234
14235 (define_insn "*sse5_setcc<mode>"
14236   [(set (match_operand:MODEF 0 "register_operand" "=x")
14237         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14238           [(match_operand:MODEF 2 "register_operand" "x")
14239            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14240   "TARGET_SSE5"
14241   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14242   [(set_attr "type" "sse4arg")
14243    (set_attr "mode" "<MODE>")])
14244
14245 \f
14246 ;; Basic conditional jump instructions.
14247 ;; We ignore the overflow flag for signed branch instructions.
14248
14249 ;; For all bCOND expanders, also expand the compare or test insn that
14250 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14251
14252 (define_expand "b<code>"
14253   [(set (pc)
14254         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14255                                    (const_int 0))
14256                       (label_ref (match_operand 0 ""))
14257                       (pc)))]
14258   ""
14259   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14260
14261 (define_expand "b<code>"
14262   [(set (pc)
14263         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14264                                   (const_int 0))
14265                       (label_ref (match_operand 0 ""))
14266                       (pc)))]
14267   "TARGET_80387 || TARGET_SSE_MATH"
14268   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14269
14270 (define_insn "*jcc_1"
14271   [(set (pc)
14272         (if_then_else (match_operator 1 "ix86_comparison_operator"
14273                                       [(reg FLAGS_REG) (const_int 0)])
14274                       (label_ref (match_operand 0 "" ""))
14275                       (pc)))]
14276   ""
14277   "%+j%C1\t%l0"
14278   [(set_attr "type" "ibr")
14279    (set_attr "modrm" "0")
14280    (set (attr "length")
14281            (if_then_else (and (ge (minus (match_dup 0) (pc))
14282                                   (const_int -126))
14283                               (lt (minus (match_dup 0) (pc))
14284                                   (const_int 128)))
14285              (const_int 2)
14286              (const_int 6)))])
14287
14288 (define_insn "*jcc_2"
14289   [(set (pc)
14290         (if_then_else (match_operator 1 "ix86_comparison_operator"
14291                                       [(reg FLAGS_REG) (const_int 0)])
14292                       (pc)
14293                       (label_ref (match_operand 0 "" ""))))]
14294   ""
14295   "%+j%c1\t%l0"
14296   [(set_attr "type" "ibr")
14297    (set_attr "modrm" "0")
14298    (set (attr "length")
14299            (if_then_else (and (ge (minus (match_dup 0) (pc))
14300                                   (const_int -126))
14301                               (lt (minus (match_dup 0) (pc))
14302                                   (const_int 128)))
14303              (const_int 2)
14304              (const_int 6)))])
14305
14306 ;; In general it is not safe to assume too much about CCmode registers,
14307 ;; so simplify-rtx stops when it sees a second one.  Under certain
14308 ;; conditions this is safe on x86, so help combine not create
14309 ;;
14310 ;;      seta    %al
14311 ;;      testb   %al, %al
14312 ;;      je      Lfoo
14313
14314 (define_split
14315   [(set (pc)
14316         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14317                                       [(reg FLAGS_REG) (const_int 0)])
14318                           (const_int 0))
14319                       (label_ref (match_operand 1 "" ""))
14320                       (pc)))]
14321   ""
14322   [(set (pc)
14323         (if_then_else (match_dup 0)
14324                       (label_ref (match_dup 1))
14325                       (pc)))]
14326 {
14327   PUT_MODE (operands[0], VOIDmode);
14328 })
14329
14330 (define_split
14331   [(set (pc)
14332         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14333                                       [(reg FLAGS_REG) (const_int 0)])
14334                           (const_int 0))
14335                       (label_ref (match_operand 1 "" ""))
14336                       (pc)))]
14337   ""
14338   [(set (pc)
14339         (if_then_else (match_dup 0)
14340                       (label_ref (match_dup 1))
14341                       (pc)))]
14342 {
14343   rtx new_op0 = copy_rtx (operands[0]);
14344   operands[0] = new_op0;
14345   PUT_MODE (new_op0, VOIDmode);
14346   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14347                                              GET_MODE (XEXP (new_op0, 0))));
14348
14349   /* Make sure that (a) the CCmode we have for the flags is strong
14350      enough for the reversed compare or (b) we have a valid FP compare.  */
14351   if (! ix86_comparison_operator (new_op0, VOIDmode))
14352     FAIL;
14353 })
14354
14355 ;; zero_extend in SImode is correct, since this is what combine pass
14356 ;; generates from shift insn with QImode operand.  Actually, the mode of
14357 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14358 ;; appropriate modulo of the bit offset value.
14359
14360 (define_insn_and_split "*jcc_btdi_rex64"
14361   [(set (pc)
14362         (if_then_else (match_operator 0 "bt_comparison_operator"
14363                         [(zero_extract:DI
14364                            (match_operand:DI 1 "register_operand" "r")
14365                            (const_int 1)
14366                            (zero_extend:SI
14367                              (match_operand:QI 2 "register_operand" "r")))
14368                          (const_int 0)])
14369                       (label_ref (match_operand 3 "" ""))
14370                       (pc)))
14371    (clobber (reg:CC FLAGS_REG))]
14372   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14373   "#"
14374   "&& 1"
14375   [(set (reg:CCC FLAGS_REG)
14376         (compare:CCC
14377           (zero_extract:DI
14378             (match_dup 1)
14379             (const_int 1)
14380             (match_dup 2))
14381           (const_int 0)))
14382    (set (pc)
14383         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14384                       (label_ref (match_dup 3))
14385                       (pc)))]
14386 {
14387   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14388
14389   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14390 })
14391
14392 ;; avoid useless masking of bit offset operand
14393 (define_insn_and_split "*jcc_btdi_mask_rex64"
14394   [(set (pc)
14395         (if_then_else (match_operator 0 "bt_comparison_operator"
14396                         [(zero_extract:DI
14397                            (match_operand:DI 1 "register_operand" "r")
14398                            (const_int 1)
14399                            (and:SI
14400                              (match_operand:SI 2 "register_operand" "r")
14401                              (match_operand:SI 3 "const_int_operand" "n")))])
14402                       (label_ref (match_operand 4 "" ""))
14403                       (pc)))
14404    (clobber (reg:CC FLAGS_REG))]
14405   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14406    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14407   "#"
14408   "&& 1"
14409   [(set (reg:CCC FLAGS_REG)
14410         (compare:CCC
14411           (zero_extract:DI
14412             (match_dup 1)
14413             (const_int 1)
14414             (match_dup 2))
14415           (const_int 0)))
14416    (set (pc)
14417         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14418                       (label_ref (match_dup 4))
14419                       (pc)))]
14420 {
14421   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14422
14423   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14424 })
14425
14426 (define_insn_and_split "*jcc_btsi"
14427   [(set (pc)
14428         (if_then_else (match_operator 0 "bt_comparison_operator"
14429                         [(zero_extract:SI
14430                            (match_operand:SI 1 "register_operand" "r")
14431                            (const_int 1)
14432                            (zero_extend:SI
14433                              (match_operand:QI 2 "register_operand" "r")))
14434                          (const_int 0)])
14435                       (label_ref (match_operand 3 "" ""))
14436                       (pc)))
14437    (clobber (reg:CC FLAGS_REG))]
14438   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14439   "#"
14440   "&& 1"
14441   [(set (reg:CCC FLAGS_REG)
14442         (compare:CCC
14443           (zero_extract:SI
14444             (match_dup 1)
14445             (const_int 1)
14446             (match_dup 2))
14447           (const_int 0)))
14448    (set (pc)
14449         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14450                       (label_ref (match_dup 3))
14451                       (pc)))]
14452 {
14453   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14454
14455   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14456 })
14457
14458 ;; avoid useless masking of bit offset operand
14459 (define_insn_and_split "*jcc_btsi_mask"
14460   [(set (pc)
14461         (if_then_else (match_operator 0 "bt_comparison_operator"
14462                         [(zero_extract:SI
14463                            (match_operand:SI 1 "register_operand" "r")
14464                            (const_int 1)
14465                            (and:SI
14466                              (match_operand:SI 2 "register_operand" "r")
14467                              (match_operand:SI 3 "const_int_operand" "n")))])
14468                       (label_ref (match_operand 4 "" ""))
14469                       (pc)))
14470    (clobber (reg:CC FLAGS_REG))]
14471   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14472    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14473   "#"
14474   "&& 1"
14475   [(set (reg:CCC FLAGS_REG)
14476         (compare:CCC
14477           (zero_extract:SI
14478             (match_dup 1)
14479             (const_int 1)
14480             (match_dup 2))
14481           (const_int 0)))
14482    (set (pc)
14483         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14484                       (label_ref (match_dup 4))
14485                       (pc)))]
14486   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14487
14488 (define_insn_and_split "*jcc_btsi_1"
14489   [(set (pc)
14490         (if_then_else (match_operator 0 "bt_comparison_operator"
14491                         [(and:SI
14492                            (lshiftrt:SI
14493                              (match_operand:SI 1 "register_operand" "r")
14494                              (match_operand:QI 2 "register_operand" "r"))
14495                            (const_int 1))
14496                          (const_int 0)])
14497                       (label_ref (match_operand 3 "" ""))
14498                       (pc)))
14499    (clobber (reg:CC FLAGS_REG))]
14500   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14501   "#"
14502   "&& 1"
14503   [(set (reg:CCC FLAGS_REG)
14504         (compare:CCC
14505           (zero_extract:SI
14506             (match_dup 1)
14507             (const_int 1)
14508             (match_dup 2))
14509           (const_int 0)))
14510    (set (pc)
14511         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14512                       (label_ref (match_dup 3))
14513                       (pc)))]
14514 {
14515   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14516
14517   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14518 })
14519
14520 ;; avoid useless masking of bit offset operand
14521 (define_insn_and_split "*jcc_btsi_mask_1"
14522   [(set (pc)
14523         (if_then_else
14524           (match_operator 0 "bt_comparison_operator"
14525             [(and:SI
14526                (lshiftrt:SI
14527                  (match_operand:SI 1 "register_operand" "r")
14528                  (subreg:QI
14529                    (and:SI
14530                      (match_operand:SI 2 "register_operand" "r")
14531                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14532                (const_int 1))
14533              (const_int 0)])
14534           (label_ref (match_operand 4 "" ""))
14535           (pc)))
14536    (clobber (reg:CC FLAGS_REG))]
14537   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14538    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14539   "#"
14540   "&& 1"
14541   [(set (reg:CCC FLAGS_REG)
14542         (compare:CCC
14543           (zero_extract:SI
14544             (match_dup 1)
14545             (const_int 1)
14546             (match_dup 2))
14547           (const_int 0)))
14548    (set (pc)
14549         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14550                       (label_ref (match_dup 4))
14551                       (pc)))]
14552   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14553
14554 ;; Define combination compare-and-branch fp compare instructions to use
14555 ;; during early optimization.  Splitting the operation apart early makes
14556 ;; for bad code when we want to reverse the operation.
14557
14558 (define_insn "*fp_jcc_1_mixed"
14559   [(set (pc)
14560         (if_then_else (match_operator 0 "comparison_operator"
14561                         [(match_operand 1 "register_operand" "f,x")
14562                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14563           (label_ref (match_operand 3 "" ""))
14564           (pc)))
14565    (clobber (reg:CCFP FPSR_REG))
14566    (clobber (reg:CCFP FLAGS_REG))]
14567   "TARGET_MIX_SSE_I387
14568    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14569    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14570    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14571   "#")
14572
14573 (define_insn "*fp_jcc_1_sse"
14574   [(set (pc)
14575         (if_then_else (match_operator 0 "comparison_operator"
14576                         [(match_operand 1 "register_operand" "x")
14577                          (match_operand 2 "nonimmediate_operand" "xm")])
14578           (label_ref (match_operand 3 "" ""))
14579           (pc)))
14580    (clobber (reg:CCFP FPSR_REG))
14581    (clobber (reg:CCFP FLAGS_REG))]
14582   "TARGET_SSE_MATH
14583    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14584    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14585    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14586   "#")
14587
14588 (define_insn "*fp_jcc_1_387"
14589   [(set (pc)
14590         (if_then_else (match_operator 0 "comparison_operator"
14591                         [(match_operand 1 "register_operand" "f")
14592                          (match_operand 2 "register_operand" "f")])
14593           (label_ref (match_operand 3 "" ""))
14594           (pc)))
14595    (clobber (reg:CCFP FPSR_REG))
14596    (clobber (reg:CCFP FLAGS_REG))]
14597   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14598    && TARGET_CMOVE
14599    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14600    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14601   "#")
14602
14603 (define_insn "*fp_jcc_2_mixed"
14604   [(set (pc)
14605         (if_then_else (match_operator 0 "comparison_operator"
14606                         [(match_operand 1 "register_operand" "f,x")
14607                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14608           (pc)
14609           (label_ref (match_operand 3 "" ""))))
14610    (clobber (reg:CCFP FPSR_REG))
14611    (clobber (reg:CCFP FLAGS_REG))]
14612   "TARGET_MIX_SSE_I387
14613    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14614    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14615    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14616   "#")
14617
14618 (define_insn "*fp_jcc_2_sse"
14619   [(set (pc)
14620         (if_then_else (match_operator 0 "comparison_operator"
14621                         [(match_operand 1 "register_operand" "x")
14622                          (match_operand 2 "nonimmediate_operand" "xm")])
14623           (pc)
14624           (label_ref (match_operand 3 "" ""))))
14625    (clobber (reg:CCFP FPSR_REG))
14626    (clobber (reg:CCFP FLAGS_REG))]
14627   "TARGET_SSE_MATH
14628    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14629    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14630    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14631   "#")
14632
14633 (define_insn "*fp_jcc_2_387"
14634   [(set (pc)
14635         (if_then_else (match_operator 0 "comparison_operator"
14636                         [(match_operand 1 "register_operand" "f")
14637                          (match_operand 2 "register_operand" "f")])
14638           (pc)
14639           (label_ref (match_operand 3 "" ""))))
14640    (clobber (reg:CCFP FPSR_REG))
14641    (clobber (reg:CCFP FLAGS_REG))]
14642   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14643    && TARGET_CMOVE
14644    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14645    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14646   "#")
14647
14648 (define_insn "*fp_jcc_3_387"
14649   [(set (pc)
14650         (if_then_else (match_operator 0 "comparison_operator"
14651                         [(match_operand 1 "register_operand" "f")
14652                          (match_operand 2 "nonimmediate_operand" "fm")])
14653           (label_ref (match_operand 3 "" ""))
14654           (pc)))
14655    (clobber (reg:CCFP FPSR_REG))
14656    (clobber (reg:CCFP FLAGS_REG))
14657    (clobber (match_scratch:HI 4 "=a"))]
14658   "TARGET_80387
14659    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14660    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14661    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14662    && SELECT_CC_MODE (GET_CODE (operands[0]),
14663                       operands[1], operands[2]) == CCFPmode
14664    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14665   "#")
14666
14667 (define_insn "*fp_jcc_4_387"
14668   [(set (pc)
14669         (if_then_else (match_operator 0 "comparison_operator"
14670                         [(match_operand 1 "register_operand" "f")
14671                          (match_operand 2 "nonimmediate_operand" "fm")])
14672           (pc)
14673           (label_ref (match_operand 3 "" ""))))
14674    (clobber (reg:CCFP FPSR_REG))
14675    (clobber (reg:CCFP FLAGS_REG))
14676    (clobber (match_scratch:HI 4 "=a"))]
14677   "TARGET_80387
14678    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14679    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14680    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14681    && SELECT_CC_MODE (GET_CODE (operands[0]),
14682                       operands[1], operands[2]) == CCFPmode
14683    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14684   "#")
14685
14686 (define_insn "*fp_jcc_5_387"
14687   [(set (pc)
14688         (if_then_else (match_operator 0 "comparison_operator"
14689                         [(match_operand 1 "register_operand" "f")
14690                          (match_operand 2 "register_operand" "f")])
14691           (label_ref (match_operand 3 "" ""))
14692           (pc)))
14693    (clobber (reg:CCFP FPSR_REG))
14694    (clobber (reg:CCFP FLAGS_REG))
14695    (clobber (match_scratch:HI 4 "=a"))]
14696   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14697    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14698    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14699   "#")
14700
14701 (define_insn "*fp_jcc_6_387"
14702   [(set (pc)
14703         (if_then_else (match_operator 0 "comparison_operator"
14704                         [(match_operand 1 "register_operand" "f")
14705                          (match_operand 2 "register_operand" "f")])
14706           (pc)
14707           (label_ref (match_operand 3 "" ""))))
14708    (clobber (reg:CCFP FPSR_REG))
14709    (clobber (reg:CCFP FLAGS_REG))
14710    (clobber (match_scratch:HI 4 "=a"))]
14711   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14712    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14713    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14714   "#")
14715
14716 (define_insn "*fp_jcc_7_387"
14717   [(set (pc)
14718         (if_then_else (match_operator 0 "comparison_operator"
14719                         [(match_operand 1 "register_operand" "f")
14720                          (match_operand 2 "const0_operand" "")])
14721           (label_ref (match_operand 3 "" ""))
14722           (pc)))
14723    (clobber (reg:CCFP FPSR_REG))
14724    (clobber (reg:CCFP FLAGS_REG))
14725    (clobber (match_scratch:HI 4 "=a"))]
14726   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14727    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14728    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14729    && SELECT_CC_MODE (GET_CODE (operands[0]),
14730                       operands[1], operands[2]) == CCFPmode
14731    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14732   "#")
14733
14734 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14735 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14736 ;; with a precedence over other operators and is always put in the first
14737 ;; place. Swap condition and operands to match ficom instruction.
14738
14739 (define_insn "*fp_jcc_8<mode>_387"
14740   [(set (pc)
14741         (if_then_else (match_operator 0 "comparison_operator"
14742                         [(match_operator 1 "float_operator"
14743                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14744                            (match_operand 3 "register_operand" "f,f")])
14745           (label_ref (match_operand 4 "" ""))
14746           (pc)))
14747    (clobber (reg:CCFP FPSR_REG))
14748    (clobber (reg:CCFP FLAGS_REG))
14749    (clobber (match_scratch:HI 5 "=a,a"))]
14750   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14751    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14752    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14753    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14754    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14755    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14756   "#")
14757
14758 (define_split
14759   [(set (pc)
14760         (if_then_else (match_operator 0 "comparison_operator"
14761                         [(match_operand 1 "register_operand" "")
14762                          (match_operand 2 "nonimmediate_operand" "")])
14763           (match_operand 3 "" "")
14764           (match_operand 4 "" "")))
14765    (clobber (reg:CCFP FPSR_REG))
14766    (clobber (reg:CCFP FLAGS_REG))]
14767   "reload_completed"
14768   [(const_int 0)]
14769 {
14770   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14771                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14772   DONE;
14773 })
14774
14775 (define_split
14776   [(set (pc)
14777         (if_then_else (match_operator 0 "comparison_operator"
14778                         [(match_operand 1 "register_operand" "")
14779                          (match_operand 2 "general_operand" "")])
14780           (match_operand 3 "" "")
14781           (match_operand 4 "" "")))
14782    (clobber (reg:CCFP FPSR_REG))
14783    (clobber (reg:CCFP FLAGS_REG))
14784    (clobber (match_scratch:HI 5 "=a"))]
14785   "reload_completed"
14786   [(const_int 0)]
14787 {
14788   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14789                         operands[3], operands[4], operands[5], NULL_RTX);
14790   DONE;
14791 })
14792
14793 (define_split
14794   [(set (pc)
14795         (if_then_else (match_operator 0 "comparison_operator"
14796                         [(match_operator 1 "float_operator"
14797                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14798                            (match_operand 3 "register_operand" "")])
14799           (match_operand 4 "" "")
14800           (match_operand 5 "" "")))
14801    (clobber (reg:CCFP FPSR_REG))
14802    (clobber (reg:CCFP FLAGS_REG))
14803    (clobber (match_scratch:HI 6 "=a"))]
14804   "reload_completed"
14805   [(const_int 0)]
14806 {
14807   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14808   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14809                         operands[3], operands[7],
14810                         operands[4], operands[5], operands[6], NULL_RTX);
14811   DONE;
14812 })
14813
14814 ;; %%% Kill this when reload knows how to do it.
14815 (define_split
14816   [(set (pc)
14817         (if_then_else (match_operator 0 "comparison_operator"
14818                         [(match_operator 1 "float_operator"
14819                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14820                            (match_operand 3 "register_operand" "")])
14821           (match_operand 4 "" "")
14822           (match_operand 5 "" "")))
14823    (clobber (reg:CCFP FPSR_REG))
14824    (clobber (reg:CCFP FLAGS_REG))
14825    (clobber (match_scratch:HI 6 "=a"))]
14826   "reload_completed"
14827   [(const_int 0)]
14828 {
14829   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14830   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14831   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14832                         operands[3], operands[7],
14833                         operands[4], operands[5], operands[6], operands[2]);
14834   DONE;
14835 })
14836 \f
14837 ;; Unconditional and other jump instructions
14838
14839 (define_insn "jump"
14840   [(set (pc)
14841         (label_ref (match_operand 0 "" "")))]
14842   ""
14843   "jmp\t%l0"
14844   [(set_attr "type" "ibr")
14845    (set (attr "length")
14846            (if_then_else (and (ge (minus (match_dup 0) (pc))
14847                                   (const_int -126))
14848                               (lt (minus (match_dup 0) (pc))
14849                                   (const_int 128)))
14850              (const_int 2)
14851              (const_int 5)))
14852    (set_attr "modrm" "0")])
14853
14854 (define_expand "indirect_jump"
14855   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14856   ""
14857   "")
14858
14859 (define_insn "*indirect_jump"
14860   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14861   ""
14862   "jmp\t%A0"
14863   [(set_attr "type" "ibr")
14864    (set_attr "length_immediate" "0")])
14865
14866 (define_expand "tablejump"
14867   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14868               (use (label_ref (match_operand 1 "" "")))])]
14869   ""
14870 {
14871   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14872      relative.  Convert the relative address to an absolute address.  */
14873   if (flag_pic)
14874     {
14875       rtx op0, op1;
14876       enum rtx_code code;
14877
14878       /* We can't use @GOTOFF for text labels on VxWorks;
14879          see gotoff_operand.  */
14880       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14881         {
14882           code = PLUS;
14883           op0 = operands[0];
14884           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14885         }
14886       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14887         {
14888           code = PLUS;
14889           op0 = operands[0];
14890           op1 = pic_offset_table_rtx;
14891         }
14892       else
14893         {
14894           code = MINUS;
14895           op0 = pic_offset_table_rtx;
14896           op1 = operands[0];
14897         }
14898
14899       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14900                                          OPTAB_DIRECT);
14901     }
14902 })
14903
14904 (define_insn "*tablejump_1"
14905   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14906    (use (label_ref (match_operand 1 "" "")))]
14907   ""
14908   "jmp\t%A0"
14909   [(set_attr "type" "ibr")
14910    (set_attr "length_immediate" "0")])
14911 \f
14912 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14913
14914 (define_peephole2
14915   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14916    (set (match_operand:QI 1 "register_operand" "")
14917         (match_operator:QI 2 "ix86_comparison_operator"
14918           [(reg FLAGS_REG) (const_int 0)]))
14919    (set (match_operand 3 "q_regs_operand" "")
14920         (zero_extend (match_dup 1)))]
14921   "(peep2_reg_dead_p (3, operands[1])
14922     || operands_match_p (operands[1], operands[3]))
14923    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14924   [(set (match_dup 4) (match_dup 0))
14925    (set (strict_low_part (match_dup 5))
14926         (match_dup 2))]
14927 {
14928   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14929   operands[5] = gen_lowpart (QImode, operands[3]);
14930   ix86_expand_clear (operands[3]);
14931 })
14932
14933 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14934
14935 (define_peephole2
14936   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14937    (set (match_operand:QI 1 "register_operand" "")
14938         (match_operator:QI 2 "ix86_comparison_operator"
14939           [(reg FLAGS_REG) (const_int 0)]))
14940    (parallel [(set (match_operand 3 "q_regs_operand" "")
14941                    (zero_extend (match_dup 1)))
14942               (clobber (reg:CC FLAGS_REG))])]
14943   "(peep2_reg_dead_p (3, operands[1])
14944     || operands_match_p (operands[1], operands[3]))
14945    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14946   [(set (match_dup 4) (match_dup 0))
14947    (set (strict_low_part (match_dup 5))
14948         (match_dup 2))]
14949 {
14950   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14951   operands[5] = gen_lowpart (QImode, operands[3]);
14952   ix86_expand_clear (operands[3]);
14953 })
14954 \f
14955 ;; Call instructions.
14956
14957 ;; The predicates normally associated with named expanders are not properly
14958 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14959 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14960
14961 ;; P6 processors will jump to the address after the decrement when %esp
14962 ;; is used as a call operand, so they will execute return address as a code.
14963 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
14964
14965 ;; Call subroutine returning no value.
14966
14967 (define_expand "call_pop"
14968   [(parallel [(call (match_operand:QI 0 "" "")
14969                     (match_operand:SI 1 "" ""))
14970               (set (reg:SI SP_REG)
14971                    (plus:SI (reg:SI SP_REG)
14972                             (match_operand:SI 3 "" "")))])]
14973   "!TARGET_64BIT"
14974 {
14975   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14976   DONE;
14977 })
14978
14979 (define_insn "*call_pop_0"
14980   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14981          (match_operand:SI 1 "" ""))
14982    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14983                             (match_operand:SI 2 "immediate_operand" "")))]
14984   "!TARGET_64BIT"
14985 {
14986   if (SIBLING_CALL_P (insn))
14987     return "jmp\t%P0";
14988   else
14989     return "call\t%P0";
14990 }
14991   [(set_attr "type" "call")])
14992
14993 (define_insn "*call_pop_1"
14994   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14995          (match_operand:SI 1 "" ""))
14996    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14997                             (match_operand:SI 2 "immediate_operand" "i")))]
14998   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14999 {
15000   if (constant_call_address_operand (operands[0], Pmode))
15001     return "call\t%P0";
15002   return "call\t%A0";
15003 }
15004   [(set_attr "type" "call")])
15005
15006 (define_insn "*sibcall_pop_1"
15007   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
15008          (match_operand:SI 1 "" ""))
15009    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15010                             (match_operand:SI 2 "immediate_operand" "i,i")))]
15011   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
15012   "@
15013    jmp\t%P0
15014    jmp\t%A0"
15015   [(set_attr "type" "call")])
15016
15017 (define_expand "call"
15018   [(call (match_operand:QI 0 "" "")
15019          (match_operand 1 "" ""))
15020    (use (match_operand 2 "" ""))]
15021   ""
15022 {
15023   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15024   DONE;
15025 })
15026
15027 (define_expand "sibcall"
15028   [(call (match_operand:QI 0 "" "")
15029          (match_operand 1 "" ""))
15030    (use (match_operand 2 "" ""))]
15031   ""
15032 {
15033   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15034   DONE;
15035 })
15036
15037 (define_insn "*call_0"
15038   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15039          (match_operand 1 "" ""))]
15040   ""
15041 {
15042   if (SIBLING_CALL_P (insn))
15043     return "jmp\t%P0";
15044   else
15045     return "call\t%P0";
15046 }
15047   [(set_attr "type" "call")])
15048
15049 (define_insn "*call_1"
15050   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
15051          (match_operand 1 "" ""))]
15052   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
15053 {
15054   if (constant_call_address_operand (operands[0], Pmode))
15055     return "call\t%P0";
15056   return "call\t%A0";
15057 }
15058   [(set_attr "type" "call")])
15059
15060 (define_insn "*sibcall_1"
15061   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
15062          (match_operand 1 "" ""))]
15063   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
15064   "@
15065    jmp\t%P0
15066    jmp\t%A0"
15067   [(set_attr "type" "call")])
15068
15069 (define_insn "*call_1_rex64"
15070   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15071          (match_operand 1 "" ""))]
15072   "TARGET_64BIT && !SIBLING_CALL_P (insn)
15073    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15074 {
15075   if (constant_call_address_operand (operands[0], Pmode))
15076     return "call\t%P0";
15077   return "call\t%A0";
15078 }
15079   [(set_attr "type" "call")])
15080
15081 (define_insn "*call_1_rex64_ms_sysv"
15082   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15083          (match_operand 1 "" ""))
15084    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15085    (clobber (reg:TI XMM6_REG))
15086    (clobber (reg:TI XMM7_REG))
15087    (clobber (reg:TI XMM8_REG))
15088    (clobber (reg:TI XMM9_REG))
15089    (clobber (reg:TI XMM10_REG))
15090    (clobber (reg:TI XMM11_REG))
15091    (clobber (reg:TI XMM12_REG))
15092    (clobber (reg:TI XMM13_REG))
15093    (clobber (reg:TI XMM14_REG))
15094    (clobber (reg:TI XMM15_REG))
15095    (clobber (reg:DI SI_REG))
15096    (clobber (reg:DI DI_REG))]
15097   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
15098 {
15099   if (constant_call_address_operand (operands[0], Pmode))
15100     return "call\t%P0";
15101   return "call\t%A0";
15102 }
15103   [(set_attr "type" "call")])
15104
15105 (define_insn "*call_1_rex64_large"
15106   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15107          (match_operand 1 "" ""))]
15108   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
15109   "call\t%A0"
15110   [(set_attr "type" "call")])
15111
15112 (define_insn "*sibcall_1_rex64"
15113   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
15114          (match_operand 1 "" ""))]
15115   "TARGET_64BIT && SIBLING_CALL_P (insn)"
15116   "@
15117    jmp\t%P0
15118    jmp\t%A0"
15119   [(set_attr "type" "call")])
15120
15121 ;; Call subroutine, returning value in operand 0
15122 (define_expand "call_value_pop"
15123   [(parallel [(set (match_operand 0 "" "")
15124                    (call (match_operand:QI 1 "" "")
15125                          (match_operand:SI 2 "" "")))
15126               (set (reg:SI SP_REG)
15127                    (plus:SI (reg:SI SP_REG)
15128                             (match_operand:SI 4 "" "")))])]
15129   "!TARGET_64BIT"
15130 {
15131   ix86_expand_call (operands[0], operands[1], operands[2],
15132                     operands[3], operands[4], 0);
15133   DONE;
15134 })
15135
15136 (define_expand "call_value"
15137   [(set (match_operand 0 "" "")
15138         (call (match_operand:QI 1 "" "")
15139               (match_operand:SI 2 "" "")))
15140    (use (match_operand:SI 3 "" ""))]
15141   ;; Operand 2 not used on the i386.
15142   ""
15143 {
15144   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15145   DONE;
15146 })
15147
15148 (define_expand "sibcall_value"
15149   [(set (match_operand 0 "" "")
15150         (call (match_operand:QI 1 "" "")
15151               (match_operand:SI 2 "" "")))
15152    (use (match_operand:SI 3 "" ""))]
15153   ;; Operand 2 not used on the i386.
15154   ""
15155 {
15156   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15157   DONE;
15158 })
15159
15160 ;; Call subroutine returning any type.
15161
15162 (define_expand "untyped_call"
15163   [(parallel [(call (match_operand 0 "" "")
15164                     (const_int 0))
15165               (match_operand 1 "" "")
15166               (match_operand 2 "" "")])]
15167   ""
15168 {
15169   int i;
15170
15171   /* In order to give reg-stack an easier job in validating two
15172      coprocessor registers as containing a possible return value,
15173      simply pretend the untyped call returns a complex long double
15174      value. 
15175
15176      We can't use SSE_REGPARM_MAX here since callee is unprototyped
15177      and should have the default ABI.  */
15178
15179   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15180                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15181                     operands[0], const0_rtx,
15182                     GEN_INT ((TARGET_64BIT
15183                               ? (DEFAULT_ABI == SYSV_ABI
15184                                  ? X86_64_SSE_REGPARM_MAX
15185                                  : X64_SSE_REGPARM_MAX)
15186                               : X86_32_SSE_REGPARM_MAX)
15187                              - 1),
15188                     NULL, 0);
15189
15190   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15191     {
15192       rtx set = XVECEXP (operands[2], 0, i);
15193       emit_move_insn (SET_DEST (set), SET_SRC (set));
15194     }
15195
15196   /* The optimizer does not know that the call sets the function value
15197      registers we stored in the result block.  We avoid problems by
15198      claiming that all hard registers are used and clobbered at this
15199      point.  */
15200   emit_insn (gen_blockage ());
15201
15202   DONE;
15203 })
15204 \f
15205 ;; Prologue and epilogue instructions
15206
15207 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15208 ;; all of memory.  This blocks insns from being moved across this point.
15209
15210 (define_insn "blockage"
15211   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15212   ""
15213   ""
15214   [(set_attr "length" "0")])
15215
15216 ;; Do not schedule instructions accessing memory across this point.
15217
15218 (define_expand "memory_blockage"
15219   [(set (match_dup 0)
15220         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15221   ""
15222 {
15223   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15224   MEM_VOLATILE_P (operands[0]) = 1;
15225 })
15226
15227 (define_insn "*memory_blockage"
15228   [(set (match_operand:BLK 0 "" "")
15229         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15230   ""
15231   ""
15232   [(set_attr "length" "0")])
15233
15234 ;; As USE insns aren't meaningful after reload, this is used instead
15235 ;; to prevent deleting instructions setting registers for PIC code
15236 (define_insn "prologue_use"
15237   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15238   ""
15239   ""
15240   [(set_attr "length" "0")])
15241
15242 ;; Insn emitted into the body of a function to return from a function.
15243 ;; This is only done if the function's epilogue is known to be simple.
15244 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15245
15246 (define_expand "return"
15247   [(return)]
15248   "ix86_can_use_return_insn_p ()"
15249 {
15250   if (crtl->args.pops_args)
15251     {
15252       rtx popc = GEN_INT (crtl->args.pops_args);
15253       emit_jump_insn (gen_return_pop_internal (popc));
15254       DONE;
15255     }
15256 })
15257
15258 (define_insn "return_internal"
15259   [(return)]
15260   "reload_completed"
15261   "ret"
15262   [(set_attr "length" "1")
15263    (set_attr "length_immediate" "0")
15264    (set_attr "modrm" "0")])
15265
15266 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15267 ;; instruction Athlon and K8 have.
15268
15269 (define_insn "return_internal_long"
15270   [(return)
15271    (unspec [(const_int 0)] UNSPEC_REP)]
15272   "reload_completed"
15273   "rep\;ret"
15274   [(set_attr "length" "1")
15275    (set_attr "length_immediate" "0")
15276    (set_attr "prefix_rep" "1")
15277    (set_attr "modrm" "0")])
15278
15279 (define_insn "return_pop_internal"
15280   [(return)
15281    (use (match_operand:SI 0 "const_int_operand" ""))]
15282   "reload_completed"
15283   "ret\t%0"
15284   [(set_attr "length" "3")
15285    (set_attr "length_immediate" "2")
15286    (set_attr "modrm" "0")])
15287
15288 (define_insn "return_indirect_internal"
15289   [(return)
15290    (use (match_operand:SI 0 "register_operand" "r"))]
15291   "reload_completed"
15292   "jmp\t%A0"
15293   [(set_attr "type" "ibr")
15294    (set_attr "length_immediate" "0")])
15295
15296 (define_insn "nop"
15297   [(const_int 0)]
15298   ""
15299   "nop"
15300   [(set_attr "length" "1")
15301    (set_attr "length_immediate" "0")
15302    (set_attr "modrm" "0")])
15303
15304 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15305 ;; branch prediction penalty for the third jump in a 16-byte
15306 ;; block on K8.
15307
15308 (define_insn "align"
15309   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15310   ""
15311 {
15312 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15313   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15314 #else
15315   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15316      The align insn is used to avoid 3 jump instructions in the row to improve
15317      branch prediction and the benefits hardly outweigh the cost of extra 8
15318      nops on the average inserted by full alignment pseudo operation.  */
15319 #endif
15320   return "";
15321 }
15322   [(set_attr "length" "16")])
15323
15324 (define_expand "prologue"
15325   [(const_int 0)]
15326   ""
15327   "ix86_expand_prologue (); DONE;")
15328
15329 (define_insn "set_got"
15330   [(set (match_operand:SI 0 "register_operand" "=r")
15331         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15332    (clobber (reg:CC FLAGS_REG))]
15333   "!TARGET_64BIT"
15334   { return output_set_got (operands[0], NULL_RTX); }
15335   [(set_attr "type" "multi")
15336    (set_attr "length" "12")])
15337
15338 (define_insn "set_got_labelled"
15339   [(set (match_operand:SI 0 "register_operand" "=r")
15340         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15341          UNSPEC_SET_GOT))
15342    (clobber (reg:CC FLAGS_REG))]
15343   "!TARGET_64BIT"
15344   { return output_set_got (operands[0], operands[1]); }
15345   [(set_attr "type" "multi")
15346    (set_attr "length" "12")])
15347
15348 (define_insn "set_got_rex64"
15349   [(set (match_operand:DI 0 "register_operand" "=r")
15350         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15351   "TARGET_64BIT"
15352   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15353   [(set_attr "type" "lea")
15354    (set_attr "length" "6")])
15355
15356 (define_insn "set_rip_rex64"
15357   [(set (match_operand:DI 0 "register_operand" "=r")
15358         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15359   "TARGET_64BIT"
15360   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15361   [(set_attr "type" "lea")
15362    (set_attr "length" "6")])
15363
15364 (define_insn "set_got_offset_rex64"
15365   [(set (match_operand:DI 0 "register_operand" "=r")
15366         (unspec:DI
15367           [(label_ref (match_operand 1 "" ""))]
15368           UNSPEC_SET_GOT_OFFSET))]
15369   "TARGET_64BIT"
15370   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15371   [(set_attr "type" "imov")
15372    (set_attr "length" "11")])
15373
15374 (define_expand "epilogue"
15375   [(const_int 0)]
15376   ""
15377   "ix86_expand_epilogue (1); DONE;")
15378
15379 (define_expand "sibcall_epilogue"
15380   [(const_int 0)]
15381   ""
15382   "ix86_expand_epilogue (0); DONE;")
15383
15384 (define_expand "eh_return"
15385   [(use (match_operand 0 "register_operand" ""))]
15386   ""
15387 {
15388   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15389
15390   /* Tricky bit: we write the address of the handler to which we will
15391      be returning into someone else's stack frame, one word below the
15392      stack address we wish to restore.  */
15393   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15394   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15395   tmp = gen_rtx_MEM (Pmode, tmp);
15396   emit_move_insn (tmp, ra);
15397
15398   if (Pmode == SImode)
15399     emit_jump_insn (gen_eh_return_si (sa));
15400   else
15401     emit_jump_insn (gen_eh_return_di (sa));
15402   emit_barrier ();
15403   DONE;
15404 })
15405
15406 (define_insn_and_split "eh_return_<mode>"
15407   [(set (pc)
15408         (unspec [(match_operand:P 0 "register_operand" "c")]
15409                  UNSPEC_EH_RETURN))]
15410   ""
15411   "#"
15412   "reload_completed"
15413   [(const_int 0)]
15414   "ix86_expand_epilogue (2); DONE;")
15415
15416 (define_insn "leave"
15417   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15418    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15419    (clobber (mem:BLK (scratch)))]
15420   "!TARGET_64BIT"
15421   "leave"
15422   [(set_attr "type" "leave")])
15423
15424 (define_insn "leave_rex64"
15425   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15426    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15427    (clobber (mem:BLK (scratch)))]
15428   "TARGET_64BIT"
15429   "leave"
15430   [(set_attr "type" "leave")])
15431 \f
15432 (define_expand "ffssi2"
15433   [(parallel
15434      [(set (match_operand:SI 0 "register_operand" "")
15435            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15436       (clobber (match_scratch:SI 2 ""))
15437       (clobber (reg:CC FLAGS_REG))])]
15438   ""
15439 {
15440   if (TARGET_CMOVE)
15441     {
15442       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15443       DONE;
15444     }
15445 })
15446
15447 (define_expand "ffs_cmove"
15448   [(set (match_dup 2) (const_int -1))
15449    (parallel [(set (reg:CCZ FLAGS_REG)
15450                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15451                                 (const_int 0)))
15452               (set (match_operand:SI 0 "register_operand" "")
15453                    (ctz:SI (match_dup 1)))])
15454    (set (match_dup 0) (if_then_else:SI
15455                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15456                         (match_dup 2)
15457                         (match_dup 0)))
15458    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15459               (clobber (reg:CC FLAGS_REG))])]
15460   "TARGET_CMOVE"
15461   "operands[2] = gen_reg_rtx (SImode);")
15462
15463 (define_insn_and_split "*ffs_no_cmove"
15464   [(set (match_operand:SI 0 "register_operand" "=r")
15465         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15466    (clobber (match_scratch:SI 2 "=&q"))
15467    (clobber (reg:CC FLAGS_REG))]
15468   "!TARGET_CMOVE"
15469   "#"
15470   "&& reload_completed"
15471   [(parallel [(set (reg:CCZ FLAGS_REG)
15472                    (compare:CCZ (match_dup 1) (const_int 0)))
15473               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15474    (set (strict_low_part (match_dup 3))
15475         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15476    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15477               (clobber (reg:CC FLAGS_REG))])
15478    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15479               (clobber (reg:CC FLAGS_REG))])
15480    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15481               (clobber (reg:CC FLAGS_REG))])]
15482 {
15483   operands[3] = gen_lowpart (QImode, operands[2]);
15484   ix86_expand_clear (operands[2]);
15485 })
15486
15487 (define_insn "*ffssi_1"
15488   [(set (reg:CCZ FLAGS_REG)
15489         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15490                      (const_int 0)))
15491    (set (match_operand:SI 0 "register_operand" "=r")
15492         (ctz:SI (match_dup 1)))]
15493   ""
15494   "bsf{l}\t{%1, %0|%0, %1}"
15495   [(set_attr "prefix_0f" "1")])
15496
15497 (define_expand "ffsdi2"
15498   [(set (match_dup 2) (const_int -1))
15499    (parallel [(set (reg:CCZ FLAGS_REG)
15500                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15501                                 (const_int 0)))
15502               (set (match_operand:DI 0 "register_operand" "")
15503                    (ctz:DI (match_dup 1)))])
15504    (set (match_dup 0) (if_then_else:DI
15505                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15506                         (match_dup 2)
15507                         (match_dup 0)))
15508    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15509               (clobber (reg:CC FLAGS_REG))])]
15510   "TARGET_64BIT"
15511   "operands[2] = gen_reg_rtx (DImode);")
15512
15513 (define_insn "*ffsdi_1"
15514   [(set (reg:CCZ FLAGS_REG)
15515         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15516                      (const_int 0)))
15517    (set (match_operand:DI 0 "register_operand" "=r")
15518         (ctz:DI (match_dup 1)))]
15519   "TARGET_64BIT"
15520   "bsf{q}\t{%1, %0|%0, %1}"
15521   [(set_attr "prefix_0f" "1")])
15522
15523 (define_insn "ctzsi2"
15524   [(set (match_operand:SI 0 "register_operand" "=r")
15525         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15526    (clobber (reg:CC FLAGS_REG))]
15527   ""
15528   "bsf{l}\t{%1, %0|%0, %1}"
15529   [(set_attr "prefix_0f" "1")])
15530
15531 (define_insn "ctzdi2"
15532   [(set (match_operand:DI 0 "register_operand" "=r")
15533         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15534    (clobber (reg:CC FLAGS_REG))]
15535   "TARGET_64BIT"
15536   "bsf{q}\t{%1, %0|%0, %1}"
15537   [(set_attr "prefix_0f" "1")])
15538
15539 (define_expand "clzsi2"
15540   [(parallel
15541      [(set (match_operand:SI 0 "register_operand" "")
15542            (minus:SI (const_int 31)
15543                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15544       (clobber (reg:CC FLAGS_REG))])
15545    (parallel
15546      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15547       (clobber (reg:CC FLAGS_REG))])]
15548   ""
15549 {
15550   if (TARGET_ABM)
15551     {
15552       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15553       DONE;
15554     }
15555 })
15556
15557 (define_insn "clzsi2_abm"
15558   [(set (match_operand:SI 0 "register_operand" "=r")
15559         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15560    (clobber (reg:CC FLAGS_REG))]
15561   "TARGET_ABM"
15562   "lzcnt{l}\t{%1, %0|%0, %1}"
15563   [(set_attr "prefix_rep" "1")
15564    (set_attr "type" "bitmanip")
15565    (set_attr "mode" "SI")])
15566
15567 (define_insn "*bsr"
15568   [(set (match_operand:SI 0 "register_operand" "=r")
15569         (minus:SI (const_int 31)
15570                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15571    (clobber (reg:CC FLAGS_REG))]
15572   ""
15573   "bsr{l}\t{%1, %0|%0, %1}"
15574   [(set_attr "prefix_0f" "1")
15575    (set_attr "mode" "SI")])
15576
15577 (define_insn "popcount<mode>2"
15578   [(set (match_operand:SWI248 0 "register_operand" "=r")
15579         (popcount:SWI248
15580           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15581    (clobber (reg:CC FLAGS_REG))]
15582   "TARGET_POPCNT"
15583 {
15584 #if TARGET_MACHO
15585   return "popcnt\t{%1, %0|%0, %1}";
15586 #else
15587   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15588 #endif
15589 }
15590   [(set_attr "prefix_rep" "1")
15591    (set_attr "type" "bitmanip")
15592    (set_attr "mode" "<MODE>")])
15593
15594 (define_insn "*popcount<mode>2_cmp"
15595   [(set (reg FLAGS_REG)
15596         (compare
15597           (popcount:SWI248
15598             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15599           (const_int 0)))
15600    (set (match_operand:SWI248 0 "register_operand" "=r")
15601         (popcount:SWI248 (match_dup 1)))]
15602   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15603 {
15604 #if TARGET_MACHO
15605   return "popcnt\t{%1, %0|%0, %1}";
15606 #else
15607   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15608 #endif
15609 }
15610   [(set_attr "prefix_rep" "1")
15611    (set_attr "type" "bitmanip")
15612    (set_attr "mode" "<MODE>")])
15613
15614 (define_insn "*popcountsi2_cmp_zext"
15615   [(set (reg FLAGS_REG)
15616         (compare
15617           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15618           (const_int 0)))
15619    (set (match_operand:DI 0 "register_operand" "=r")
15620         (zero_extend:DI(popcount:SI (match_dup 1))))]
15621   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15622 {
15623 #if TARGET_MACHO
15624   return "popcnt\t{%1, %0|%0, %1}";
15625 #else
15626   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15627 #endif
15628 }
15629   [(set_attr "prefix_rep" "1")
15630    (set_attr "type" "bitmanip")
15631    (set_attr "mode" "SI")])
15632
15633 (define_expand "bswapsi2"
15634   [(set (match_operand:SI 0 "register_operand" "")
15635         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15636   ""
15637 {
15638   if (!TARGET_BSWAP)
15639     {
15640       rtx x = operands[0];
15641
15642       emit_move_insn (x, operands[1]);
15643       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15644       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15645       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15646       DONE;
15647     }
15648 })
15649
15650 (define_insn "*bswapsi_1"
15651   [(set (match_operand:SI 0 "register_operand" "=r")
15652         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15653   "TARGET_BSWAP"
15654   "bswap\t%0"
15655   [(set_attr "prefix_0f" "1")
15656    (set_attr "length" "2")])
15657
15658 (define_insn "*bswaphi_lowpart_1"
15659   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15660         (bswap:HI (match_dup 0)))
15661    (clobber (reg:CC FLAGS_REG))]
15662   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15663   "@
15664     xchg{b}\t{%h0, %b0|%b0, %h0}
15665     rol{w}\t{$8, %0|%0, 8}"
15666   [(set_attr "length" "2,4")
15667    (set_attr "mode" "QI,HI")])
15668
15669 (define_insn "bswaphi_lowpart"
15670   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15671         (bswap:HI (match_dup 0)))
15672    (clobber (reg:CC FLAGS_REG))]
15673   ""
15674   "rol{w}\t{$8, %0|%0, 8}"
15675   [(set_attr "length" "4")
15676    (set_attr "mode" "HI")])
15677
15678 (define_insn "bswapdi2"
15679   [(set (match_operand:DI 0 "register_operand" "=r")
15680         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15681   "TARGET_64BIT"
15682   "bswap\t%0"
15683   [(set_attr "prefix_0f" "1")
15684    (set_attr "length" "3")])
15685
15686 (define_expand "clzdi2"
15687   [(parallel
15688      [(set (match_operand:DI 0 "register_operand" "")
15689            (minus:DI (const_int 63)
15690                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15691       (clobber (reg:CC FLAGS_REG))])
15692    (parallel
15693      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15694       (clobber (reg:CC FLAGS_REG))])]
15695   "TARGET_64BIT"
15696 {
15697   if (TARGET_ABM)
15698     {
15699       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15700       DONE;
15701     }
15702 })
15703
15704 (define_insn "clzdi2_abm"
15705   [(set (match_operand:DI 0 "register_operand" "=r")
15706         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15707    (clobber (reg:CC FLAGS_REG))]
15708   "TARGET_64BIT && TARGET_ABM"
15709   "lzcnt{q}\t{%1, %0|%0, %1}"
15710   [(set_attr "prefix_rep" "1")
15711    (set_attr "type" "bitmanip")
15712    (set_attr "mode" "DI")])
15713
15714 (define_insn "*bsr_rex64"
15715   [(set (match_operand:DI 0 "register_operand" "=r")
15716         (minus:DI (const_int 63)
15717                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15718    (clobber (reg:CC FLAGS_REG))]
15719   "TARGET_64BIT"
15720   "bsr{q}\t{%1, %0|%0, %1}"
15721   [(set_attr "prefix_0f" "1")
15722    (set_attr "mode" "DI")])
15723
15724 (define_expand "clzhi2"
15725   [(parallel
15726      [(set (match_operand:HI 0 "register_operand" "")
15727            (minus:HI (const_int 15)
15728                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15729       (clobber (reg:CC FLAGS_REG))])
15730    (parallel
15731      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15732       (clobber (reg:CC FLAGS_REG))])]
15733   ""
15734 {
15735   if (TARGET_ABM)
15736     {
15737       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15738       DONE;
15739     }
15740 })
15741
15742 (define_insn "clzhi2_abm"
15743   [(set (match_operand:HI 0 "register_operand" "=r")
15744         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15745    (clobber (reg:CC FLAGS_REG))]
15746   "TARGET_ABM"
15747   "lzcnt{w}\t{%1, %0|%0, %1}"
15748   [(set_attr "prefix_rep" "1")
15749    (set_attr "type" "bitmanip")
15750    (set_attr "mode" "HI")])
15751
15752 (define_insn "*bsrhi"
15753   [(set (match_operand:HI 0 "register_operand" "=r")
15754         (minus:HI (const_int 15)
15755                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15756    (clobber (reg:CC FLAGS_REG))]
15757   ""
15758   "bsr{w}\t{%1, %0|%0, %1}"
15759   [(set_attr "prefix_0f" "1")
15760    (set_attr "mode" "HI")])
15761
15762 (define_expand "paritydi2"
15763   [(set (match_operand:DI 0 "register_operand" "")
15764         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15765   "! TARGET_POPCNT"
15766 {
15767   rtx scratch = gen_reg_rtx (QImode);
15768   rtx cond;
15769
15770   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15771                                 NULL_RTX, operands[1]));
15772
15773   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15774                          gen_rtx_REG (CCmode, FLAGS_REG),
15775                          const0_rtx);
15776   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15777
15778   if (TARGET_64BIT)
15779     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15780   else
15781     {
15782       rtx tmp = gen_reg_rtx (SImode);
15783
15784       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15785       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15786     }
15787   DONE;
15788 })
15789
15790 (define_insn_and_split "paritydi2_cmp"
15791   [(set (reg:CC FLAGS_REG)
15792         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
15793                    UNSPEC_PARITY))
15794    (clobber (match_scratch:DI 0 "=r"))
15795    (clobber (match_scratch:SI 1 "=&r"))
15796    (clobber (match_scratch:HI 2 "=Q"))]
15797   "! TARGET_POPCNT"
15798   "#"
15799   "&& reload_completed"
15800   [(parallel
15801      [(set (match_dup 1)
15802            (xor:SI (match_dup 1) (match_dup 4)))
15803       (clobber (reg:CC FLAGS_REG))])
15804    (parallel
15805      [(set (reg:CC FLAGS_REG)
15806            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
15807       (clobber (match_dup 1))
15808       (clobber (match_dup 2))])]
15809 {
15810   operands[4] = gen_lowpart (SImode, operands[3]);
15811
15812   if (TARGET_64BIT)
15813     {
15814       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15815       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15816     }
15817   else
15818     operands[1] = gen_highpart (SImode, operands[3]);
15819 })
15820
15821 (define_expand "paritysi2"
15822   [(set (match_operand:SI 0 "register_operand" "")
15823         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15824   "! TARGET_POPCNT"
15825 {
15826   rtx scratch = gen_reg_rtx (QImode);
15827   rtx cond;
15828
15829   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15830
15831   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15832                          gen_rtx_REG (CCmode, FLAGS_REG),
15833                          const0_rtx);
15834   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15835
15836   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15837   DONE;
15838 })
15839
15840 (define_insn_and_split "paritysi2_cmp"
15841   [(set (reg:CC FLAGS_REG)
15842         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
15843                    UNSPEC_PARITY))
15844    (clobber (match_scratch:SI 0 "=r"))
15845    (clobber (match_scratch:HI 1 "=&Q"))]
15846   "! TARGET_POPCNT"
15847   "#"
15848   "&& reload_completed"
15849   [(parallel
15850      [(set (match_dup 1)
15851            (xor:HI (match_dup 1) (match_dup 3)))
15852       (clobber (reg:CC FLAGS_REG))])
15853    (parallel
15854      [(set (reg:CC FLAGS_REG)
15855            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
15856       (clobber (match_dup 1))])]
15857 {
15858   operands[3] = gen_lowpart (HImode, operands[2]);
15859
15860   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15861   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15862 })
15863
15864 (define_insn "*parityhi2_cmp"
15865   [(set (reg:CC FLAGS_REG)
15866         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
15867                    UNSPEC_PARITY))
15868    (clobber (match_scratch:HI 0 "=Q"))]
15869   "! TARGET_POPCNT"
15870   "xor{b}\t{%h0, %b0|%b0, %h0}"
15871   [(set_attr "length" "2")
15872    (set_attr "mode" "HI")])
15873 \f
15874 ;; Thread-local storage patterns for ELF.
15875 ;;
15876 ;; Note that these code sequences must appear exactly as shown
15877 ;; in order to allow linker relaxation.
15878
15879 (define_insn "*tls_global_dynamic_32_gnu"
15880   [(set (match_operand:SI 0 "register_operand" "=a")
15881         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15882                     (match_operand:SI 2 "tls_symbolic_operand" "")
15883                     (match_operand:SI 3 "call_insn_operand" "")]
15884                     UNSPEC_TLS_GD))
15885    (clobber (match_scratch:SI 4 "=d"))
15886    (clobber (match_scratch:SI 5 "=c"))
15887    (clobber (reg:CC FLAGS_REG))]
15888   "!TARGET_64BIT && TARGET_GNU_TLS"
15889   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15890   [(set_attr "type" "multi")
15891    (set_attr "length" "12")])
15892
15893 (define_expand "tls_global_dynamic_32"
15894   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15895                    (unspec:SI
15896                     [(match_dup 2)
15897                      (match_operand:SI 1 "tls_symbolic_operand" "")
15898                      (match_dup 3)]
15899                     UNSPEC_TLS_GD))
15900               (clobber (match_scratch:SI 4 ""))
15901               (clobber (match_scratch:SI 5 ""))
15902               (clobber (reg:CC FLAGS_REG))])]
15903   ""
15904 {
15905   if (flag_pic)
15906     operands[2] = pic_offset_table_rtx;
15907   else
15908     {
15909       operands[2] = gen_reg_rtx (Pmode);
15910       emit_insn (gen_set_got (operands[2]));
15911     }
15912   if (TARGET_GNU2_TLS)
15913     {
15914        emit_insn (gen_tls_dynamic_gnu2_32
15915                   (operands[0], operands[1], operands[2]));
15916        DONE;
15917     }
15918   operands[3] = ix86_tls_get_addr ();
15919 })
15920
15921 (define_insn "*tls_global_dynamic_64"
15922   [(set (match_operand:DI 0 "register_operand" "=a")
15923         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15924                  (match_operand:DI 3 "" "")))
15925    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15926               UNSPEC_TLS_GD)]
15927   "TARGET_64BIT"
15928   { return ".byte\t0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
15929   [(set_attr "type" "multi")
15930    (set_attr "length" "16")])
15931
15932 (define_expand "tls_global_dynamic_64"
15933   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15934                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15935               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15936                          UNSPEC_TLS_GD)])]
15937   ""
15938 {
15939   if (TARGET_GNU2_TLS)
15940     {
15941        emit_insn (gen_tls_dynamic_gnu2_64
15942                   (operands[0], operands[1]));
15943        DONE;
15944     }
15945   operands[2] = ix86_tls_get_addr ();
15946 })
15947
15948 (define_insn "*tls_local_dynamic_base_32_gnu"
15949   [(set (match_operand:SI 0 "register_operand" "=a")
15950         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15951                     (match_operand:SI 2 "call_insn_operand" "")]
15952                    UNSPEC_TLS_LD_BASE))
15953    (clobber (match_scratch:SI 3 "=d"))
15954    (clobber (match_scratch:SI 4 "=c"))
15955    (clobber (reg:CC FLAGS_REG))]
15956   "!TARGET_64BIT && TARGET_GNU_TLS"
15957   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15958   [(set_attr "type" "multi")
15959    (set_attr "length" "11")])
15960
15961 (define_expand "tls_local_dynamic_base_32"
15962   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15963                    (unspec:SI [(match_dup 1) (match_dup 2)]
15964                               UNSPEC_TLS_LD_BASE))
15965               (clobber (match_scratch:SI 3 ""))
15966               (clobber (match_scratch:SI 4 ""))
15967               (clobber (reg:CC FLAGS_REG))])]
15968   ""
15969 {
15970   if (flag_pic)
15971     operands[1] = pic_offset_table_rtx;
15972   else
15973     {
15974       operands[1] = gen_reg_rtx (Pmode);
15975       emit_insn (gen_set_got (operands[1]));
15976     }
15977   if (TARGET_GNU2_TLS)
15978     {
15979        emit_insn (gen_tls_dynamic_gnu2_32
15980                   (operands[0], ix86_tls_module_base (), operands[1]));
15981        DONE;
15982     }
15983   operands[2] = ix86_tls_get_addr ();
15984 })
15985
15986 (define_insn "*tls_local_dynamic_base_64"
15987   [(set (match_operand:DI 0 "register_operand" "=a")
15988         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15989                  (match_operand:DI 2 "" "")))
15990    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15991   "TARGET_64BIT"
15992   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15993   [(set_attr "type" "multi")
15994    (set_attr "length" "12")])
15995
15996 (define_expand "tls_local_dynamic_base_64"
15997   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15998                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15999               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16000   ""
16001 {
16002   if (TARGET_GNU2_TLS)
16003     {
16004        emit_insn (gen_tls_dynamic_gnu2_64
16005                   (operands[0], ix86_tls_module_base ()));
16006        DONE;
16007     }
16008   operands[1] = ix86_tls_get_addr ();
16009 })
16010
16011 ;; Local dynamic of a single variable is a lose.  Show combine how
16012 ;; to convert that back to global dynamic.
16013
16014 (define_insn_and_split "*tls_local_dynamic_32_once"
16015   [(set (match_operand:SI 0 "register_operand" "=a")
16016         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16017                              (match_operand:SI 2 "call_insn_operand" "")]
16018                             UNSPEC_TLS_LD_BASE)
16019                  (const:SI (unspec:SI
16020                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16021                             UNSPEC_DTPOFF))))
16022    (clobber (match_scratch:SI 4 "=d"))
16023    (clobber (match_scratch:SI 5 "=c"))
16024    (clobber (reg:CC FLAGS_REG))]
16025   ""
16026   "#"
16027   ""
16028   [(parallel [(set (match_dup 0)
16029                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16030                               UNSPEC_TLS_GD))
16031               (clobber (match_dup 4))
16032               (clobber (match_dup 5))
16033               (clobber (reg:CC FLAGS_REG))])]
16034   "")
16035
16036 ;; Load and add the thread base pointer from %gs:0.
16037
16038 (define_insn "*load_tp_si"
16039   [(set (match_operand:SI 0 "register_operand" "=r")
16040         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16041   "!TARGET_64BIT"
16042   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16043   [(set_attr "type" "imov")
16044    (set_attr "modrm" "0")
16045    (set_attr "length" "7")
16046    (set_attr "memory" "load")
16047    (set_attr "imm_disp" "false")])
16048
16049 (define_insn "*add_tp_si"
16050   [(set (match_operand:SI 0 "register_operand" "=r")
16051         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16052                  (match_operand:SI 1 "register_operand" "0")))
16053    (clobber (reg:CC FLAGS_REG))]
16054   "!TARGET_64BIT"
16055   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16056   [(set_attr "type" "alu")
16057    (set_attr "modrm" "0")
16058    (set_attr "length" "7")
16059    (set_attr "memory" "load")
16060    (set_attr "imm_disp" "false")])
16061
16062 (define_insn "*load_tp_di"
16063   [(set (match_operand:DI 0 "register_operand" "=r")
16064         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16065   "TARGET_64BIT"
16066   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16067   [(set_attr "type" "imov")
16068    (set_attr "modrm" "0")
16069    (set_attr "length" "7")
16070    (set_attr "memory" "load")
16071    (set_attr "imm_disp" "false")])
16072
16073 (define_insn "*add_tp_di"
16074   [(set (match_operand:DI 0 "register_operand" "=r")
16075         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16076                  (match_operand:DI 1 "register_operand" "0")))
16077    (clobber (reg:CC FLAGS_REG))]
16078   "TARGET_64BIT"
16079   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16080   [(set_attr "type" "alu")
16081    (set_attr "modrm" "0")
16082    (set_attr "length" "7")
16083    (set_attr "memory" "load")
16084    (set_attr "imm_disp" "false")])
16085
16086 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
16087 ;; %rax as destination of the initial executable code sequence.
16088 (define_insn "tls_initial_exec_64_sun"
16089   [(set (match_operand:DI 0 "register_operand" "=a")
16090         (unspec:DI
16091          [(match_operand:DI 1 "tls_symbolic_operand" "")]
16092          UNSPEC_TLS_IE_SUN))
16093    (clobber (reg:CC FLAGS_REG))]
16094   "TARGET_64BIT && TARGET_SUN_TLS"
16095   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
16096   [(set_attr "type" "multi")])
16097
16098 ;; GNU2 TLS patterns can be split.
16099
16100 (define_expand "tls_dynamic_gnu2_32"
16101   [(set (match_dup 3)
16102         (plus:SI (match_operand:SI 2 "register_operand" "")
16103                  (const:SI
16104                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16105                              UNSPEC_TLSDESC))))
16106    (parallel
16107     [(set (match_operand:SI 0 "register_operand" "")
16108           (unspec:SI [(match_dup 1) (match_dup 3)
16109                       (match_dup 2) (reg:SI SP_REG)]
16110                       UNSPEC_TLSDESC))
16111      (clobber (reg:CC FLAGS_REG))])]
16112   "!TARGET_64BIT && TARGET_GNU2_TLS"
16113 {
16114   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16115   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16116 })
16117
16118 (define_insn "*tls_dynamic_lea_32"
16119   [(set (match_operand:SI 0 "register_operand" "=r")
16120         (plus:SI (match_operand:SI 1 "register_operand" "b")
16121                  (const:SI
16122                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16123                               UNSPEC_TLSDESC))))]
16124   "!TARGET_64BIT && TARGET_GNU2_TLS"
16125   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16126   [(set_attr "type" "lea")
16127    (set_attr "mode" "SI")
16128    (set_attr "length" "6")
16129    (set_attr "length_address" "4")])
16130
16131 (define_insn "*tls_dynamic_call_32"
16132   [(set (match_operand:SI 0 "register_operand" "=a")
16133         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16134                     (match_operand:SI 2 "register_operand" "0")
16135                     ;; we have to make sure %ebx still points to the GOT
16136                     (match_operand:SI 3 "register_operand" "b")
16137                     (reg:SI SP_REG)]
16138                    UNSPEC_TLSDESC))
16139    (clobber (reg:CC FLAGS_REG))]
16140   "!TARGET_64BIT && TARGET_GNU2_TLS"
16141   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16142   [(set_attr "type" "call")
16143    (set_attr "length" "2")
16144    (set_attr "length_address" "0")])
16145
16146 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16147   [(set (match_operand:SI 0 "register_operand" "=&a")
16148         (plus:SI
16149          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16150                      (match_operand:SI 4 "" "")
16151                      (match_operand:SI 2 "register_operand" "b")
16152                      (reg:SI SP_REG)]
16153                     UNSPEC_TLSDESC)
16154          (const:SI (unspec:SI
16155                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16156                     UNSPEC_DTPOFF))))
16157    (clobber (reg:CC FLAGS_REG))]
16158   "!TARGET_64BIT && TARGET_GNU2_TLS"
16159   "#"
16160   ""
16161   [(set (match_dup 0) (match_dup 5))]
16162 {
16163   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16164   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16165 })
16166
16167 (define_expand "tls_dynamic_gnu2_64"
16168   [(set (match_dup 2)
16169         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16170                    UNSPEC_TLSDESC))
16171    (parallel
16172     [(set (match_operand:DI 0 "register_operand" "")
16173           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16174                      UNSPEC_TLSDESC))
16175      (clobber (reg:CC FLAGS_REG))])]
16176   "TARGET_64BIT && TARGET_GNU2_TLS"
16177 {
16178   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16179   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16180 })
16181
16182 (define_insn "*tls_dynamic_lea_64"
16183   [(set (match_operand:DI 0 "register_operand" "=r")
16184         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16185                    UNSPEC_TLSDESC))]
16186   "TARGET_64BIT && TARGET_GNU2_TLS"
16187   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16188   [(set_attr "type" "lea")
16189    (set_attr "mode" "DI")
16190    (set_attr "length" "7")
16191    (set_attr "length_address" "4")])
16192
16193 (define_insn "*tls_dynamic_call_64"
16194   [(set (match_operand:DI 0 "register_operand" "=a")
16195         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16196                     (match_operand:DI 2 "register_operand" "0")
16197                     (reg:DI SP_REG)]
16198                    UNSPEC_TLSDESC))
16199    (clobber (reg:CC FLAGS_REG))]
16200   "TARGET_64BIT && TARGET_GNU2_TLS"
16201   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16202   [(set_attr "type" "call")
16203    (set_attr "length" "2")
16204    (set_attr "length_address" "0")])
16205
16206 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16207   [(set (match_operand:DI 0 "register_operand" "=&a")
16208         (plus:DI
16209          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16210                      (match_operand:DI 3 "" "")
16211                      (reg:DI SP_REG)]
16212                     UNSPEC_TLSDESC)
16213          (const:DI (unspec:DI
16214                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16215                     UNSPEC_DTPOFF))))
16216    (clobber (reg:CC FLAGS_REG))]
16217   "TARGET_64BIT && TARGET_GNU2_TLS"
16218   "#"
16219   ""
16220   [(set (match_dup 0) (match_dup 4))]
16221 {
16222   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16223   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16224 })
16225
16226 ;;
16227 \f
16228 ;; These patterns match the binary 387 instructions for addM3, subM3,
16229 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16230 ;; SFmode.  The first is the normal insn, the second the same insn but
16231 ;; with one operand a conversion, and the third the same insn but with
16232 ;; the other operand a conversion.  The conversion may be SFmode or
16233 ;; SImode if the target mode DFmode, but only SImode if the target mode
16234 ;; is SFmode.
16235
16236 ;; Gcc is slightly more smart about handling normal two address instructions
16237 ;; so use special patterns for add and mull.
16238
16239 (define_insn "*fop_<mode>_comm_mixed_avx"
16240   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16241         (match_operator:MODEF 3 "binary_fp_operator"
16242           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16243            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16244   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16245    && COMMUTATIVE_ARITH_P (operands[3])
16246    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16247   "* return output_387_binary_op (insn, operands);"
16248   [(set (attr "type")
16249         (if_then_else (eq_attr "alternative" "1")
16250            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16251               (const_string "ssemul")
16252               (const_string "sseadd"))
16253            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16254               (const_string "fmul")
16255               (const_string "fop"))))
16256    (set_attr "prefix" "orig,maybe_vex")
16257    (set_attr "mode" "<MODE>")])
16258
16259 (define_insn "*fop_<mode>_comm_mixed"
16260   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16261         (match_operator:MODEF 3 "binary_fp_operator"
16262           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16263            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16264   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16265    && COMMUTATIVE_ARITH_P (operands[3])
16266    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16267   "* return output_387_binary_op (insn, operands);"
16268   [(set (attr "type")
16269         (if_then_else (eq_attr "alternative" "1")
16270            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16271               (const_string "ssemul")
16272               (const_string "sseadd"))
16273            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16274               (const_string "fmul")
16275               (const_string "fop"))))
16276    (set_attr "mode" "<MODE>")])
16277
16278 (define_insn "*fop_<mode>_comm_avx"
16279   [(set (match_operand:MODEF 0 "register_operand" "=x")
16280         (match_operator:MODEF 3 "binary_fp_operator"
16281           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16282            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16283   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16284    && COMMUTATIVE_ARITH_P (operands[3])
16285    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16286   "* return output_387_binary_op (insn, operands);"
16287   [(set (attr "type")
16288         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16289            (const_string "ssemul")
16290            (const_string "sseadd")))
16291    (set_attr "prefix" "vex")
16292    (set_attr "mode" "<MODE>")])
16293
16294 (define_insn "*fop_<mode>_comm_sse"
16295   [(set (match_operand:MODEF 0 "register_operand" "=x")
16296         (match_operator:MODEF 3 "binary_fp_operator"
16297           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16298            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16299   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16300    && COMMUTATIVE_ARITH_P (operands[3])
16301    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16302   "* return output_387_binary_op (insn, operands);"
16303   [(set (attr "type")
16304         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16305            (const_string "ssemul")
16306            (const_string "sseadd")))
16307    (set_attr "mode" "<MODE>")])
16308
16309 (define_insn "*fop_<mode>_comm_i387"
16310   [(set (match_operand:MODEF 0 "register_operand" "=f")
16311         (match_operator:MODEF 3 "binary_fp_operator"
16312           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16313            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16314   "TARGET_80387
16315    && COMMUTATIVE_ARITH_P (operands[3])
16316    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16317   "* return output_387_binary_op (insn, operands);"
16318   [(set (attr "type")
16319         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16320            (const_string "fmul")
16321            (const_string "fop")))
16322    (set_attr "mode" "<MODE>")])
16323
16324 (define_insn "*fop_<mode>_1_mixed_avx"
16325   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16326         (match_operator:MODEF 3 "binary_fp_operator"
16327           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16328            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16329   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16330    && !COMMUTATIVE_ARITH_P (operands[3])
16331    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16332   "* return output_387_binary_op (insn, operands);"
16333   [(set (attr "type")
16334         (cond [(and (eq_attr "alternative" "2")
16335                     (match_operand:MODEF 3 "mult_operator" ""))
16336                  (const_string "ssemul")
16337                (and (eq_attr "alternative" "2")
16338                     (match_operand:MODEF 3 "div_operator" ""))
16339                  (const_string "ssediv")
16340                (eq_attr "alternative" "2")
16341                  (const_string "sseadd")
16342                (match_operand:MODEF 3 "mult_operator" "")
16343                  (const_string "fmul")
16344                (match_operand:MODEF 3 "div_operator" "")
16345                  (const_string "fdiv")
16346               ]
16347               (const_string "fop")))
16348    (set_attr "prefix" "orig,orig,maybe_vex")
16349    (set_attr "mode" "<MODE>")])
16350
16351 (define_insn "*fop_<mode>_1_mixed"
16352   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16353         (match_operator:MODEF 3 "binary_fp_operator"
16354           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16355            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16356   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16357    && !COMMUTATIVE_ARITH_P (operands[3])
16358    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16359   "* return output_387_binary_op (insn, operands);"
16360   [(set (attr "type")
16361         (cond [(and (eq_attr "alternative" "2")
16362                     (match_operand:MODEF 3 "mult_operator" ""))
16363                  (const_string "ssemul")
16364                (and (eq_attr "alternative" "2")
16365                     (match_operand:MODEF 3 "div_operator" ""))
16366                  (const_string "ssediv")
16367                (eq_attr "alternative" "2")
16368                  (const_string "sseadd")
16369                (match_operand:MODEF 3 "mult_operator" "")
16370                  (const_string "fmul")
16371                (match_operand:MODEF 3 "div_operator" "")
16372                  (const_string "fdiv")
16373               ]
16374               (const_string "fop")))
16375    (set_attr "mode" "<MODE>")])
16376
16377 (define_insn "*rcpsf2_sse"
16378   [(set (match_operand:SF 0 "register_operand" "=x")
16379         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16380                    UNSPEC_RCP))]
16381   "TARGET_SSE_MATH"
16382   "%vrcpss\t{%1, %d0|%d0, %1}"
16383   [(set_attr "type" "sse")
16384    (set_attr "prefix" "maybe_vex")
16385    (set_attr "mode" "SF")])
16386
16387 (define_insn "*fop_<mode>_1_avx"
16388   [(set (match_operand:MODEF 0 "register_operand" "=x")
16389         (match_operator:MODEF 3 "binary_fp_operator"
16390           [(match_operand:MODEF 1 "register_operand" "x")
16391            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16392   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16393    && !COMMUTATIVE_ARITH_P (operands[3])"
16394   "* return output_387_binary_op (insn, operands);"
16395   [(set (attr "type")
16396         (cond [(match_operand:MODEF 3 "mult_operator" "")
16397                  (const_string "ssemul")
16398                (match_operand:MODEF 3 "div_operator" "")
16399                  (const_string "ssediv")
16400               ]
16401               (const_string "sseadd")))
16402    (set_attr "prefix" "vex")
16403    (set_attr "mode" "<MODE>")])
16404
16405 (define_insn "*fop_<mode>_1_sse"
16406   [(set (match_operand:MODEF 0 "register_operand" "=x")
16407         (match_operator:MODEF 3 "binary_fp_operator"
16408           [(match_operand:MODEF 1 "register_operand" "0")
16409            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16410   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16411    && !COMMUTATIVE_ARITH_P (operands[3])"
16412   "* return output_387_binary_op (insn, operands);"
16413   [(set (attr "type")
16414         (cond [(match_operand:MODEF 3 "mult_operator" "")
16415                  (const_string "ssemul")
16416                (match_operand:MODEF 3 "div_operator" "")
16417                  (const_string "ssediv")
16418               ]
16419               (const_string "sseadd")))
16420    (set_attr "mode" "<MODE>")])
16421
16422 ;; This pattern is not fully shadowed by the pattern above.
16423 (define_insn "*fop_<mode>_1_i387"
16424   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16425         (match_operator:MODEF 3 "binary_fp_operator"
16426           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16427            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16428   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16429    && !COMMUTATIVE_ARITH_P (operands[3])
16430    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16431   "* return output_387_binary_op (insn, operands);"
16432   [(set (attr "type")
16433         (cond [(match_operand:MODEF 3 "mult_operator" "")
16434                  (const_string "fmul")
16435                (match_operand:MODEF 3 "div_operator" "")
16436                  (const_string "fdiv")
16437               ]
16438               (const_string "fop")))
16439    (set_attr "mode" "<MODE>")])
16440
16441 ;; ??? Add SSE splitters for these!
16442 (define_insn "*fop_<MODEF:mode>_2_i387"
16443   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16444         (match_operator:MODEF 3 "binary_fp_operator"
16445           [(float:MODEF
16446              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16447            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16448   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16449    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16450   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16451   [(set (attr "type")
16452         (cond [(match_operand:MODEF 3 "mult_operator" "")
16453                  (const_string "fmul")
16454                (match_operand:MODEF 3 "div_operator" "")
16455                  (const_string "fdiv")
16456               ]
16457               (const_string "fop")))
16458    (set_attr "fp_int_src" "true")
16459    (set_attr "mode" "<X87MODEI12:MODE>")])
16460
16461 (define_insn "*fop_<MODEF:mode>_3_i387"
16462   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16463         (match_operator:MODEF 3 "binary_fp_operator"
16464           [(match_operand:MODEF 1 "register_operand" "0,0")
16465            (float:MODEF
16466              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16467   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16468    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16469   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16470   [(set (attr "type")
16471         (cond [(match_operand:MODEF 3 "mult_operator" "")
16472                  (const_string "fmul")
16473                (match_operand:MODEF 3 "div_operator" "")
16474                  (const_string "fdiv")
16475               ]
16476               (const_string "fop")))
16477    (set_attr "fp_int_src" "true")
16478    (set_attr "mode" "<MODE>")])
16479
16480 (define_insn "*fop_df_4_i387"
16481   [(set (match_operand:DF 0 "register_operand" "=f,f")
16482         (match_operator:DF 3 "binary_fp_operator"
16483            [(float_extend:DF
16484              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16485             (match_operand:DF 2 "register_operand" "0,f")]))]
16486   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16487    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16488   "* return output_387_binary_op (insn, operands);"
16489   [(set (attr "type")
16490         (cond [(match_operand:DF 3 "mult_operator" "")
16491                  (const_string "fmul")
16492                (match_operand:DF 3 "div_operator" "")
16493                  (const_string "fdiv")
16494               ]
16495               (const_string "fop")))
16496    (set_attr "mode" "SF")])
16497
16498 (define_insn "*fop_df_5_i387"
16499   [(set (match_operand:DF 0 "register_operand" "=f,f")
16500         (match_operator:DF 3 "binary_fp_operator"
16501           [(match_operand:DF 1 "register_operand" "0,f")
16502            (float_extend:DF
16503             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16504   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16505   "* return output_387_binary_op (insn, operands);"
16506   [(set (attr "type")
16507         (cond [(match_operand:DF 3 "mult_operator" "")
16508                  (const_string "fmul")
16509                (match_operand:DF 3 "div_operator" "")
16510                  (const_string "fdiv")
16511               ]
16512               (const_string "fop")))
16513    (set_attr "mode" "SF")])
16514
16515 (define_insn "*fop_df_6_i387"
16516   [(set (match_operand:DF 0 "register_operand" "=f,f")
16517         (match_operator:DF 3 "binary_fp_operator"
16518           [(float_extend:DF
16519             (match_operand:SF 1 "register_operand" "0,f"))
16520            (float_extend:DF
16521             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16522   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16523   "* return output_387_binary_op (insn, operands);"
16524   [(set (attr "type")
16525         (cond [(match_operand:DF 3 "mult_operator" "")
16526                  (const_string "fmul")
16527                (match_operand:DF 3 "div_operator" "")
16528                  (const_string "fdiv")
16529               ]
16530               (const_string "fop")))
16531    (set_attr "mode" "SF")])
16532
16533 (define_insn "*fop_xf_comm_i387"
16534   [(set (match_operand:XF 0 "register_operand" "=f")
16535         (match_operator:XF 3 "binary_fp_operator"
16536                         [(match_operand:XF 1 "register_operand" "%0")
16537                          (match_operand:XF 2 "register_operand" "f")]))]
16538   "TARGET_80387
16539    && COMMUTATIVE_ARITH_P (operands[3])"
16540   "* return output_387_binary_op (insn, operands);"
16541   [(set (attr "type")
16542         (if_then_else (match_operand:XF 3 "mult_operator" "")
16543            (const_string "fmul")
16544            (const_string "fop")))
16545    (set_attr "mode" "XF")])
16546
16547 (define_insn "*fop_xf_1_i387"
16548   [(set (match_operand:XF 0 "register_operand" "=f,f")
16549         (match_operator:XF 3 "binary_fp_operator"
16550                         [(match_operand:XF 1 "register_operand" "0,f")
16551                          (match_operand:XF 2 "register_operand" "f,0")]))]
16552   "TARGET_80387
16553    && !COMMUTATIVE_ARITH_P (operands[3])"
16554   "* return output_387_binary_op (insn, operands);"
16555   [(set (attr "type")
16556         (cond [(match_operand:XF 3 "mult_operator" "")
16557                  (const_string "fmul")
16558                (match_operand:XF 3 "div_operator" "")
16559                  (const_string "fdiv")
16560               ]
16561               (const_string "fop")))
16562    (set_attr "mode" "XF")])
16563
16564 (define_insn "*fop_xf_2_i387"
16565   [(set (match_operand:XF 0 "register_operand" "=f,f")
16566         (match_operator:XF 3 "binary_fp_operator"
16567           [(float:XF
16568              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16569            (match_operand:XF 2 "register_operand" "0,0")]))]
16570   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16571   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16572   [(set (attr "type")
16573         (cond [(match_operand:XF 3 "mult_operator" "")
16574                  (const_string "fmul")
16575                (match_operand:XF 3 "div_operator" "")
16576                  (const_string "fdiv")
16577               ]
16578               (const_string "fop")))
16579    (set_attr "fp_int_src" "true")
16580    (set_attr "mode" "<MODE>")])
16581
16582 (define_insn "*fop_xf_3_i387"
16583   [(set (match_operand:XF 0 "register_operand" "=f,f")
16584         (match_operator:XF 3 "binary_fp_operator"
16585           [(match_operand:XF 1 "register_operand" "0,0")
16586            (float:XF
16587              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16588   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16589   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16590   [(set (attr "type")
16591         (cond [(match_operand:XF 3 "mult_operator" "")
16592                  (const_string "fmul")
16593                (match_operand:XF 3 "div_operator" "")
16594                  (const_string "fdiv")
16595               ]
16596               (const_string "fop")))
16597    (set_attr "fp_int_src" "true")
16598    (set_attr "mode" "<MODE>")])
16599
16600 (define_insn "*fop_xf_4_i387"
16601   [(set (match_operand:XF 0 "register_operand" "=f,f")
16602         (match_operator:XF 3 "binary_fp_operator"
16603            [(float_extend:XF
16604               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16605             (match_operand:XF 2 "register_operand" "0,f")]))]
16606   "TARGET_80387"
16607   "* return output_387_binary_op (insn, operands);"
16608   [(set (attr "type")
16609         (cond [(match_operand:XF 3 "mult_operator" "")
16610                  (const_string "fmul")
16611                (match_operand:XF 3 "div_operator" "")
16612                  (const_string "fdiv")
16613               ]
16614               (const_string "fop")))
16615    (set_attr "mode" "<MODE>")])
16616
16617 (define_insn "*fop_xf_5_i387"
16618   [(set (match_operand:XF 0 "register_operand" "=f,f")
16619         (match_operator:XF 3 "binary_fp_operator"
16620           [(match_operand:XF 1 "register_operand" "0,f")
16621            (float_extend:XF
16622              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16623   "TARGET_80387"
16624   "* return output_387_binary_op (insn, operands);"
16625   [(set (attr "type")
16626         (cond [(match_operand:XF 3 "mult_operator" "")
16627                  (const_string "fmul")
16628                (match_operand:XF 3 "div_operator" "")
16629                  (const_string "fdiv")
16630               ]
16631               (const_string "fop")))
16632    (set_attr "mode" "<MODE>")])
16633
16634 (define_insn "*fop_xf_6_i387"
16635   [(set (match_operand:XF 0 "register_operand" "=f,f")
16636         (match_operator:XF 3 "binary_fp_operator"
16637           [(float_extend:XF
16638              (match_operand:MODEF 1 "register_operand" "0,f"))
16639            (float_extend:XF
16640              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16641   "TARGET_80387"
16642   "* return output_387_binary_op (insn, operands);"
16643   [(set (attr "type")
16644         (cond [(match_operand:XF 3 "mult_operator" "")
16645                  (const_string "fmul")
16646                (match_operand:XF 3 "div_operator" "")
16647                  (const_string "fdiv")
16648               ]
16649               (const_string "fop")))
16650    (set_attr "mode" "<MODE>")])
16651
16652 (define_split
16653   [(set (match_operand 0 "register_operand" "")
16654         (match_operator 3 "binary_fp_operator"
16655            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16656             (match_operand 2 "register_operand" "")]))]
16657   "reload_completed
16658    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16659   [(const_int 0)]
16660 {
16661   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16662   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16663   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16664                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16665                                           GET_MODE (operands[3]),
16666                                           operands[4],
16667                                           operands[2])));
16668   ix86_free_from_memory (GET_MODE (operands[1]));
16669   DONE;
16670 })
16671
16672 (define_split
16673   [(set (match_operand 0 "register_operand" "")
16674         (match_operator 3 "binary_fp_operator"
16675            [(match_operand 1 "register_operand" "")
16676             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16677   "reload_completed
16678    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16679   [(const_int 0)]
16680 {
16681   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16682   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16683   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16684                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16685                                           GET_MODE (operands[3]),
16686                                           operands[1],
16687                                           operands[4])));
16688   ix86_free_from_memory (GET_MODE (operands[2]));
16689   DONE;
16690 })
16691 \f
16692 ;; FPU special functions.
16693
16694 ;; This pattern implements a no-op XFmode truncation for
16695 ;; all fancy i386 XFmode math functions.
16696
16697 (define_insn "truncxf<mode>2_i387_noop_unspec"
16698   [(set (match_operand:MODEF 0 "register_operand" "=f")
16699         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16700         UNSPEC_TRUNC_NOOP))]
16701   "TARGET_USE_FANCY_MATH_387"
16702   "* return output_387_reg_move (insn, operands);"
16703   [(set_attr "type" "fmov")
16704    (set_attr "mode" "<MODE>")])
16705
16706 (define_insn "sqrtxf2"
16707   [(set (match_operand:XF 0 "register_operand" "=f")
16708         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16709   "TARGET_USE_FANCY_MATH_387"
16710   "fsqrt"
16711   [(set_attr "type" "fpspc")
16712    (set_attr "mode" "XF")
16713    (set_attr "athlon_decode" "direct")
16714    (set_attr "amdfam10_decode" "direct")])
16715
16716 (define_insn "sqrt_extend<mode>xf2_i387"
16717   [(set (match_operand:XF 0 "register_operand" "=f")
16718         (sqrt:XF
16719           (float_extend:XF
16720             (match_operand:MODEF 1 "register_operand" "0"))))]
16721   "TARGET_USE_FANCY_MATH_387"
16722   "fsqrt"
16723   [(set_attr "type" "fpspc")
16724    (set_attr "mode" "XF")
16725    (set_attr "athlon_decode" "direct")
16726    (set_attr "amdfam10_decode" "direct")])
16727
16728 (define_insn "*rsqrtsf2_sse"
16729   [(set (match_operand:SF 0 "register_operand" "=x")
16730         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16731                    UNSPEC_RSQRT))]
16732   "TARGET_SSE_MATH"
16733   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16734   [(set_attr "type" "sse")
16735    (set_attr "prefix" "maybe_vex")
16736    (set_attr "mode" "SF")])
16737
16738 (define_expand "rsqrtsf2"
16739   [(set (match_operand:SF 0 "register_operand" "")
16740         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16741                    UNSPEC_RSQRT))]
16742   "TARGET_SSE_MATH"
16743 {
16744   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16745   DONE;
16746 })
16747
16748 (define_insn "*sqrt<mode>2_sse"
16749   [(set (match_operand:MODEF 0 "register_operand" "=x")
16750         (sqrt:MODEF
16751           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16752   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16753   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16754   [(set_attr "type" "sse")
16755    (set_attr "prefix" "maybe_vex")
16756    (set_attr "mode" "<MODE>")
16757    (set_attr "athlon_decode" "*")
16758    (set_attr "amdfam10_decode" "*")])
16759
16760 (define_expand "sqrt<mode>2"
16761   [(set (match_operand:MODEF 0 "register_operand" "")
16762         (sqrt:MODEF
16763           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16764   "TARGET_USE_FANCY_MATH_387
16765    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16766 {
16767   if (<MODE>mode == SFmode
16768       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16769       && flag_finite_math_only && !flag_trapping_math
16770       && flag_unsafe_math_optimizations)
16771     {
16772       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16773       DONE;
16774     }
16775
16776   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16777     {
16778       rtx op0 = gen_reg_rtx (XFmode);
16779       rtx op1 = force_reg (<MODE>mode, operands[1]);
16780
16781       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16782       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16783       DONE;
16784    }
16785 })
16786
16787 (define_insn "fpremxf4_i387"
16788   [(set (match_operand:XF 0 "register_operand" "=f")
16789         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16790                     (match_operand:XF 3 "register_operand" "1")]
16791                    UNSPEC_FPREM_F))
16792    (set (match_operand:XF 1 "register_operand" "=u")
16793         (unspec:XF [(match_dup 2) (match_dup 3)]
16794                    UNSPEC_FPREM_U))
16795    (set (reg:CCFP FPSR_REG)
16796         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16797                      UNSPEC_C2_FLAG))]
16798   "TARGET_USE_FANCY_MATH_387"
16799   "fprem"
16800   [(set_attr "type" "fpspc")
16801    (set_attr "mode" "XF")])
16802
16803 (define_expand "fmodxf3"
16804   [(use (match_operand:XF 0 "register_operand" ""))
16805    (use (match_operand:XF 1 "general_operand" ""))
16806    (use (match_operand:XF 2 "general_operand" ""))]
16807   "TARGET_USE_FANCY_MATH_387"
16808 {
16809   rtx label = gen_label_rtx ();
16810
16811   rtx op1 = gen_reg_rtx (XFmode);
16812   rtx op2 = gen_reg_rtx (XFmode);
16813
16814   emit_move_insn (op2, operands[2]);
16815   emit_move_insn (op1, operands[1]);
16816
16817   emit_label (label);
16818   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16819   ix86_emit_fp_unordered_jump (label);
16820   LABEL_NUSES (label) = 1;
16821
16822   emit_move_insn (operands[0], op1);
16823   DONE;
16824 })
16825
16826 (define_expand "fmod<mode>3"
16827   [(use (match_operand:MODEF 0 "register_operand" ""))
16828    (use (match_operand:MODEF 1 "general_operand" ""))
16829    (use (match_operand:MODEF 2 "general_operand" ""))]
16830   "TARGET_USE_FANCY_MATH_387"
16831 {
16832   rtx label = gen_label_rtx ();
16833
16834   rtx op1 = gen_reg_rtx (XFmode);
16835   rtx op2 = gen_reg_rtx (XFmode);
16836
16837   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16838   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16839
16840   emit_label (label);
16841   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16842   ix86_emit_fp_unordered_jump (label);
16843   LABEL_NUSES (label) = 1;
16844
16845   /* Truncate the result properly for strict SSE math.  */
16846   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16847       && !TARGET_MIX_SSE_I387)
16848     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16849   else
16850     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16851
16852   DONE;
16853 })
16854
16855 (define_insn "fprem1xf4_i387"
16856   [(set (match_operand:XF 0 "register_operand" "=f")
16857         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16858                     (match_operand:XF 3 "register_operand" "1")]
16859                    UNSPEC_FPREM1_F))
16860    (set (match_operand:XF 1 "register_operand" "=u")
16861         (unspec:XF [(match_dup 2) (match_dup 3)]
16862                    UNSPEC_FPREM1_U))
16863    (set (reg:CCFP FPSR_REG)
16864         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16865                      UNSPEC_C2_FLAG))]
16866   "TARGET_USE_FANCY_MATH_387"
16867   "fprem1"
16868   [(set_attr "type" "fpspc")
16869    (set_attr "mode" "XF")])
16870
16871 (define_expand "remainderxf3"
16872   [(use (match_operand:XF 0 "register_operand" ""))
16873    (use (match_operand:XF 1 "general_operand" ""))
16874    (use (match_operand:XF 2 "general_operand" ""))]
16875   "TARGET_USE_FANCY_MATH_387"
16876 {
16877   rtx label = gen_label_rtx ();
16878
16879   rtx op1 = gen_reg_rtx (XFmode);
16880   rtx op2 = gen_reg_rtx (XFmode);
16881
16882   emit_move_insn (op2, operands[2]);
16883   emit_move_insn (op1, operands[1]);
16884
16885   emit_label (label);
16886   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16887   ix86_emit_fp_unordered_jump (label);
16888   LABEL_NUSES (label) = 1;
16889
16890   emit_move_insn (operands[0], op1);
16891   DONE;
16892 })
16893
16894 (define_expand "remainder<mode>3"
16895   [(use (match_operand:MODEF 0 "register_operand" ""))
16896    (use (match_operand:MODEF 1 "general_operand" ""))
16897    (use (match_operand:MODEF 2 "general_operand" ""))]
16898   "TARGET_USE_FANCY_MATH_387"
16899 {
16900   rtx label = gen_label_rtx ();
16901
16902   rtx op1 = gen_reg_rtx (XFmode);
16903   rtx op2 = gen_reg_rtx (XFmode);
16904
16905   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16906   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16907
16908   emit_label (label);
16909
16910   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16911   ix86_emit_fp_unordered_jump (label);
16912   LABEL_NUSES (label) = 1;
16913
16914   /* Truncate the result properly for strict SSE math.  */
16915   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16916       && !TARGET_MIX_SSE_I387)
16917     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16918   else
16919     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16920
16921   DONE;
16922 })
16923
16924 (define_insn "*sinxf2_i387"
16925   [(set (match_operand:XF 0 "register_operand" "=f")
16926         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16927   "TARGET_USE_FANCY_MATH_387
16928    && flag_unsafe_math_optimizations"
16929   "fsin"
16930   [(set_attr "type" "fpspc")
16931    (set_attr "mode" "XF")])
16932
16933 (define_insn "*sin_extend<mode>xf2_i387"
16934   [(set (match_operand:XF 0 "register_operand" "=f")
16935         (unspec:XF [(float_extend:XF
16936                       (match_operand:MODEF 1 "register_operand" "0"))]
16937                    UNSPEC_SIN))]
16938   "TARGET_USE_FANCY_MATH_387
16939    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16940        || TARGET_MIX_SSE_I387)
16941    && flag_unsafe_math_optimizations"
16942   "fsin"
16943   [(set_attr "type" "fpspc")
16944    (set_attr "mode" "XF")])
16945
16946 (define_insn "*cosxf2_i387"
16947   [(set (match_operand:XF 0 "register_operand" "=f")
16948         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16949   "TARGET_USE_FANCY_MATH_387
16950    && flag_unsafe_math_optimizations"
16951   "fcos"
16952   [(set_attr "type" "fpspc")
16953    (set_attr "mode" "XF")])
16954
16955 (define_insn "*cos_extend<mode>xf2_i387"
16956   [(set (match_operand:XF 0 "register_operand" "=f")
16957         (unspec:XF [(float_extend:XF
16958                       (match_operand:MODEF 1 "register_operand" "0"))]
16959                    UNSPEC_COS))]
16960   "TARGET_USE_FANCY_MATH_387
16961    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16962        || TARGET_MIX_SSE_I387)
16963    && flag_unsafe_math_optimizations"
16964   "fcos"
16965   [(set_attr "type" "fpspc")
16966    (set_attr "mode" "XF")])
16967
16968 ;; When sincos pattern is defined, sin and cos builtin functions will be
16969 ;; expanded to sincos pattern with one of its outputs left unused.
16970 ;; CSE pass will figure out if two sincos patterns can be combined,
16971 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16972 ;; depending on the unused output.
16973
16974 (define_insn "sincosxf3"
16975   [(set (match_operand:XF 0 "register_operand" "=f")
16976         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16977                    UNSPEC_SINCOS_COS))
16978    (set (match_operand:XF 1 "register_operand" "=u")
16979         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16980   "TARGET_USE_FANCY_MATH_387
16981    && flag_unsafe_math_optimizations"
16982   "fsincos"
16983   [(set_attr "type" "fpspc")
16984    (set_attr "mode" "XF")])
16985
16986 (define_split
16987   [(set (match_operand:XF 0 "register_operand" "")
16988         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16989                    UNSPEC_SINCOS_COS))
16990    (set (match_operand:XF 1 "register_operand" "")
16991         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16992   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16993    && !(reload_completed || reload_in_progress)"
16994   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16995   "")
16996
16997 (define_split
16998   [(set (match_operand:XF 0 "register_operand" "")
16999         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17000                    UNSPEC_SINCOS_COS))
17001    (set (match_operand:XF 1 "register_operand" "")
17002         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17003   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17004    && !(reload_completed || reload_in_progress)"
17005   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17006   "")
17007
17008 (define_insn "sincos_extend<mode>xf3_i387"
17009   [(set (match_operand:XF 0 "register_operand" "=f")
17010         (unspec:XF [(float_extend:XF
17011                       (match_operand:MODEF 2 "register_operand" "0"))]
17012                    UNSPEC_SINCOS_COS))
17013    (set (match_operand:XF 1 "register_operand" "=u")
17014         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17015   "TARGET_USE_FANCY_MATH_387
17016    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17017        || TARGET_MIX_SSE_I387)
17018    && flag_unsafe_math_optimizations"
17019   "fsincos"
17020   [(set_attr "type" "fpspc")
17021    (set_attr "mode" "XF")])
17022
17023 (define_split
17024   [(set (match_operand:XF 0 "register_operand" "")
17025         (unspec:XF [(float_extend:XF
17026                       (match_operand:MODEF 2 "register_operand" ""))]
17027                    UNSPEC_SINCOS_COS))
17028    (set (match_operand:XF 1 "register_operand" "")
17029         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17030   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17031    && !(reload_completed || reload_in_progress)"
17032   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17033   "")
17034
17035 (define_split
17036   [(set (match_operand:XF 0 "register_operand" "")
17037         (unspec:XF [(float_extend:XF
17038                       (match_operand:MODEF 2 "register_operand" ""))]
17039                    UNSPEC_SINCOS_COS))
17040    (set (match_operand:XF 1 "register_operand" "")
17041         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17042   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17043    && !(reload_completed || reload_in_progress)"
17044   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17045   "")
17046
17047 (define_expand "sincos<mode>3"
17048   [(use (match_operand:MODEF 0 "register_operand" ""))
17049    (use (match_operand:MODEF 1 "register_operand" ""))
17050    (use (match_operand:MODEF 2 "register_operand" ""))]
17051   "TARGET_USE_FANCY_MATH_387
17052    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17053        || TARGET_MIX_SSE_I387)
17054    && flag_unsafe_math_optimizations"
17055 {
17056   rtx op0 = gen_reg_rtx (XFmode);
17057   rtx op1 = gen_reg_rtx (XFmode);
17058
17059   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17060   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17061   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17062   DONE;
17063 })
17064
17065 (define_insn "fptanxf4_i387"
17066   [(set (match_operand:XF 0 "register_operand" "=f")
17067         (match_operand:XF 3 "const_double_operand" "F"))
17068    (set (match_operand:XF 1 "register_operand" "=u")
17069         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17070                    UNSPEC_TAN))]
17071   "TARGET_USE_FANCY_MATH_387
17072    && flag_unsafe_math_optimizations
17073    && standard_80387_constant_p (operands[3]) == 2"
17074   "fptan"
17075   [(set_attr "type" "fpspc")
17076    (set_attr "mode" "XF")])
17077
17078 (define_insn "fptan_extend<mode>xf4_i387"
17079   [(set (match_operand:MODEF 0 "register_operand" "=f")
17080         (match_operand:MODEF 3 "const_double_operand" "F"))
17081    (set (match_operand:XF 1 "register_operand" "=u")
17082         (unspec:XF [(float_extend:XF
17083                       (match_operand:MODEF 2 "register_operand" "0"))]
17084                    UNSPEC_TAN))]
17085   "TARGET_USE_FANCY_MATH_387
17086    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17087        || TARGET_MIX_SSE_I387)
17088    && flag_unsafe_math_optimizations
17089    && standard_80387_constant_p (operands[3]) == 2"
17090   "fptan"
17091   [(set_attr "type" "fpspc")
17092    (set_attr "mode" "XF")])
17093
17094 (define_expand "tanxf2"
17095   [(use (match_operand:XF 0 "register_operand" ""))
17096    (use (match_operand:XF 1 "register_operand" ""))]
17097   "TARGET_USE_FANCY_MATH_387
17098    && flag_unsafe_math_optimizations"
17099 {
17100   rtx one = gen_reg_rtx (XFmode);
17101   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17102
17103   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17104   DONE;
17105 })
17106
17107 (define_expand "tan<mode>2"
17108   [(use (match_operand:MODEF 0 "register_operand" ""))
17109    (use (match_operand:MODEF 1 "register_operand" ""))]
17110   "TARGET_USE_FANCY_MATH_387
17111    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17112        || TARGET_MIX_SSE_I387)
17113    && flag_unsafe_math_optimizations"
17114 {
17115   rtx op0 = gen_reg_rtx (XFmode);
17116
17117   rtx one = gen_reg_rtx (<MODE>mode);
17118   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17119
17120   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17121                                              operands[1], op2));
17122   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17123   DONE;
17124 })
17125
17126 (define_insn "*fpatanxf3_i387"
17127   [(set (match_operand:XF 0 "register_operand" "=f")
17128         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17129                     (match_operand:XF 2 "register_operand" "u")]
17130                    UNSPEC_FPATAN))
17131    (clobber (match_scratch:XF 3 "=2"))]
17132   "TARGET_USE_FANCY_MATH_387
17133    && flag_unsafe_math_optimizations"
17134   "fpatan"
17135   [(set_attr "type" "fpspc")
17136    (set_attr "mode" "XF")])
17137
17138 (define_insn "fpatan_extend<mode>xf3_i387"
17139   [(set (match_operand:XF 0 "register_operand" "=f")
17140         (unspec:XF [(float_extend:XF
17141                       (match_operand:MODEF 1 "register_operand" "0"))
17142                     (float_extend:XF
17143                       (match_operand:MODEF 2 "register_operand" "u"))]
17144                    UNSPEC_FPATAN))
17145    (clobber (match_scratch:XF 3 "=2"))]
17146   "TARGET_USE_FANCY_MATH_387
17147    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17148        || TARGET_MIX_SSE_I387)
17149    && flag_unsafe_math_optimizations"
17150   "fpatan"
17151   [(set_attr "type" "fpspc")
17152    (set_attr "mode" "XF")])
17153
17154 (define_expand "atan2xf3"
17155   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17156                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17157                                (match_operand:XF 1 "register_operand" "")]
17158                               UNSPEC_FPATAN))
17159               (clobber (match_scratch:XF 3 ""))])]
17160   "TARGET_USE_FANCY_MATH_387
17161    && flag_unsafe_math_optimizations"
17162   "")
17163
17164 (define_expand "atan2<mode>3"
17165   [(use (match_operand:MODEF 0 "register_operand" ""))
17166    (use (match_operand:MODEF 1 "register_operand" ""))
17167    (use (match_operand:MODEF 2 "register_operand" ""))]
17168   "TARGET_USE_FANCY_MATH_387
17169    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17170        || TARGET_MIX_SSE_I387)
17171    && flag_unsafe_math_optimizations"
17172 {
17173   rtx op0 = gen_reg_rtx (XFmode);
17174
17175   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17176   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17177   DONE;
17178 })
17179
17180 (define_expand "atanxf2"
17181   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17182                    (unspec:XF [(match_dup 2)
17183                                (match_operand:XF 1 "register_operand" "")]
17184                               UNSPEC_FPATAN))
17185               (clobber (match_scratch:XF 3 ""))])]
17186   "TARGET_USE_FANCY_MATH_387
17187    && flag_unsafe_math_optimizations"
17188 {
17189   operands[2] = gen_reg_rtx (XFmode);
17190   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17191 })
17192
17193 (define_expand "atan<mode>2"
17194   [(use (match_operand:MODEF 0 "register_operand" ""))
17195    (use (match_operand:MODEF 1 "register_operand" ""))]
17196   "TARGET_USE_FANCY_MATH_387
17197    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17198        || TARGET_MIX_SSE_I387)
17199    && flag_unsafe_math_optimizations"
17200 {
17201   rtx op0 = gen_reg_rtx (XFmode);
17202
17203   rtx op2 = gen_reg_rtx (<MODE>mode);
17204   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17205
17206   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17207   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17208   DONE;
17209 })
17210
17211 (define_expand "asinxf2"
17212   [(set (match_dup 2)
17213         (mult:XF (match_operand:XF 1 "register_operand" "")
17214                  (match_dup 1)))
17215    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17216    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17217    (parallel [(set (match_operand:XF 0 "register_operand" "")
17218                    (unspec:XF [(match_dup 5) (match_dup 1)]
17219                               UNSPEC_FPATAN))
17220               (clobber (match_scratch:XF 6 ""))])]
17221   "TARGET_USE_FANCY_MATH_387
17222    && flag_unsafe_math_optimizations"
17223 {
17224   int i;
17225
17226   if (optimize_insn_for_size_p ())
17227     FAIL;
17228
17229   for (i = 2; i < 6; i++)
17230     operands[i] = gen_reg_rtx (XFmode);
17231
17232   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17233 })
17234
17235 (define_expand "asin<mode>2"
17236   [(use (match_operand:MODEF 0 "register_operand" ""))
17237    (use (match_operand:MODEF 1 "general_operand" ""))]
17238  "TARGET_USE_FANCY_MATH_387
17239    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17240        || TARGET_MIX_SSE_I387)
17241    && flag_unsafe_math_optimizations"
17242 {
17243   rtx op0 = gen_reg_rtx (XFmode);
17244   rtx op1 = gen_reg_rtx (XFmode);
17245
17246   if (optimize_insn_for_size_p ())
17247     FAIL;
17248
17249   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17250   emit_insn (gen_asinxf2 (op0, op1));
17251   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17252   DONE;
17253 })
17254
17255 (define_expand "acosxf2"
17256   [(set (match_dup 2)
17257         (mult:XF (match_operand:XF 1 "register_operand" "")
17258                  (match_dup 1)))
17259    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17260    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17261    (parallel [(set (match_operand:XF 0 "register_operand" "")
17262                    (unspec:XF [(match_dup 1) (match_dup 5)]
17263                               UNSPEC_FPATAN))
17264               (clobber (match_scratch:XF 6 ""))])]
17265   "TARGET_USE_FANCY_MATH_387
17266    && flag_unsafe_math_optimizations"
17267 {
17268   int i;
17269
17270   if (optimize_insn_for_size_p ())
17271     FAIL;
17272
17273   for (i = 2; i < 6; i++)
17274     operands[i] = gen_reg_rtx (XFmode);
17275
17276   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17277 })
17278
17279 (define_expand "acos<mode>2"
17280   [(use (match_operand:MODEF 0 "register_operand" ""))
17281    (use (match_operand:MODEF 1 "general_operand" ""))]
17282  "TARGET_USE_FANCY_MATH_387
17283    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17284        || TARGET_MIX_SSE_I387)
17285    && flag_unsafe_math_optimizations"
17286 {
17287   rtx op0 = gen_reg_rtx (XFmode);
17288   rtx op1 = gen_reg_rtx (XFmode);
17289
17290   if (optimize_insn_for_size_p ())
17291     FAIL;
17292
17293   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17294   emit_insn (gen_acosxf2 (op0, op1));
17295   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17296   DONE;
17297 })
17298
17299 (define_insn "fyl2xxf3_i387"
17300   [(set (match_operand:XF 0 "register_operand" "=f")
17301         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17302                     (match_operand:XF 2 "register_operand" "u")]
17303                    UNSPEC_FYL2X))
17304    (clobber (match_scratch:XF 3 "=2"))]
17305   "TARGET_USE_FANCY_MATH_387
17306    && flag_unsafe_math_optimizations"
17307   "fyl2x"
17308   [(set_attr "type" "fpspc")
17309    (set_attr "mode" "XF")])
17310
17311 (define_insn "fyl2x_extend<mode>xf3_i387"
17312   [(set (match_operand:XF 0 "register_operand" "=f")
17313         (unspec:XF [(float_extend:XF
17314                       (match_operand:MODEF 1 "register_operand" "0"))
17315                     (match_operand:XF 2 "register_operand" "u")]
17316                    UNSPEC_FYL2X))
17317    (clobber (match_scratch:XF 3 "=2"))]
17318   "TARGET_USE_FANCY_MATH_387
17319    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17320        || TARGET_MIX_SSE_I387)
17321    && flag_unsafe_math_optimizations"
17322   "fyl2x"
17323   [(set_attr "type" "fpspc")
17324    (set_attr "mode" "XF")])
17325
17326 (define_expand "logxf2"
17327   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17328                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17329                                (match_dup 2)] UNSPEC_FYL2X))
17330               (clobber (match_scratch:XF 3 ""))])]
17331   "TARGET_USE_FANCY_MATH_387
17332    && flag_unsafe_math_optimizations"
17333 {
17334   operands[2] = gen_reg_rtx (XFmode);
17335   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17336 })
17337
17338 (define_expand "log<mode>2"
17339   [(use (match_operand:MODEF 0 "register_operand" ""))
17340    (use (match_operand:MODEF 1 "register_operand" ""))]
17341   "TARGET_USE_FANCY_MATH_387
17342    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17343        || TARGET_MIX_SSE_I387)
17344    && flag_unsafe_math_optimizations"
17345 {
17346   rtx op0 = gen_reg_rtx (XFmode);
17347
17348   rtx op2 = gen_reg_rtx (XFmode);
17349   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17350
17351   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17352   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17353   DONE;
17354 })
17355
17356 (define_expand "log10xf2"
17357   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17358                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17359                                (match_dup 2)] UNSPEC_FYL2X))
17360               (clobber (match_scratch:XF 3 ""))])]
17361   "TARGET_USE_FANCY_MATH_387
17362    && flag_unsafe_math_optimizations"
17363 {
17364   operands[2] = gen_reg_rtx (XFmode);
17365   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17366 })
17367
17368 (define_expand "log10<mode>2"
17369   [(use (match_operand:MODEF 0 "register_operand" ""))
17370    (use (match_operand:MODEF 1 "register_operand" ""))]
17371   "TARGET_USE_FANCY_MATH_387
17372    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17373        || TARGET_MIX_SSE_I387)
17374    && flag_unsafe_math_optimizations"
17375 {
17376   rtx op0 = gen_reg_rtx (XFmode);
17377
17378   rtx op2 = gen_reg_rtx (XFmode);
17379   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17380
17381   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17382   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17383   DONE;
17384 })
17385
17386 (define_expand "log2xf2"
17387   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17388                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17389                                (match_dup 2)] UNSPEC_FYL2X))
17390               (clobber (match_scratch:XF 3 ""))])]
17391   "TARGET_USE_FANCY_MATH_387
17392    && flag_unsafe_math_optimizations"
17393 {
17394   operands[2] = gen_reg_rtx (XFmode);
17395   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17396 })
17397
17398 (define_expand "log2<mode>2"
17399   [(use (match_operand:MODEF 0 "register_operand" ""))
17400    (use (match_operand:MODEF 1 "register_operand" ""))]
17401   "TARGET_USE_FANCY_MATH_387
17402    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17403        || TARGET_MIX_SSE_I387)
17404    && flag_unsafe_math_optimizations"
17405 {
17406   rtx op0 = gen_reg_rtx (XFmode);
17407
17408   rtx op2 = gen_reg_rtx (XFmode);
17409   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17410
17411   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17412   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17413   DONE;
17414 })
17415
17416 (define_insn "fyl2xp1xf3_i387"
17417   [(set (match_operand:XF 0 "register_operand" "=f")
17418         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17419                     (match_operand:XF 2 "register_operand" "u")]
17420                    UNSPEC_FYL2XP1))
17421    (clobber (match_scratch:XF 3 "=2"))]
17422   "TARGET_USE_FANCY_MATH_387
17423    && flag_unsafe_math_optimizations"
17424   "fyl2xp1"
17425   [(set_attr "type" "fpspc")
17426    (set_attr "mode" "XF")])
17427
17428 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17429   [(set (match_operand:XF 0 "register_operand" "=f")
17430         (unspec:XF [(float_extend:XF
17431                       (match_operand:MODEF 1 "register_operand" "0"))
17432                     (match_operand:XF 2 "register_operand" "u")]
17433                    UNSPEC_FYL2XP1))
17434    (clobber (match_scratch:XF 3 "=2"))]
17435   "TARGET_USE_FANCY_MATH_387
17436    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17437        || TARGET_MIX_SSE_I387)
17438    && flag_unsafe_math_optimizations"
17439   "fyl2xp1"
17440   [(set_attr "type" "fpspc")
17441    (set_attr "mode" "XF")])
17442
17443 (define_expand "log1pxf2"
17444   [(use (match_operand:XF 0 "register_operand" ""))
17445    (use (match_operand:XF 1 "register_operand" ""))]
17446   "TARGET_USE_FANCY_MATH_387
17447    && flag_unsafe_math_optimizations"
17448 {
17449   if (optimize_insn_for_size_p ())
17450     FAIL;
17451
17452   ix86_emit_i387_log1p (operands[0], operands[1]);
17453   DONE;
17454 })
17455
17456 (define_expand "log1p<mode>2"
17457   [(use (match_operand:MODEF 0 "register_operand" ""))
17458    (use (match_operand:MODEF 1 "register_operand" ""))]
17459   "TARGET_USE_FANCY_MATH_387
17460    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17461        || TARGET_MIX_SSE_I387)
17462    && flag_unsafe_math_optimizations"
17463 {
17464   rtx op0;
17465
17466   if (optimize_insn_for_size_p ())
17467     FAIL;
17468
17469   op0 = gen_reg_rtx (XFmode);
17470
17471   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17472
17473   ix86_emit_i387_log1p (op0, operands[1]);
17474   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17475   DONE;
17476 })
17477
17478 (define_insn "fxtractxf3_i387"
17479   [(set (match_operand:XF 0 "register_operand" "=f")
17480         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17481                    UNSPEC_XTRACT_FRACT))
17482    (set (match_operand:XF 1 "register_operand" "=u")
17483         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17484   "TARGET_USE_FANCY_MATH_387
17485    && flag_unsafe_math_optimizations"
17486   "fxtract"
17487   [(set_attr "type" "fpspc")
17488    (set_attr "mode" "XF")])
17489
17490 (define_insn "fxtract_extend<mode>xf3_i387"
17491   [(set (match_operand:XF 0 "register_operand" "=f")
17492         (unspec:XF [(float_extend:XF
17493                       (match_operand:MODEF 2 "register_operand" "0"))]
17494                    UNSPEC_XTRACT_FRACT))
17495    (set (match_operand:XF 1 "register_operand" "=u")
17496         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17497   "TARGET_USE_FANCY_MATH_387
17498    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17499        || TARGET_MIX_SSE_I387)
17500    && flag_unsafe_math_optimizations"
17501   "fxtract"
17502   [(set_attr "type" "fpspc")
17503    (set_attr "mode" "XF")])
17504
17505 (define_expand "logbxf2"
17506   [(parallel [(set (match_dup 2)
17507                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17508                               UNSPEC_XTRACT_FRACT))
17509               (set (match_operand:XF 0 "register_operand" "")
17510                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17511   "TARGET_USE_FANCY_MATH_387
17512    && flag_unsafe_math_optimizations"
17513 {
17514   operands[2] = gen_reg_rtx (XFmode);
17515 })
17516
17517 (define_expand "logb<mode>2"
17518   [(use (match_operand:MODEF 0 "register_operand" ""))
17519    (use (match_operand:MODEF 1 "register_operand" ""))]
17520   "TARGET_USE_FANCY_MATH_387
17521    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17522        || TARGET_MIX_SSE_I387)
17523    && flag_unsafe_math_optimizations"
17524 {
17525   rtx op0 = gen_reg_rtx (XFmode);
17526   rtx op1 = gen_reg_rtx (XFmode);
17527
17528   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17529   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17530   DONE;
17531 })
17532
17533 (define_expand "ilogbxf2"
17534   [(use (match_operand:SI 0 "register_operand" ""))
17535    (use (match_operand:XF 1 "register_operand" ""))]
17536   "TARGET_USE_FANCY_MATH_387
17537    && flag_unsafe_math_optimizations"
17538 {
17539   rtx op0, op1;
17540
17541   if (optimize_insn_for_size_p ())
17542     FAIL;
17543
17544   op0 = gen_reg_rtx (XFmode);
17545   op1 = gen_reg_rtx (XFmode);
17546
17547   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17548   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17549   DONE;
17550 })
17551
17552 (define_expand "ilogb<mode>2"
17553   [(use (match_operand:SI 0 "register_operand" ""))
17554    (use (match_operand:MODEF 1 "register_operand" ""))]
17555   "TARGET_USE_FANCY_MATH_387
17556    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17557        || TARGET_MIX_SSE_I387)
17558    && flag_unsafe_math_optimizations"
17559 {
17560   rtx op0, op1;
17561
17562   if (optimize_insn_for_size_p ())
17563     FAIL;
17564
17565   op0 = gen_reg_rtx (XFmode);
17566   op1 = gen_reg_rtx (XFmode);
17567
17568   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17569   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17570   DONE;
17571 })
17572
17573 (define_insn "*f2xm1xf2_i387"
17574   [(set (match_operand:XF 0 "register_operand" "=f")
17575         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17576                    UNSPEC_F2XM1))]
17577   "TARGET_USE_FANCY_MATH_387
17578    && flag_unsafe_math_optimizations"
17579   "f2xm1"
17580   [(set_attr "type" "fpspc")
17581    (set_attr "mode" "XF")])
17582
17583 (define_insn "*fscalexf4_i387"
17584   [(set (match_operand:XF 0 "register_operand" "=f")
17585         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17586                     (match_operand:XF 3 "register_operand" "1")]
17587                    UNSPEC_FSCALE_FRACT))
17588    (set (match_operand:XF 1 "register_operand" "=u")
17589         (unspec:XF [(match_dup 2) (match_dup 3)]
17590                    UNSPEC_FSCALE_EXP))]
17591   "TARGET_USE_FANCY_MATH_387
17592    && flag_unsafe_math_optimizations"
17593   "fscale"
17594   [(set_attr "type" "fpspc")
17595    (set_attr "mode" "XF")])
17596
17597 (define_expand "expNcorexf3"
17598   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17599                                (match_operand:XF 2 "register_operand" "")))
17600    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17601    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17602    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17603    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17604    (parallel [(set (match_operand:XF 0 "register_operand" "")
17605                    (unspec:XF [(match_dup 8) (match_dup 4)]
17606                               UNSPEC_FSCALE_FRACT))
17607               (set (match_dup 9)
17608                    (unspec:XF [(match_dup 8) (match_dup 4)]
17609                               UNSPEC_FSCALE_EXP))])]
17610   "TARGET_USE_FANCY_MATH_387
17611    && flag_unsafe_math_optimizations"
17612 {
17613   int i;
17614
17615   if (optimize_insn_for_size_p ())
17616     FAIL;
17617
17618   for (i = 3; i < 10; i++)
17619     operands[i] = gen_reg_rtx (XFmode);
17620
17621   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17622 })
17623
17624 (define_expand "expxf2"
17625   [(use (match_operand:XF 0 "register_operand" ""))
17626    (use (match_operand:XF 1 "register_operand" ""))]
17627   "TARGET_USE_FANCY_MATH_387
17628    && flag_unsafe_math_optimizations"
17629 {
17630   rtx op2;
17631
17632   if (optimize_insn_for_size_p ())
17633     FAIL;
17634
17635   op2 = gen_reg_rtx (XFmode);
17636   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17637
17638   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17639   DONE;
17640 })
17641
17642 (define_expand "exp<mode>2"
17643   [(use (match_operand:MODEF 0 "register_operand" ""))
17644    (use (match_operand:MODEF 1 "general_operand" ""))]
17645  "TARGET_USE_FANCY_MATH_387
17646    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17647        || TARGET_MIX_SSE_I387)
17648    && flag_unsafe_math_optimizations"
17649 {
17650   rtx op0, op1;
17651
17652   if (optimize_insn_for_size_p ())
17653     FAIL;
17654
17655   op0 = gen_reg_rtx (XFmode);
17656   op1 = gen_reg_rtx (XFmode);
17657
17658   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17659   emit_insn (gen_expxf2 (op0, op1));
17660   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17661   DONE;
17662 })
17663
17664 (define_expand "exp10xf2"
17665   [(use (match_operand:XF 0 "register_operand" ""))
17666    (use (match_operand:XF 1 "register_operand" ""))]
17667   "TARGET_USE_FANCY_MATH_387
17668    && flag_unsafe_math_optimizations"
17669 {
17670   rtx op2;
17671
17672   if (optimize_insn_for_size_p ())
17673     FAIL;
17674
17675   op2 = gen_reg_rtx (XFmode);
17676   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17677
17678   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17679   DONE;
17680 })
17681
17682 (define_expand "exp10<mode>2"
17683   [(use (match_operand:MODEF 0 "register_operand" ""))
17684    (use (match_operand:MODEF 1 "general_operand" ""))]
17685  "TARGET_USE_FANCY_MATH_387
17686    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17687        || TARGET_MIX_SSE_I387)
17688    && flag_unsafe_math_optimizations"
17689 {
17690   rtx op0, op1;
17691
17692   if (optimize_insn_for_size_p ())
17693     FAIL;
17694
17695   op0 = gen_reg_rtx (XFmode);
17696   op1 = gen_reg_rtx (XFmode);
17697
17698   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17699   emit_insn (gen_exp10xf2 (op0, op1));
17700   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17701   DONE;
17702 })
17703
17704 (define_expand "exp2xf2"
17705   [(use (match_operand:XF 0 "register_operand" ""))
17706    (use (match_operand:XF 1 "register_operand" ""))]
17707   "TARGET_USE_FANCY_MATH_387
17708    && flag_unsafe_math_optimizations"
17709 {
17710   rtx op2;
17711
17712   if (optimize_insn_for_size_p ())
17713     FAIL;
17714
17715   op2 = gen_reg_rtx (XFmode);
17716   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17717
17718   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17719   DONE;
17720 })
17721
17722 (define_expand "exp2<mode>2"
17723   [(use (match_operand:MODEF 0 "register_operand" ""))
17724    (use (match_operand:MODEF 1 "general_operand" ""))]
17725  "TARGET_USE_FANCY_MATH_387
17726    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17727        || TARGET_MIX_SSE_I387)
17728    && flag_unsafe_math_optimizations"
17729 {
17730   rtx op0, op1;
17731
17732   if (optimize_insn_for_size_p ())
17733     FAIL;
17734
17735   op0 = gen_reg_rtx (XFmode);
17736   op1 = gen_reg_rtx (XFmode);
17737
17738   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17739   emit_insn (gen_exp2xf2 (op0, op1));
17740   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17741   DONE;
17742 })
17743
17744 (define_expand "expm1xf2"
17745   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17746                                (match_dup 2)))
17747    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17748    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17749    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17750    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17751    (parallel [(set (match_dup 7)
17752                    (unspec:XF [(match_dup 6) (match_dup 4)]
17753                               UNSPEC_FSCALE_FRACT))
17754               (set (match_dup 8)
17755                    (unspec:XF [(match_dup 6) (match_dup 4)]
17756                               UNSPEC_FSCALE_EXP))])
17757    (parallel [(set (match_dup 10)
17758                    (unspec:XF [(match_dup 9) (match_dup 8)]
17759                               UNSPEC_FSCALE_FRACT))
17760               (set (match_dup 11)
17761                    (unspec:XF [(match_dup 9) (match_dup 8)]
17762                               UNSPEC_FSCALE_EXP))])
17763    (set (match_dup 12) (minus:XF (match_dup 10)
17764                                  (float_extend:XF (match_dup 13))))
17765    (set (match_operand:XF 0 "register_operand" "")
17766         (plus:XF (match_dup 12) (match_dup 7)))]
17767   "TARGET_USE_FANCY_MATH_387
17768    && flag_unsafe_math_optimizations"
17769 {
17770   int i;
17771
17772   if (optimize_insn_for_size_p ())
17773     FAIL;
17774
17775   for (i = 2; i < 13; i++)
17776     operands[i] = gen_reg_rtx (XFmode);
17777
17778   operands[13]
17779     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17780
17781   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17782 })
17783
17784 (define_expand "expm1<mode>2"
17785   [(use (match_operand:MODEF 0 "register_operand" ""))
17786    (use (match_operand:MODEF 1 "general_operand" ""))]
17787  "TARGET_USE_FANCY_MATH_387
17788    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17789        || TARGET_MIX_SSE_I387)
17790    && flag_unsafe_math_optimizations"
17791 {
17792   rtx op0, op1;
17793
17794   if (optimize_insn_for_size_p ())
17795     FAIL;
17796
17797   op0 = gen_reg_rtx (XFmode);
17798   op1 = gen_reg_rtx (XFmode);
17799
17800   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17801   emit_insn (gen_expm1xf2 (op0, op1));
17802   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17803   DONE;
17804 })
17805
17806 (define_expand "ldexpxf3"
17807   [(set (match_dup 3)
17808         (float:XF (match_operand:SI 2 "register_operand" "")))
17809    (parallel [(set (match_operand:XF 0 " register_operand" "")
17810                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17811                                (match_dup 3)]
17812                               UNSPEC_FSCALE_FRACT))
17813               (set (match_dup 4)
17814                    (unspec:XF [(match_dup 1) (match_dup 3)]
17815                               UNSPEC_FSCALE_EXP))])]
17816   "TARGET_USE_FANCY_MATH_387
17817    && flag_unsafe_math_optimizations"
17818 {
17819   if (optimize_insn_for_size_p ())
17820     FAIL;
17821
17822   operands[3] = gen_reg_rtx (XFmode);
17823   operands[4] = gen_reg_rtx (XFmode);
17824 })
17825
17826 (define_expand "ldexp<mode>3"
17827   [(use (match_operand:MODEF 0 "register_operand" ""))
17828    (use (match_operand:MODEF 1 "general_operand" ""))
17829    (use (match_operand:SI 2 "register_operand" ""))]
17830  "TARGET_USE_FANCY_MATH_387
17831    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17832        || TARGET_MIX_SSE_I387)
17833    && flag_unsafe_math_optimizations"
17834 {
17835   rtx op0, op1;
17836
17837   if (optimize_insn_for_size_p ())
17838     FAIL;
17839
17840   op0 = gen_reg_rtx (XFmode);
17841   op1 = gen_reg_rtx (XFmode);
17842
17843   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17844   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17845   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17846   DONE;
17847 })
17848
17849 (define_expand "scalbxf3"
17850   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17851                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17852                                (match_operand:XF 2 "register_operand" "")]
17853                               UNSPEC_FSCALE_FRACT))
17854               (set (match_dup 3)
17855                    (unspec:XF [(match_dup 1) (match_dup 2)]
17856                               UNSPEC_FSCALE_EXP))])]
17857   "TARGET_USE_FANCY_MATH_387
17858    && flag_unsafe_math_optimizations"
17859 {
17860   if (optimize_insn_for_size_p ())
17861     FAIL;
17862
17863   operands[3] = gen_reg_rtx (XFmode);
17864 })
17865
17866 (define_expand "scalb<mode>3"
17867   [(use (match_operand:MODEF 0 "register_operand" ""))
17868    (use (match_operand:MODEF 1 "general_operand" ""))
17869    (use (match_operand:MODEF 2 "register_operand" ""))]
17870  "TARGET_USE_FANCY_MATH_387
17871    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17872        || TARGET_MIX_SSE_I387)
17873    && flag_unsafe_math_optimizations"
17874 {
17875   rtx op0, op1, op2;
17876
17877   if (optimize_insn_for_size_p ())
17878     FAIL;
17879
17880   op0 = gen_reg_rtx (XFmode);
17881   op1 = gen_reg_rtx (XFmode);
17882   op2 = gen_reg_rtx (XFmode);
17883
17884   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17885   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17886   emit_insn (gen_scalbxf3 (op0, op1, op2));
17887   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17888   DONE;
17889 })
17890 \f
17891
17892 (define_insn "sse4_1_round<mode>2"
17893   [(set (match_operand:MODEF 0 "register_operand" "=x")
17894         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17895                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17896                       UNSPEC_ROUND))]
17897   "TARGET_ROUND"
17898   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17899   [(set_attr "type" "ssecvt")
17900    (set_attr "prefix_extra" "1")
17901    (set_attr "prefix" "maybe_vex")
17902    (set_attr "mode" "<MODE>")])
17903
17904 (define_insn "rintxf2"
17905   [(set (match_operand:XF 0 "register_operand" "=f")
17906         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17907                    UNSPEC_FRNDINT))]
17908   "TARGET_USE_FANCY_MATH_387
17909    && flag_unsafe_math_optimizations"
17910   "frndint"
17911   [(set_attr "type" "fpspc")
17912    (set_attr "mode" "XF")])
17913
17914 (define_expand "rint<mode>2"
17915   [(use (match_operand:MODEF 0 "register_operand" ""))
17916    (use (match_operand:MODEF 1 "register_operand" ""))]
17917   "(TARGET_USE_FANCY_MATH_387
17918     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17919         || TARGET_MIX_SSE_I387)
17920     && flag_unsafe_math_optimizations)
17921    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17922        && !flag_trapping_math)"
17923 {
17924   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17925       && !flag_trapping_math)
17926     {
17927       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17928         FAIL;
17929       if (TARGET_ROUND)
17930         emit_insn (gen_sse4_1_round<mode>2
17931                    (operands[0], operands[1], GEN_INT (0x04)));
17932       else
17933         ix86_expand_rint (operand0, operand1);
17934     }
17935   else
17936     {
17937       rtx op0 = gen_reg_rtx (XFmode);
17938       rtx op1 = gen_reg_rtx (XFmode);
17939
17940       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17941       emit_insn (gen_rintxf2 (op0, op1));
17942
17943       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17944     }
17945   DONE;
17946 })
17947
17948 (define_expand "round<mode>2"
17949   [(match_operand:MODEF 0 "register_operand" "")
17950    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17951   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17952    && !flag_trapping_math && !flag_rounding_math"
17953 {
17954   if (optimize_insn_for_size_p ())
17955     FAIL;
17956   if (TARGET_64BIT || (<MODE>mode != DFmode))
17957     ix86_expand_round (operand0, operand1);
17958   else
17959     ix86_expand_rounddf_32 (operand0, operand1);
17960   DONE;
17961 })
17962
17963 (define_insn_and_split "*fistdi2_1"
17964   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17965         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17966                    UNSPEC_FIST))]
17967   "TARGET_USE_FANCY_MATH_387
17968    && !(reload_completed || reload_in_progress)"
17969   "#"
17970   "&& 1"
17971   [(const_int 0)]
17972 {
17973   if (memory_operand (operands[0], VOIDmode))
17974     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17975   else
17976     {
17977       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17978       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17979                                          operands[2]));
17980     }
17981   DONE;
17982 }
17983   [(set_attr "type" "fpspc")
17984    (set_attr "mode" "DI")])
17985
17986 (define_insn "fistdi2"
17987   [(set (match_operand:DI 0 "memory_operand" "=m")
17988         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17989                    UNSPEC_FIST))
17990    (clobber (match_scratch:XF 2 "=&1f"))]
17991   "TARGET_USE_FANCY_MATH_387"
17992   "* return output_fix_trunc (insn, operands, 0);"
17993   [(set_attr "type" "fpspc")
17994    (set_attr "mode" "DI")])
17995
17996 (define_insn "fistdi2_with_temp"
17997   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17998         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17999                    UNSPEC_FIST))
18000    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18001    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18002   "TARGET_USE_FANCY_MATH_387"
18003   "#"
18004   [(set_attr "type" "fpspc")
18005    (set_attr "mode" "DI")])
18006
18007 (define_split
18008   [(set (match_operand:DI 0 "register_operand" "")
18009         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18010                    UNSPEC_FIST))
18011    (clobber (match_operand:DI 2 "memory_operand" ""))
18012    (clobber (match_scratch 3 ""))]
18013   "reload_completed"
18014   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18015               (clobber (match_dup 3))])
18016    (set (match_dup 0) (match_dup 2))]
18017   "")
18018
18019 (define_split
18020   [(set (match_operand:DI 0 "memory_operand" "")
18021         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18022                    UNSPEC_FIST))
18023    (clobber (match_operand:DI 2 "memory_operand" ""))
18024    (clobber (match_scratch 3 ""))]
18025   "reload_completed"
18026   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18027               (clobber (match_dup 3))])]
18028   "")
18029
18030 (define_insn_and_split "*fist<mode>2_1"
18031   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18032         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18033                            UNSPEC_FIST))]
18034   "TARGET_USE_FANCY_MATH_387
18035    && !(reload_completed || reload_in_progress)"
18036   "#"
18037   "&& 1"
18038   [(const_int 0)]
18039 {
18040   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18041   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18042                                         operands[2]));
18043   DONE;
18044 }
18045   [(set_attr "type" "fpspc")
18046    (set_attr "mode" "<MODE>")])
18047
18048 (define_insn "fist<mode>2"
18049   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18050         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18051                            UNSPEC_FIST))]
18052   "TARGET_USE_FANCY_MATH_387"
18053   "* return output_fix_trunc (insn, operands, 0);"
18054   [(set_attr "type" "fpspc")
18055    (set_attr "mode" "<MODE>")])
18056
18057 (define_insn "fist<mode>2_with_temp"
18058   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18059         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18060                            UNSPEC_FIST))
18061    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18062   "TARGET_USE_FANCY_MATH_387"
18063   "#"
18064   [(set_attr "type" "fpspc")
18065    (set_attr "mode" "<MODE>")])
18066
18067 (define_split
18068   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18069         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18070                            UNSPEC_FIST))
18071    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18072   "reload_completed"
18073   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18074    (set (match_dup 0) (match_dup 2))]
18075   "")
18076
18077 (define_split
18078   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18079         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18080                            UNSPEC_FIST))
18081    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18082   "reload_completed"
18083   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18084   "")
18085
18086 (define_expand "lrintxf<mode>2"
18087   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18088      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18089                       UNSPEC_FIST))]
18090   "TARGET_USE_FANCY_MATH_387"
18091   "")
18092
18093 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18094   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18095      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18096                         UNSPEC_FIX_NOTRUNC))]
18097   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18098    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18099   "")
18100
18101 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18102   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18103    (match_operand:MODEF 1 "register_operand" "")]
18104   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18105    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18106    && !flag_trapping_math && !flag_rounding_math"
18107 {
18108   if (optimize_insn_for_size_p ())
18109     FAIL;
18110   ix86_expand_lround (operand0, operand1);
18111   DONE;
18112 })
18113
18114 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18115 (define_insn_and_split "frndintxf2_floor"
18116   [(set (match_operand:XF 0 "register_operand" "")
18117         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18118          UNSPEC_FRNDINT_FLOOR))
18119    (clobber (reg:CC FLAGS_REG))]
18120   "TARGET_USE_FANCY_MATH_387
18121    && flag_unsafe_math_optimizations
18122    && !(reload_completed || reload_in_progress)"
18123   "#"
18124   "&& 1"
18125   [(const_int 0)]
18126 {
18127   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18128
18129   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18130   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18131
18132   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18133                                         operands[2], operands[3]));
18134   DONE;
18135 }
18136   [(set_attr "type" "frndint")
18137    (set_attr "i387_cw" "floor")
18138    (set_attr "mode" "XF")])
18139
18140 (define_insn "frndintxf2_floor_i387"
18141   [(set (match_operand:XF 0 "register_operand" "=f")
18142         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18143          UNSPEC_FRNDINT_FLOOR))
18144    (use (match_operand:HI 2 "memory_operand" "m"))
18145    (use (match_operand:HI 3 "memory_operand" "m"))]
18146   "TARGET_USE_FANCY_MATH_387
18147    && flag_unsafe_math_optimizations"
18148   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18149   [(set_attr "type" "frndint")
18150    (set_attr "i387_cw" "floor")
18151    (set_attr "mode" "XF")])
18152
18153 (define_expand "floorxf2"
18154   [(use (match_operand:XF 0 "register_operand" ""))
18155    (use (match_operand:XF 1 "register_operand" ""))]
18156   "TARGET_USE_FANCY_MATH_387
18157    && flag_unsafe_math_optimizations"
18158 {
18159   if (optimize_insn_for_size_p ())
18160     FAIL;
18161   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18162   DONE;
18163 })
18164
18165 (define_expand "floor<mode>2"
18166   [(use (match_operand:MODEF 0 "register_operand" ""))
18167    (use (match_operand:MODEF 1 "register_operand" ""))]
18168   "(TARGET_USE_FANCY_MATH_387
18169     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18170         || TARGET_MIX_SSE_I387)
18171     && flag_unsafe_math_optimizations)
18172    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18173        && !flag_trapping_math)"
18174 {
18175   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18176       && !flag_trapping_math
18177       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18178     {
18179       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18180         FAIL;
18181       if (TARGET_ROUND)
18182         emit_insn (gen_sse4_1_round<mode>2
18183                    (operands[0], operands[1], GEN_INT (0x01)));
18184       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18185         ix86_expand_floorceil (operand0, operand1, true);
18186       else
18187         ix86_expand_floorceildf_32 (operand0, operand1, true);
18188     }
18189   else
18190     {
18191       rtx op0, op1;
18192
18193       if (optimize_insn_for_size_p ())
18194         FAIL;
18195
18196       op0 = gen_reg_rtx (XFmode);
18197       op1 = gen_reg_rtx (XFmode);
18198       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18199       emit_insn (gen_frndintxf2_floor (op0, op1));
18200
18201       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18202     }
18203   DONE;
18204 })
18205
18206 (define_insn_and_split "*fist<mode>2_floor_1"
18207   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18208         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18209          UNSPEC_FIST_FLOOR))
18210    (clobber (reg:CC FLAGS_REG))]
18211   "TARGET_USE_FANCY_MATH_387
18212    && flag_unsafe_math_optimizations
18213    && !(reload_completed || reload_in_progress)"
18214   "#"
18215   "&& 1"
18216   [(const_int 0)]
18217 {
18218   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18219
18220   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18221   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18222   if (memory_operand (operands[0], VOIDmode))
18223     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18224                                       operands[2], operands[3]));
18225   else
18226     {
18227       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18228       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18229                                                   operands[2], operands[3],
18230                                                   operands[4]));
18231     }
18232   DONE;
18233 }
18234   [(set_attr "type" "fistp")
18235    (set_attr "i387_cw" "floor")
18236    (set_attr "mode" "<MODE>")])
18237
18238 (define_insn "fistdi2_floor"
18239   [(set (match_operand:DI 0 "memory_operand" "=m")
18240         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18241          UNSPEC_FIST_FLOOR))
18242    (use (match_operand:HI 2 "memory_operand" "m"))
18243    (use (match_operand:HI 3 "memory_operand" "m"))
18244    (clobber (match_scratch:XF 4 "=&1f"))]
18245   "TARGET_USE_FANCY_MATH_387
18246    && flag_unsafe_math_optimizations"
18247   "* return output_fix_trunc (insn, operands, 0);"
18248   [(set_attr "type" "fistp")
18249    (set_attr "i387_cw" "floor")
18250    (set_attr "mode" "DI")])
18251
18252 (define_insn "fistdi2_floor_with_temp"
18253   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18254         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18255          UNSPEC_FIST_FLOOR))
18256    (use (match_operand:HI 2 "memory_operand" "m,m"))
18257    (use (match_operand:HI 3 "memory_operand" "m,m"))
18258    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18259    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18260   "TARGET_USE_FANCY_MATH_387
18261    && flag_unsafe_math_optimizations"
18262   "#"
18263   [(set_attr "type" "fistp")
18264    (set_attr "i387_cw" "floor")
18265    (set_attr "mode" "DI")])
18266
18267 (define_split
18268   [(set (match_operand:DI 0 "register_operand" "")
18269         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18270          UNSPEC_FIST_FLOOR))
18271    (use (match_operand:HI 2 "memory_operand" ""))
18272    (use (match_operand:HI 3 "memory_operand" ""))
18273    (clobber (match_operand:DI 4 "memory_operand" ""))
18274    (clobber (match_scratch 5 ""))]
18275   "reload_completed"
18276   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18277               (use (match_dup 2))
18278               (use (match_dup 3))
18279               (clobber (match_dup 5))])
18280    (set (match_dup 0) (match_dup 4))]
18281   "")
18282
18283 (define_split
18284   [(set (match_operand:DI 0 "memory_operand" "")
18285         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18286          UNSPEC_FIST_FLOOR))
18287    (use (match_operand:HI 2 "memory_operand" ""))
18288    (use (match_operand:HI 3 "memory_operand" ""))
18289    (clobber (match_operand:DI 4 "memory_operand" ""))
18290    (clobber (match_scratch 5 ""))]
18291   "reload_completed"
18292   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18293               (use (match_dup 2))
18294               (use (match_dup 3))
18295               (clobber (match_dup 5))])]
18296   "")
18297
18298 (define_insn "fist<mode>2_floor"
18299   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18300         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18301          UNSPEC_FIST_FLOOR))
18302    (use (match_operand:HI 2 "memory_operand" "m"))
18303    (use (match_operand:HI 3 "memory_operand" "m"))]
18304   "TARGET_USE_FANCY_MATH_387
18305    && flag_unsafe_math_optimizations"
18306   "* return output_fix_trunc (insn, operands, 0);"
18307   [(set_attr "type" "fistp")
18308    (set_attr "i387_cw" "floor")
18309    (set_attr "mode" "<MODE>")])
18310
18311 (define_insn "fist<mode>2_floor_with_temp"
18312   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18313         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18314          UNSPEC_FIST_FLOOR))
18315    (use (match_operand:HI 2 "memory_operand" "m,m"))
18316    (use (match_operand:HI 3 "memory_operand" "m,m"))
18317    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18318   "TARGET_USE_FANCY_MATH_387
18319    && flag_unsafe_math_optimizations"
18320   "#"
18321   [(set_attr "type" "fistp")
18322    (set_attr "i387_cw" "floor")
18323    (set_attr "mode" "<MODE>")])
18324
18325 (define_split
18326   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18327         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18328          UNSPEC_FIST_FLOOR))
18329    (use (match_operand:HI 2 "memory_operand" ""))
18330    (use (match_operand:HI 3 "memory_operand" ""))
18331    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18332   "reload_completed"
18333   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18334                                   UNSPEC_FIST_FLOOR))
18335               (use (match_dup 2))
18336               (use (match_dup 3))])
18337    (set (match_dup 0) (match_dup 4))]
18338   "")
18339
18340 (define_split
18341   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18342         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18343          UNSPEC_FIST_FLOOR))
18344    (use (match_operand:HI 2 "memory_operand" ""))
18345    (use (match_operand:HI 3 "memory_operand" ""))
18346    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18347   "reload_completed"
18348   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18349                                   UNSPEC_FIST_FLOOR))
18350               (use (match_dup 2))
18351               (use (match_dup 3))])]
18352   "")
18353
18354 (define_expand "lfloorxf<mode>2"
18355   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18356                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18357                     UNSPEC_FIST_FLOOR))
18358               (clobber (reg:CC FLAGS_REG))])]
18359   "TARGET_USE_FANCY_MATH_387
18360    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18361    && flag_unsafe_math_optimizations"
18362   "")
18363
18364 (define_expand "lfloor<mode>di2"
18365   [(match_operand:DI 0 "nonimmediate_operand" "")
18366    (match_operand:MODEF 1 "register_operand" "")]
18367   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18368    && !flag_trapping_math"
18369 {
18370   if (optimize_insn_for_size_p ())
18371     FAIL;
18372   ix86_expand_lfloorceil (operand0, operand1, true);
18373   DONE;
18374 })
18375
18376 (define_expand "lfloor<mode>si2"
18377   [(match_operand:SI 0 "nonimmediate_operand" "")
18378    (match_operand:MODEF 1 "register_operand" "")]
18379   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18380    && !flag_trapping_math"
18381 {
18382   if (optimize_insn_for_size_p () && TARGET_64BIT)
18383     FAIL;
18384   ix86_expand_lfloorceil (operand0, operand1, true);
18385   DONE;
18386 })
18387
18388 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18389 (define_insn_and_split "frndintxf2_ceil"
18390   [(set (match_operand:XF 0 "register_operand" "")
18391         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18392          UNSPEC_FRNDINT_CEIL))
18393    (clobber (reg:CC FLAGS_REG))]
18394   "TARGET_USE_FANCY_MATH_387
18395    && flag_unsafe_math_optimizations
18396    && !(reload_completed || reload_in_progress)"
18397   "#"
18398   "&& 1"
18399   [(const_int 0)]
18400 {
18401   ix86_optimize_mode_switching[I387_CEIL] = 1;
18402
18403   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18404   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18405
18406   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18407                                        operands[2], operands[3]));
18408   DONE;
18409 }
18410   [(set_attr "type" "frndint")
18411    (set_attr "i387_cw" "ceil")
18412    (set_attr "mode" "XF")])
18413
18414 (define_insn "frndintxf2_ceil_i387"
18415   [(set (match_operand:XF 0 "register_operand" "=f")
18416         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18417          UNSPEC_FRNDINT_CEIL))
18418    (use (match_operand:HI 2 "memory_operand" "m"))
18419    (use (match_operand:HI 3 "memory_operand" "m"))]
18420   "TARGET_USE_FANCY_MATH_387
18421    && flag_unsafe_math_optimizations"
18422   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18423   [(set_attr "type" "frndint")
18424    (set_attr "i387_cw" "ceil")
18425    (set_attr "mode" "XF")])
18426
18427 (define_expand "ceilxf2"
18428   [(use (match_operand:XF 0 "register_operand" ""))
18429    (use (match_operand:XF 1 "register_operand" ""))]
18430   "TARGET_USE_FANCY_MATH_387
18431    && flag_unsafe_math_optimizations"
18432 {
18433   if (optimize_insn_for_size_p ())
18434     FAIL;
18435   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18436   DONE;
18437 })
18438
18439 (define_expand "ceil<mode>2"
18440   [(use (match_operand:MODEF 0 "register_operand" ""))
18441    (use (match_operand:MODEF 1 "register_operand" ""))]
18442   "(TARGET_USE_FANCY_MATH_387
18443     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18444         || TARGET_MIX_SSE_I387)
18445     && flag_unsafe_math_optimizations)
18446    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18447        && !flag_trapping_math)"
18448 {
18449   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18450       && !flag_trapping_math
18451       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18452     {
18453       if (TARGET_ROUND)
18454         emit_insn (gen_sse4_1_round<mode>2
18455                    (operands[0], operands[1], GEN_INT (0x02)));
18456       else if (optimize_insn_for_size_p ())
18457         FAIL;
18458       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18459         ix86_expand_floorceil (operand0, operand1, false);
18460       else
18461         ix86_expand_floorceildf_32 (operand0, operand1, false);
18462     }
18463   else
18464     {
18465       rtx op0, op1;
18466
18467       if (optimize_insn_for_size_p ())
18468         FAIL;
18469
18470       op0 = gen_reg_rtx (XFmode);
18471       op1 = gen_reg_rtx (XFmode);
18472       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18473       emit_insn (gen_frndintxf2_ceil (op0, op1));
18474
18475       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18476     }
18477   DONE;
18478 })
18479
18480 (define_insn_and_split "*fist<mode>2_ceil_1"
18481   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18482         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18483          UNSPEC_FIST_CEIL))
18484    (clobber (reg:CC FLAGS_REG))]
18485   "TARGET_USE_FANCY_MATH_387
18486    && flag_unsafe_math_optimizations
18487    && !(reload_completed || reload_in_progress)"
18488   "#"
18489   "&& 1"
18490   [(const_int 0)]
18491 {
18492   ix86_optimize_mode_switching[I387_CEIL] = 1;
18493
18494   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18495   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18496   if (memory_operand (operands[0], VOIDmode))
18497     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18498                                      operands[2], operands[3]));
18499   else
18500     {
18501       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18502       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18503                                                  operands[2], operands[3],
18504                                                  operands[4]));
18505     }
18506   DONE;
18507 }
18508   [(set_attr "type" "fistp")
18509    (set_attr "i387_cw" "ceil")
18510    (set_attr "mode" "<MODE>")])
18511
18512 (define_insn "fistdi2_ceil"
18513   [(set (match_operand:DI 0 "memory_operand" "=m")
18514         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18515          UNSPEC_FIST_CEIL))
18516    (use (match_operand:HI 2 "memory_operand" "m"))
18517    (use (match_operand:HI 3 "memory_operand" "m"))
18518    (clobber (match_scratch:XF 4 "=&1f"))]
18519   "TARGET_USE_FANCY_MATH_387
18520    && flag_unsafe_math_optimizations"
18521   "* return output_fix_trunc (insn, operands, 0);"
18522   [(set_attr "type" "fistp")
18523    (set_attr "i387_cw" "ceil")
18524    (set_attr "mode" "DI")])
18525
18526 (define_insn "fistdi2_ceil_with_temp"
18527   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18528         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18529          UNSPEC_FIST_CEIL))
18530    (use (match_operand:HI 2 "memory_operand" "m,m"))
18531    (use (match_operand:HI 3 "memory_operand" "m,m"))
18532    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18533    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18534   "TARGET_USE_FANCY_MATH_387
18535    && flag_unsafe_math_optimizations"
18536   "#"
18537   [(set_attr "type" "fistp")
18538    (set_attr "i387_cw" "ceil")
18539    (set_attr "mode" "DI")])
18540
18541 (define_split
18542   [(set (match_operand:DI 0 "register_operand" "")
18543         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18544          UNSPEC_FIST_CEIL))
18545    (use (match_operand:HI 2 "memory_operand" ""))
18546    (use (match_operand:HI 3 "memory_operand" ""))
18547    (clobber (match_operand:DI 4 "memory_operand" ""))
18548    (clobber (match_scratch 5 ""))]
18549   "reload_completed"
18550   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18551               (use (match_dup 2))
18552               (use (match_dup 3))
18553               (clobber (match_dup 5))])
18554    (set (match_dup 0) (match_dup 4))]
18555   "")
18556
18557 (define_split
18558   [(set (match_operand:DI 0 "memory_operand" "")
18559         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18560          UNSPEC_FIST_CEIL))
18561    (use (match_operand:HI 2 "memory_operand" ""))
18562    (use (match_operand:HI 3 "memory_operand" ""))
18563    (clobber (match_operand:DI 4 "memory_operand" ""))
18564    (clobber (match_scratch 5 ""))]
18565   "reload_completed"
18566   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18567               (use (match_dup 2))
18568               (use (match_dup 3))
18569               (clobber (match_dup 5))])]
18570   "")
18571
18572 (define_insn "fist<mode>2_ceil"
18573   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18574         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18575          UNSPEC_FIST_CEIL))
18576    (use (match_operand:HI 2 "memory_operand" "m"))
18577    (use (match_operand:HI 3 "memory_operand" "m"))]
18578   "TARGET_USE_FANCY_MATH_387
18579    && flag_unsafe_math_optimizations"
18580   "* return output_fix_trunc (insn, operands, 0);"
18581   [(set_attr "type" "fistp")
18582    (set_attr "i387_cw" "ceil")
18583    (set_attr "mode" "<MODE>")])
18584
18585 (define_insn "fist<mode>2_ceil_with_temp"
18586   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18587         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18588          UNSPEC_FIST_CEIL))
18589    (use (match_operand:HI 2 "memory_operand" "m,m"))
18590    (use (match_operand:HI 3 "memory_operand" "m,m"))
18591    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18592   "TARGET_USE_FANCY_MATH_387
18593    && flag_unsafe_math_optimizations"
18594   "#"
18595   [(set_attr "type" "fistp")
18596    (set_attr "i387_cw" "ceil")
18597    (set_attr "mode" "<MODE>")])
18598
18599 (define_split
18600   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18601         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18602          UNSPEC_FIST_CEIL))
18603    (use (match_operand:HI 2 "memory_operand" ""))
18604    (use (match_operand:HI 3 "memory_operand" ""))
18605    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18606   "reload_completed"
18607   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18608                                   UNSPEC_FIST_CEIL))
18609               (use (match_dup 2))
18610               (use (match_dup 3))])
18611    (set (match_dup 0) (match_dup 4))]
18612   "")
18613
18614 (define_split
18615   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18616         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18617          UNSPEC_FIST_CEIL))
18618    (use (match_operand:HI 2 "memory_operand" ""))
18619    (use (match_operand:HI 3 "memory_operand" ""))
18620    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18621   "reload_completed"
18622   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18623                                   UNSPEC_FIST_CEIL))
18624               (use (match_dup 2))
18625               (use (match_dup 3))])]
18626   "")
18627
18628 (define_expand "lceilxf<mode>2"
18629   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18630                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18631                     UNSPEC_FIST_CEIL))
18632               (clobber (reg:CC FLAGS_REG))])]
18633   "TARGET_USE_FANCY_MATH_387
18634    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18635    && flag_unsafe_math_optimizations"
18636   "")
18637
18638 (define_expand "lceil<mode>di2"
18639   [(match_operand:DI 0 "nonimmediate_operand" "")
18640    (match_operand:MODEF 1 "register_operand" "")]
18641   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18642    && !flag_trapping_math"
18643 {
18644   ix86_expand_lfloorceil (operand0, operand1, false);
18645   DONE;
18646 })
18647
18648 (define_expand "lceil<mode>si2"
18649   [(match_operand:SI 0 "nonimmediate_operand" "")
18650    (match_operand:MODEF 1 "register_operand" "")]
18651   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18652    && !flag_trapping_math"
18653 {
18654   ix86_expand_lfloorceil (operand0, operand1, false);
18655   DONE;
18656 })
18657
18658 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18659 (define_insn_and_split "frndintxf2_trunc"
18660   [(set (match_operand:XF 0 "register_operand" "")
18661         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18662          UNSPEC_FRNDINT_TRUNC))
18663    (clobber (reg:CC FLAGS_REG))]
18664   "TARGET_USE_FANCY_MATH_387
18665    && flag_unsafe_math_optimizations
18666    && !(reload_completed || reload_in_progress)"
18667   "#"
18668   "&& 1"
18669   [(const_int 0)]
18670 {
18671   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18672
18673   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18674   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18675
18676   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18677                                         operands[2], operands[3]));
18678   DONE;
18679 }
18680   [(set_attr "type" "frndint")
18681    (set_attr "i387_cw" "trunc")
18682    (set_attr "mode" "XF")])
18683
18684 (define_insn "frndintxf2_trunc_i387"
18685   [(set (match_operand:XF 0 "register_operand" "=f")
18686         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18687          UNSPEC_FRNDINT_TRUNC))
18688    (use (match_operand:HI 2 "memory_operand" "m"))
18689    (use (match_operand:HI 3 "memory_operand" "m"))]
18690   "TARGET_USE_FANCY_MATH_387
18691    && flag_unsafe_math_optimizations"
18692   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18693   [(set_attr "type" "frndint")
18694    (set_attr "i387_cw" "trunc")
18695    (set_attr "mode" "XF")])
18696
18697 (define_expand "btruncxf2"
18698   [(use (match_operand:XF 0 "register_operand" ""))
18699    (use (match_operand:XF 1 "register_operand" ""))]
18700   "TARGET_USE_FANCY_MATH_387
18701    && flag_unsafe_math_optimizations"
18702 {
18703   if (optimize_insn_for_size_p ())
18704     FAIL;
18705   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18706   DONE;
18707 })
18708
18709 (define_expand "btrunc<mode>2"
18710   [(use (match_operand:MODEF 0 "register_operand" ""))
18711    (use (match_operand:MODEF 1 "register_operand" ""))]
18712   "(TARGET_USE_FANCY_MATH_387
18713     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18714         || TARGET_MIX_SSE_I387)
18715     && flag_unsafe_math_optimizations)
18716    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18717        && !flag_trapping_math)"
18718 {
18719   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18720       && !flag_trapping_math
18721       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18722     {
18723       if (TARGET_ROUND)
18724         emit_insn (gen_sse4_1_round<mode>2
18725                    (operands[0], operands[1], GEN_INT (0x03)));
18726       else if (optimize_insn_for_size_p ())
18727         FAIL;
18728       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18729         ix86_expand_trunc (operand0, operand1);
18730       else
18731         ix86_expand_truncdf_32 (operand0, operand1);
18732     }
18733   else
18734     {
18735       rtx op0, op1;
18736
18737       if (optimize_insn_for_size_p ())
18738         FAIL;
18739
18740       op0 = gen_reg_rtx (XFmode);
18741       op1 = gen_reg_rtx (XFmode);
18742       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18743       emit_insn (gen_frndintxf2_trunc (op0, op1));
18744
18745       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18746     }
18747   DONE;
18748 })
18749
18750 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18751 (define_insn_and_split "frndintxf2_mask_pm"
18752   [(set (match_operand:XF 0 "register_operand" "")
18753         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18754          UNSPEC_FRNDINT_MASK_PM))
18755    (clobber (reg:CC FLAGS_REG))]
18756   "TARGET_USE_FANCY_MATH_387
18757    && flag_unsafe_math_optimizations
18758    && !(reload_completed || reload_in_progress)"
18759   "#"
18760   "&& 1"
18761   [(const_int 0)]
18762 {
18763   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18764
18765   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18766   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18767
18768   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18769                                           operands[2], operands[3]));
18770   DONE;
18771 }
18772   [(set_attr "type" "frndint")
18773    (set_attr "i387_cw" "mask_pm")
18774    (set_attr "mode" "XF")])
18775
18776 (define_insn "frndintxf2_mask_pm_i387"
18777   [(set (match_operand:XF 0 "register_operand" "=f")
18778         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18779          UNSPEC_FRNDINT_MASK_PM))
18780    (use (match_operand:HI 2 "memory_operand" "m"))
18781    (use (match_operand:HI 3 "memory_operand" "m"))]
18782   "TARGET_USE_FANCY_MATH_387
18783    && flag_unsafe_math_optimizations"
18784   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18785   [(set_attr "type" "frndint")
18786    (set_attr "i387_cw" "mask_pm")
18787    (set_attr "mode" "XF")])
18788
18789 (define_expand "nearbyintxf2"
18790   [(use (match_operand:XF 0 "register_operand" ""))
18791    (use (match_operand:XF 1 "register_operand" ""))]
18792   "TARGET_USE_FANCY_MATH_387
18793    && flag_unsafe_math_optimizations"
18794 {
18795   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18796
18797   DONE;
18798 })
18799
18800 (define_expand "nearbyint<mode>2"
18801   [(use (match_operand:MODEF 0 "register_operand" ""))
18802    (use (match_operand:MODEF 1 "register_operand" ""))]
18803   "TARGET_USE_FANCY_MATH_387
18804    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18805        || TARGET_MIX_SSE_I387)
18806    && flag_unsafe_math_optimizations"
18807 {
18808   rtx op0 = gen_reg_rtx (XFmode);
18809   rtx op1 = gen_reg_rtx (XFmode);
18810
18811   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18812   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18813
18814   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18815   DONE;
18816 })
18817
18818 (define_insn "fxam<mode>2_i387"
18819   [(set (match_operand:HI 0 "register_operand" "=a")
18820         (unspec:HI
18821           [(match_operand:X87MODEF 1 "register_operand" "f")]
18822           UNSPEC_FXAM))]
18823   "TARGET_USE_FANCY_MATH_387"
18824   "fxam\n\tfnstsw\t%0"
18825   [(set_attr "type" "multi")
18826    (set_attr "unit" "i387")
18827    (set_attr "mode" "<MODE>")])
18828
18829 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18830   [(set (match_operand:HI 0 "register_operand" "")
18831         (unspec:HI
18832           [(match_operand:MODEF 1 "memory_operand" "")]
18833           UNSPEC_FXAM_MEM))]
18834   "TARGET_USE_FANCY_MATH_387
18835    && !(reload_completed || reload_in_progress)"
18836   "#"
18837   "&& 1"
18838   [(set (match_dup 2)(match_dup 1))
18839    (set (match_dup 0)
18840         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18841 {
18842   operands[2] = gen_reg_rtx (<MODE>mode);
18843
18844   MEM_VOLATILE_P (operands[1]) = 1;
18845 }
18846   [(set_attr "type" "multi")
18847    (set_attr "unit" "i387")
18848    (set_attr "mode" "<MODE>")])
18849
18850 (define_expand "isinfxf2"
18851   [(use (match_operand:SI 0 "register_operand" ""))
18852    (use (match_operand:XF 1 "register_operand" ""))]
18853   "TARGET_USE_FANCY_MATH_387
18854    && TARGET_C99_FUNCTIONS"
18855 {
18856   rtx mask = GEN_INT (0x45);
18857   rtx val = GEN_INT (0x05);
18858
18859   rtx cond;
18860
18861   rtx scratch = gen_reg_rtx (HImode);
18862   rtx res = gen_reg_rtx (QImode);
18863
18864   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18865
18866   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18867   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18868   cond = gen_rtx_fmt_ee (EQ, QImode,
18869                          gen_rtx_REG (CCmode, FLAGS_REG),
18870                          const0_rtx);
18871   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18872   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18873   DONE;
18874 })
18875
18876 (define_expand "isinf<mode>2"
18877   [(use (match_operand:SI 0 "register_operand" ""))
18878    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18879   "TARGET_USE_FANCY_MATH_387
18880    && TARGET_C99_FUNCTIONS
18881    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18882 {
18883   rtx mask = GEN_INT (0x45);
18884   rtx val = GEN_INT (0x05);
18885
18886   rtx cond;
18887
18888   rtx scratch = gen_reg_rtx (HImode);
18889   rtx res = gen_reg_rtx (QImode);
18890
18891   /* Remove excess precision by forcing value through memory. */
18892   if (memory_operand (operands[1], VOIDmode))
18893     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18894   else
18895     {
18896       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18897       rtx temp = assign_386_stack_local (<MODE>mode, slot);
18898
18899       emit_move_insn (temp, operands[1]);
18900       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18901     }
18902
18903   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18904   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18905   cond = gen_rtx_fmt_ee (EQ, QImode,
18906                          gen_rtx_REG (CCmode, FLAGS_REG),
18907                          const0_rtx);
18908   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18909   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18910   DONE;
18911 })
18912
18913 (define_expand "signbit<mode>2"
18914   [(use (match_operand:SI 0 "register_operand" ""))
18915    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18916   "TARGET_USE_FANCY_MATH_387
18917    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18918 {
18919   rtx mask = GEN_INT (0x0200);
18920
18921   rtx scratch = gen_reg_rtx (HImode);
18922
18923   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18924   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18925   DONE;
18926 })
18927 \f
18928 ;; Block operation instructions
18929
18930 (define_insn "cld"
18931   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18932   ""
18933   "cld"
18934   [(set_attr "length" "1")
18935    (set_attr "length_immediate" "0")
18936    (set_attr "modrm" "0")])
18937
18938 (define_expand "movmemsi"
18939   [(use (match_operand:BLK 0 "memory_operand" ""))
18940    (use (match_operand:BLK 1 "memory_operand" ""))
18941    (use (match_operand:SI 2 "nonmemory_operand" ""))
18942    (use (match_operand:SI 3 "const_int_operand" ""))
18943    (use (match_operand:SI 4 "const_int_operand" ""))
18944    (use (match_operand:SI 5 "const_int_operand" ""))]
18945   ""
18946 {
18947  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18948                          operands[4], operands[5]))
18949    DONE;
18950  else
18951    FAIL;
18952 })
18953
18954 (define_expand "movmemdi"
18955   [(use (match_operand:BLK 0 "memory_operand" ""))
18956    (use (match_operand:BLK 1 "memory_operand" ""))
18957    (use (match_operand:DI 2 "nonmemory_operand" ""))
18958    (use (match_operand:DI 3 "const_int_operand" ""))
18959    (use (match_operand:SI 4 "const_int_operand" ""))
18960    (use (match_operand:SI 5 "const_int_operand" ""))]
18961   "TARGET_64BIT"
18962 {
18963  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18964                          operands[4], operands[5]))
18965    DONE;
18966  else
18967    FAIL;
18968 })
18969
18970 ;; Most CPUs don't like single string operations
18971 ;; Handle this case here to simplify previous expander.
18972
18973 (define_expand "strmov"
18974   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18975    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18976    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18977               (clobber (reg:CC FLAGS_REG))])
18978    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18979               (clobber (reg:CC FLAGS_REG))])]
18980   ""
18981 {
18982   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18983
18984   /* If .md ever supports :P for Pmode, these can be directly
18985      in the pattern above.  */
18986   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18987   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18988
18989   /* Can't use this if the user has appropriated esi or edi.  */
18990   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18991       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18992     {
18993       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18994                                       operands[2], operands[3],
18995                                       operands[5], operands[6]));
18996       DONE;
18997     }
18998
18999   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19000 })
19001
19002 (define_expand "strmov_singleop"
19003   [(parallel [(set (match_operand 1 "memory_operand" "")
19004                    (match_operand 3 "memory_operand" ""))
19005               (set (match_operand 0 "register_operand" "")
19006                    (match_operand 4 "" ""))
19007               (set (match_operand 2 "register_operand" "")
19008                    (match_operand 5 "" ""))])]
19009   ""
19010   "ix86_current_function_needs_cld = 1;")
19011
19012 (define_insn "*strmovdi_rex_1"
19013   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19014         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19015    (set (match_operand:DI 0 "register_operand" "=D")
19016         (plus:DI (match_dup 2)
19017                  (const_int 8)))
19018    (set (match_operand:DI 1 "register_operand" "=S")
19019         (plus:DI (match_dup 3)
19020                  (const_int 8)))]
19021   "TARGET_64BIT
19022    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19023   "movsq"
19024   [(set_attr "type" "str")
19025    (set_attr "mode" "DI")
19026    (set_attr "memory" "both")])
19027
19028 (define_insn "*strmovsi_1"
19029   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19030         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19031    (set (match_operand:SI 0 "register_operand" "=D")
19032         (plus:SI (match_dup 2)
19033                  (const_int 4)))
19034    (set (match_operand:SI 1 "register_operand" "=S")
19035         (plus:SI (match_dup 3)
19036                  (const_int 4)))]
19037   "!TARGET_64BIT
19038    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19039   "movs{l|d}"
19040   [(set_attr "type" "str")
19041    (set_attr "mode" "SI")
19042    (set_attr "memory" "both")])
19043
19044 (define_insn "*strmovsi_rex_1"
19045   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19046         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19047    (set (match_operand:DI 0 "register_operand" "=D")
19048         (plus:DI (match_dup 2)
19049                  (const_int 4)))
19050    (set (match_operand:DI 1 "register_operand" "=S")
19051         (plus:DI (match_dup 3)
19052                  (const_int 4)))]
19053   "TARGET_64BIT
19054    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19055   "movs{l|d}"
19056   [(set_attr "type" "str")
19057    (set_attr "mode" "SI")
19058    (set_attr "memory" "both")])
19059
19060 (define_insn "*strmovhi_1"
19061   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19062         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19063    (set (match_operand:SI 0 "register_operand" "=D")
19064         (plus:SI (match_dup 2)
19065                  (const_int 2)))
19066    (set (match_operand:SI 1 "register_operand" "=S")
19067         (plus:SI (match_dup 3)
19068                  (const_int 2)))]
19069   "!TARGET_64BIT
19070    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19071   "movsw"
19072   [(set_attr "type" "str")
19073    (set_attr "memory" "both")
19074    (set_attr "mode" "HI")])
19075
19076 (define_insn "*strmovhi_rex_1"
19077   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19078         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19079    (set (match_operand:DI 0 "register_operand" "=D")
19080         (plus:DI (match_dup 2)
19081                  (const_int 2)))
19082    (set (match_operand:DI 1 "register_operand" "=S")
19083         (plus:DI (match_dup 3)
19084                  (const_int 2)))]
19085   "TARGET_64BIT
19086    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19087   "movsw"
19088   [(set_attr "type" "str")
19089    (set_attr "memory" "both")
19090    (set_attr "mode" "HI")])
19091
19092 (define_insn "*strmovqi_1"
19093   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19094         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19095    (set (match_operand:SI 0 "register_operand" "=D")
19096         (plus:SI (match_dup 2)
19097                  (const_int 1)))
19098    (set (match_operand:SI 1 "register_operand" "=S")
19099         (plus:SI (match_dup 3)
19100                  (const_int 1)))]
19101   "!TARGET_64BIT
19102    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19103   "movsb"
19104   [(set_attr "type" "str")
19105    (set_attr "memory" "both")
19106    (set_attr "mode" "QI")])
19107
19108 (define_insn "*strmovqi_rex_1"
19109   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19110         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19111    (set (match_operand:DI 0 "register_operand" "=D")
19112         (plus:DI (match_dup 2)
19113                  (const_int 1)))
19114    (set (match_operand:DI 1 "register_operand" "=S")
19115         (plus:DI (match_dup 3)
19116                  (const_int 1)))]
19117   "TARGET_64BIT
19118    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19119   "movsb"
19120   [(set_attr "type" "str")
19121    (set_attr "memory" "both")
19122    (set_attr "mode" "QI")])
19123
19124 (define_expand "rep_mov"
19125   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19126               (set (match_operand 0 "register_operand" "")
19127                    (match_operand 5 "" ""))
19128               (set (match_operand 2 "register_operand" "")
19129                    (match_operand 6 "" ""))
19130               (set (match_operand 1 "memory_operand" "")
19131                    (match_operand 3 "memory_operand" ""))
19132               (use (match_dup 4))])]
19133   ""
19134   "ix86_current_function_needs_cld = 1;")
19135
19136 (define_insn "*rep_movdi_rex64"
19137   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19138    (set (match_operand:DI 0 "register_operand" "=D")
19139         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19140                             (const_int 3))
19141                  (match_operand:DI 3 "register_operand" "0")))
19142    (set (match_operand:DI 1 "register_operand" "=S")
19143         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19144                  (match_operand:DI 4 "register_operand" "1")))
19145    (set (mem:BLK (match_dup 3))
19146         (mem:BLK (match_dup 4)))
19147    (use (match_dup 5))]
19148   "TARGET_64BIT
19149    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19150   "rep{%;} movsq"
19151   [(set_attr "type" "str")
19152    (set_attr "prefix_rep" "1")
19153    (set_attr "memory" "both")
19154    (set_attr "mode" "DI")])
19155
19156 (define_insn "*rep_movsi"
19157   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19158    (set (match_operand:SI 0 "register_operand" "=D")
19159         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19160                             (const_int 2))
19161                  (match_operand:SI 3 "register_operand" "0")))
19162    (set (match_operand:SI 1 "register_operand" "=S")
19163         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19164                  (match_operand:SI 4 "register_operand" "1")))
19165    (set (mem:BLK (match_dup 3))
19166         (mem:BLK (match_dup 4)))
19167    (use (match_dup 5))]
19168   "!TARGET_64BIT
19169    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19170   "rep{%;} movs{l|d}"
19171   [(set_attr "type" "str")
19172    (set_attr "prefix_rep" "1")
19173    (set_attr "memory" "both")
19174    (set_attr "mode" "SI")])
19175
19176 (define_insn "*rep_movsi_rex64"
19177   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19178    (set (match_operand:DI 0 "register_operand" "=D")
19179         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19180                             (const_int 2))
19181                  (match_operand:DI 3 "register_operand" "0")))
19182    (set (match_operand:DI 1 "register_operand" "=S")
19183         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19184                  (match_operand:DI 4 "register_operand" "1")))
19185    (set (mem:BLK (match_dup 3))
19186         (mem:BLK (match_dup 4)))
19187    (use (match_dup 5))]
19188   "TARGET_64BIT
19189    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19190   "rep{%;} movs{l|d}"
19191   [(set_attr "type" "str")
19192    (set_attr "prefix_rep" "1")
19193    (set_attr "memory" "both")
19194    (set_attr "mode" "SI")])
19195
19196 (define_insn "*rep_movqi"
19197   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19198    (set (match_operand:SI 0 "register_operand" "=D")
19199         (plus:SI (match_operand:SI 3 "register_operand" "0")
19200                  (match_operand:SI 5 "register_operand" "2")))
19201    (set (match_operand:SI 1 "register_operand" "=S")
19202         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19203    (set (mem:BLK (match_dup 3))
19204         (mem:BLK (match_dup 4)))
19205    (use (match_dup 5))]
19206   "!TARGET_64BIT
19207    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19208   "rep{%;} movsb"
19209   [(set_attr "type" "str")
19210    (set_attr "prefix_rep" "1")
19211    (set_attr "memory" "both")
19212    (set_attr "mode" "SI")])
19213
19214 (define_insn "*rep_movqi_rex64"
19215   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19216    (set (match_operand:DI 0 "register_operand" "=D")
19217         (plus:DI (match_operand:DI 3 "register_operand" "0")
19218                  (match_operand:DI 5 "register_operand" "2")))
19219    (set (match_operand:DI 1 "register_operand" "=S")
19220         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19221    (set (mem:BLK (match_dup 3))
19222         (mem:BLK (match_dup 4)))
19223    (use (match_dup 5))]
19224   "TARGET_64BIT
19225    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19226   "rep{%;} movsb"
19227   [(set_attr "type" "str")
19228    (set_attr "prefix_rep" "1")
19229    (set_attr "memory" "both")
19230    (set_attr "mode" "SI")])
19231
19232 (define_expand "setmemsi"
19233    [(use (match_operand:BLK 0 "memory_operand" ""))
19234     (use (match_operand:SI 1 "nonmemory_operand" ""))
19235     (use (match_operand 2 "const_int_operand" ""))
19236     (use (match_operand 3 "const_int_operand" ""))
19237     (use (match_operand:SI 4 "const_int_operand" ""))
19238     (use (match_operand:SI 5 "const_int_operand" ""))]
19239   ""
19240 {
19241  if (ix86_expand_setmem (operands[0], operands[1],
19242                          operands[2], operands[3],
19243                          operands[4], operands[5]))
19244    DONE;
19245  else
19246    FAIL;
19247 })
19248
19249 (define_expand "setmemdi"
19250    [(use (match_operand:BLK 0 "memory_operand" ""))
19251     (use (match_operand:DI 1 "nonmemory_operand" ""))
19252     (use (match_operand 2 "const_int_operand" ""))
19253     (use (match_operand 3 "const_int_operand" ""))
19254     (use (match_operand 4 "const_int_operand" ""))
19255     (use (match_operand 5 "const_int_operand" ""))]
19256   "TARGET_64BIT"
19257 {
19258  if (ix86_expand_setmem (operands[0], operands[1],
19259                          operands[2], operands[3],
19260                          operands[4], operands[5]))
19261    DONE;
19262  else
19263    FAIL;
19264 })
19265
19266 ;; Most CPUs don't like single string operations
19267 ;; Handle this case here to simplify previous expander.
19268
19269 (define_expand "strset"
19270   [(set (match_operand 1 "memory_operand" "")
19271         (match_operand 2 "register_operand" ""))
19272    (parallel [(set (match_operand 0 "register_operand" "")
19273                    (match_dup 3))
19274               (clobber (reg:CC FLAGS_REG))])]
19275   ""
19276 {
19277   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19278     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19279
19280   /* If .md ever supports :P for Pmode, this can be directly
19281      in the pattern above.  */
19282   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19283                               GEN_INT (GET_MODE_SIZE (GET_MODE
19284                                                       (operands[2]))));
19285   /* Can't use this if the user has appropriated eax or edi.  */
19286   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19287       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
19288     {
19289       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19290                                       operands[3]));
19291       DONE;
19292     }
19293 })
19294
19295 (define_expand "strset_singleop"
19296   [(parallel [(set (match_operand 1 "memory_operand" "")
19297                    (match_operand 2 "register_operand" ""))
19298               (set (match_operand 0 "register_operand" "")
19299                    (match_operand 3 "" ""))])]
19300   ""
19301   "ix86_current_function_needs_cld = 1;")
19302
19303 (define_insn "*strsetdi_rex_1"
19304   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19305         (match_operand:DI 2 "register_operand" "a"))
19306    (set (match_operand:DI 0 "register_operand" "=D")
19307         (plus:DI (match_dup 1)
19308                  (const_int 8)))]
19309   "TARGET_64BIT
19310    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19311   "stosq"
19312   [(set_attr "type" "str")
19313    (set_attr "memory" "store")
19314    (set_attr "mode" "DI")])
19315
19316 (define_insn "*strsetsi_1"
19317   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19318         (match_operand:SI 2 "register_operand" "a"))
19319    (set (match_operand:SI 0 "register_operand" "=D")
19320         (plus:SI (match_dup 1)
19321                  (const_int 4)))]
19322   "!TARGET_64BIT
19323    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19324   "stos{l|d}"
19325   [(set_attr "type" "str")
19326    (set_attr "memory" "store")
19327    (set_attr "mode" "SI")])
19328
19329 (define_insn "*strsetsi_rex_1"
19330   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19331         (match_operand:SI 2 "register_operand" "a"))
19332    (set (match_operand:DI 0 "register_operand" "=D")
19333         (plus:DI (match_dup 1)
19334                  (const_int 4)))]
19335   "TARGET_64BIT
19336    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19337   "stos{l|d}"
19338   [(set_attr "type" "str")
19339    (set_attr "memory" "store")
19340    (set_attr "mode" "SI")])
19341
19342 (define_insn "*strsethi_1"
19343   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19344         (match_operand:HI 2 "register_operand" "a"))
19345    (set (match_operand:SI 0 "register_operand" "=D")
19346         (plus:SI (match_dup 1)
19347                  (const_int 2)))]
19348   "!TARGET_64BIT
19349    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19350   "stosw"
19351   [(set_attr "type" "str")
19352    (set_attr "memory" "store")
19353    (set_attr "mode" "HI")])
19354
19355 (define_insn "*strsethi_rex_1"
19356   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19357         (match_operand:HI 2 "register_operand" "a"))
19358    (set (match_operand:DI 0 "register_operand" "=D")
19359         (plus:DI (match_dup 1)
19360                  (const_int 2)))]
19361   "TARGET_64BIT
19362    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19363   "stosw"
19364   [(set_attr "type" "str")
19365    (set_attr "memory" "store")
19366    (set_attr "mode" "HI")])
19367
19368 (define_insn "*strsetqi_1"
19369   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19370         (match_operand:QI 2 "register_operand" "a"))
19371    (set (match_operand:SI 0 "register_operand" "=D")
19372         (plus:SI (match_dup 1)
19373                  (const_int 1)))]
19374   "!TARGET_64BIT
19375    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19376   "stosb"
19377   [(set_attr "type" "str")
19378    (set_attr "memory" "store")
19379    (set_attr "mode" "QI")])
19380
19381 (define_insn "*strsetqi_rex_1"
19382   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19383         (match_operand:QI 2 "register_operand" "a"))
19384    (set (match_operand:DI 0 "register_operand" "=D")
19385         (plus:DI (match_dup 1)
19386                  (const_int 1)))]
19387   "TARGET_64BIT
19388    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
19389   "stosb"
19390   [(set_attr "type" "str")
19391    (set_attr "memory" "store")
19392    (set_attr "mode" "QI")])
19393
19394 (define_expand "rep_stos"
19395   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19396               (set (match_operand 0 "register_operand" "")
19397                    (match_operand 4 "" ""))
19398               (set (match_operand 2 "memory_operand" "") (const_int 0))
19399               (use (match_operand 3 "register_operand" ""))
19400               (use (match_dup 1))])]
19401   ""
19402   "ix86_current_function_needs_cld = 1;")
19403
19404 (define_insn "*rep_stosdi_rex64"
19405   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19406    (set (match_operand:DI 0 "register_operand" "=D")
19407         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19408                             (const_int 3))
19409                  (match_operand:DI 3 "register_operand" "0")))
19410    (set (mem:BLK (match_dup 3))
19411         (const_int 0))
19412    (use (match_operand:DI 2 "register_operand" "a"))
19413    (use (match_dup 4))]
19414   "TARGET_64BIT
19415    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19416   "rep{%;} stosq"
19417   [(set_attr "type" "str")
19418    (set_attr "prefix_rep" "1")
19419    (set_attr "memory" "store")
19420    (set_attr "mode" "DI")])
19421
19422 (define_insn "*rep_stossi"
19423   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19424    (set (match_operand:SI 0 "register_operand" "=D")
19425         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19426                             (const_int 2))
19427                  (match_operand:SI 3 "register_operand" "0")))
19428    (set (mem:BLK (match_dup 3))
19429         (const_int 0))
19430    (use (match_operand:SI 2 "register_operand" "a"))
19431    (use (match_dup 4))]
19432   "!TARGET_64BIT
19433    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19434   "rep{%;} stos{l|d}"
19435   [(set_attr "type" "str")
19436    (set_attr "prefix_rep" "1")
19437    (set_attr "memory" "store")
19438    (set_attr "mode" "SI")])
19439
19440 (define_insn "*rep_stossi_rex64"
19441   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19442    (set (match_operand:DI 0 "register_operand" "=D")
19443         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19444                             (const_int 2))
19445                  (match_operand:DI 3 "register_operand" "0")))
19446    (set (mem:BLK (match_dup 3))
19447         (const_int 0))
19448    (use (match_operand:SI 2 "register_operand" "a"))
19449    (use (match_dup 4))]
19450   "TARGET_64BIT
19451    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19452   "rep{%;} stos{l|d}"
19453   [(set_attr "type" "str")
19454    (set_attr "prefix_rep" "1")
19455    (set_attr "memory" "store")
19456    (set_attr "mode" "SI")])
19457
19458 (define_insn "*rep_stosqi"
19459   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19460    (set (match_operand:SI 0 "register_operand" "=D")
19461         (plus:SI (match_operand:SI 3 "register_operand" "0")
19462                  (match_operand:SI 4 "register_operand" "1")))
19463    (set (mem:BLK (match_dup 3))
19464         (const_int 0))
19465    (use (match_operand:QI 2 "register_operand" "a"))
19466    (use (match_dup 4))]
19467   "!TARGET_64BIT
19468    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19469   "rep{%;} stosb"
19470   [(set_attr "type" "str")
19471    (set_attr "prefix_rep" "1")
19472    (set_attr "memory" "store")
19473    (set_attr "mode" "QI")])
19474
19475 (define_insn "*rep_stosqi_rex64"
19476   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19477    (set (match_operand:DI 0 "register_operand" "=D")
19478         (plus:DI (match_operand:DI 3 "register_operand" "0")
19479                  (match_operand:DI 4 "register_operand" "1")))
19480    (set (mem:BLK (match_dup 3))
19481         (const_int 0))
19482    (use (match_operand:QI 2 "register_operand" "a"))
19483    (use (match_dup 4))]
19484   "TARGET_64BIT
19485    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19486   "rep{%;} stosb"
19487   [(set_attr "type" "str")
19488    (set_attr "prefix_rep" "1")
19489    (set_attr "memory" "store")
19490    (set_attr "mode" "QI")])
19491
19492 (define_expand "cmpstrnsi"
19493   [(set (match_operand:SI 0 "register_operand" "")
19494         (compare:SI (match_operand:BLK 1 "general_operand" "")
19495                     (match_operand:BLK 2 "general_operand" "")))
19496    (use (match_operand 3 "general_operand" ""))
19497    (use (match_operand 4 "immediate_operand" ""))]
19498   ""
19499 {
19500   rtx addr1, addr2, out, outlow, count, countreg, align;
19501
19502   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19503     FAIL;
19504
19505   /* Can't use this if the user has appropriated ecx, esi or edi.  */
19506   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
19507     FAIL;
19508
19509   out = operands[0];
19510   if (!REG_P (out))
19511     out = gen_reg_rtx (SImode);
19512
19513   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19514   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19515   if (addr1 != XEXP (operands[1], 0))
19516     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19517   if (addr2 != XEXP (operands[2], 0))
19518     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19519
19520   count = operands[3];
19521   countreg = ix86_zero_extend_to_Pmode (count);
19522
19523   /* %%% Iff we are testing strict equality, we can use known alignment
19524      to good advantage.  This may be possible with combine, particularly
19525      once cc0 is dead.  */
19526   align = operands[4];
19527
19528   if (CONST_INT_P (count))
19529     {
19530       if (INTVAL (count) == 0)
19531         {
19532           emit_move_insn (operands[0], const0_rtx);
19533           DONE;
19534         }
19535       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19536                                      operands[1], operands[2]));
19537     }
19538   else
19539     {
19540       if (TARGET_64BIT)
19541         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19542       else
19543         emit_insn (gen_cmpsi_1 (countreg, countreg));
19544       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19545                                   operands[1], operands[2]));
19546     }
19547
19548   outlow = gen_lowpart (QImode, out);
19549   emit_insn (gen_cmpintqi (outlow));
19550   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19551
19552   if (operands[0] != out)
19553     emit_move_insn (operands[0], out);
19554
19555   DONE;
19556 })
19557
19558 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19559
19560 (define_expand "cmpintqi"
19561   [(set (match_dup 1)
19562         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19563    (set (match_dup 2)
19564         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19565    (parallel [(set (match_operand:QI 0 "register_operand" "")
19566                    (minus:QI (match_dup 1)
19567                              (match_dup 2)))
19568               (clobber (reg:CC FLAGS_REG))])]
19569   ""
19570   "operands[1] = gen_reg_rtx (QImode);
19571    operands[2] = gen_reg_rtx (QImode);")
19572
19573 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19574 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19575
19576 (define_expand "cmpstrnqi_nz_1"
19577   [(parallel [(set (reg:CC FLAGS_REG)
19578                    (compare:CC (match_operand 4 "memory_operand" "")
19579                                (match_operand 5 "memory_operand" "")))
19580               (use (match_operand 2 "register_operand" ""))
19581               (use (match_operand:SI 3 "immediate_operand" ""))
19582               (clobber (match_operand 0 "register_operand" ""))
19583               (clobber (match_operand 1 "register_operand" ""))
19584               (clobber (match_dup 2))])]
19585   ""
19586   "ix86_current_function_needs_cld = 1;")
19587
19588 (define_insn "*cmpstrnqi_nz_1"
19589   [(set (reg:CC FLAGS_REG)
19590         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19591                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19592    (use (match_operand:SI 6 "register_operand" "2"))
19593    (use (match_operand:SI 3 "immediate_operand" "i"))
19594    (clobber (match_operand:SI 0 "register_operand" "=S"))
19595    (clobber (match_operand:SI 1 "register_operand" "=D"))
19596    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19597   "!TARGET_64BIT
19598    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19599   "repz{%;} cmpsb"
19600   [(set_attr "type" "str")
19601    (set_attr "mode" "QI")
19602    (set_attr "prefix_rep" "1")])
19603
19604 (define_insn "*cmpstrnqi_nz_rex_1"
19605   [(set (reg:CC FLAGS_REG)
19606         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19607                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19608    (use (match_operand:DI 6 "register_operand" "2"))
19609    (use (match_operand:SI 3 "immediate_operand" "i"))
19610    (clobber (match_operand:DI 0 "register_operand" "=S"))
19611    (clobber (match_operand:DI 1 "register_operand" "=D"))
19612    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19613   "TARGET_64BIT
19614    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19615   "repz{%;} cmpsb"
19616   [(set_attr "type" "str")
19617    (set_attr "mode" "QI")
19618    (set_attr "prefix_rep" "1")])
19619
19620 ;; The same, but the count is not known to not be zero.
19621
19622 (define_expand "cmpstrnqi_1"
19623   [(parallel [(set (reg:CC FLAGS_REG)
19624                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19625                                      (const_int 0))
19626                   (compare:CC (match_operand 4 "memory_operand" "")
19627                               (match_operand 5 "memory_operand" ""))
19628                   (const_int 0)))
19629               (use (match_operand:SI 3 "immediate_operand" ""))
19630               (use (reg:CC FLAGS_REG))
19631               (clobber (match_operand 0 "register_operand" ""))
19632               (clobber (match_operand 1 "register_operand" ""))
19633               (clobber (match_dup 2))])]
19634   ""
19635   "ix86_current_function_needs_cld = 1;")
19636
19637 (define_insn "*cmpstrnqi_1"
19638   [(set (reg:CC FLAGS_REG)
19639         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19640                              (const_int 0))
19641           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19642                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19643           (const_int 0)))
19644    (use (match_operand:SI 3 "immediate_operand" "i"))
19645    (use (reg:CC FLAGS_REG))
19646    (clobber (match_operand:SI 0 "register_operand" "=S"))
19647    (clobber (match_operand:SI 1 "register_operand" "=D"))
19648    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19649   "!TARGET_64BIT
19650    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19651   "repz{%;} cmpsb"
19652   [(set_attr "type" "str")
19653    (set_attr "mode" "QI")
19654    (set_attr "prefix_rep" "1")])
19655
19656 (define_insn "*cmpstrnqi_rex_1"
19657   [(set (reg:CC FLAGS_REG)
19658         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19659                              (const_int 0))
19660           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19661                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19662           (const_int 0)))
19663    (use (match_operand:SI 3 "immediate_operand" "i"))
19664    (use (reg:CC FLAGS_REG))
19665    (clobber (match_operand:DI 0 "register_operand" "=S"))
19666    (clobber (match_operand:DI 1 "register_operand" "=D"))
19667    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19668   "TARGET_64BIT
19669    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
19670   "repz{%;} cmpsb"
19671   [(set_attr "type" "str")
19672    (set_attr "mode" "QI")
19673    (set_attr "prefix_rep" "1")])
19674
19675 (define_expand "strlensi"
19676   [(set (match_operand:SI 0 "register_operand" "")
19677         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19678                     (match_operand:QI 2 "immediate_operand" "")
19679                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19680   "!TARGET_64BIT"
19681 {
19682  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19683    DONE;
19684  else
19685    FAIL;
19686 })
19687
19688 (define_expand "strlendi"
19689   [(set (match_operand:DI 0 "register_operand" "")
19690         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19691                     (match_operand:QI 2 "immediate_operand" "")
19692                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19693   "TARGET_64BIT"
19694 {
19695  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19696    DONE;
19697  else
19698    FAIL;
19699 })
19700
19701 (define_expand "strlenqi_1"
19702   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19703               (clobber (match_operand 1 "register_operand" ""))
19704               (clobber (reg:CC FLAGS_REG))])]
19705   ""
19706   "ix86_current_function_needs_cld = 1;")
19707
19708 (define_insn "*strlenqi_1"
19709   [(set (match_operand:SI 0 "register_operand" "=&c")
19710         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19711                     (match_operand:QI 2 "register_operand" "a")
19712                     (match_operand:SI 3 "immediate_operand" "i")
19713                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19714    (clobber (match_operand:SI 1 "register_operand" "=D"))
19715    (clobber (reg:CC FLAGS_REG))]
19716   "!TARGET_64BIT
19717    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19718   "repnz{%;} scasb"
19719   [(set_attr "type" "str")
19720    (set_attr "mode" "QI")
19721    (set_attr "prefix_rep" "1")])
19722
19723 (define_insn "*strlenqi_rex_1"
19724   [(set (match_operand:DI 0 "register_operand" "=&c")
19725         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19726                     (match_operand:QI 2 "register_operand" "a")
19727                     (match_operand:DI 3 "immediate_operand" "i")
19728                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19729    (clobber (match_operand:DI 1 "register_operand" "=D"))
19730    (clobber (reg:CC FLAGS_REG))]
19731   "TARGET_64BIT
19732    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
19733   "repnz{%;} scasb"
19734   [(set_attr "type" "str")
19735    (set_attr "mode" "QI")
19736    (set_attr "prefix_rep" "1")])
19737
19738 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19739 ;; handled in combine, but it is not currently up to the task.
19740 ;; When used for their truth value, the cmpstrn* expanders generate
19741 ;; code like this:
19742 ;;
19743 ;;   repz cmpsb
19744 ;;   seta       %al
19745 ;;   setb       %dl
19746 ;;   cmpb       %al, %dl
19747 ;;   jcc        label
19748 ;;
19749 ;; The intermediate three instructions are unnecessary.
19750
19751 ;; This one handles cmpstrn*_nz_1...
19752 (define_peephole2
19753   [(parallel[
19754      (set (reg:CC FLAGS_REG)
19755           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19756                       (mem:BLK (match_operand 5 "register_operand" ""))))
19757      (use (match_operand 6 "register_operand" ""))
19758      (use (match_operand:SI 3 "immediate_operand" ""))
19759      (clobber (match_operand 0 "register_operand" ""))
19760      (clobber (match_operand 1 "register_operand" ""))
19761      (clobber (match_operand 2 "register_operand" ""))])
19762    (set (match_operand:QI 7 "register_operand" "")
19763         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19764    (set (match_operand:QI 8 "register_operand" "")
19765         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19766    (set (reg FLAGS_REG)
19767         (compare (match_dup 7) (match_dup 8)))
19768   ]
19769   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19770   [(parallel[
19771      (set (reg:CC FLAGS_REG)
19772           (compare:CC (mem:BLK (match_dup 4))
19773                       (mem:BLK (match_dup 5))))
19774      (use (match_dup 6))
19775      (use (match_dup 3))
19776      (clobber (match_dup 0))
19777      (clobber (match_dup 1))
19778      (clobber (match_dup 2))])]
19779   "")
19780
19781 ;; ...and this one handles cmpstrn*_1.
19782 (define_peephole2
19783   [(parallel[
19784      (set (reg:CC FLAGS_REG)
19785           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19786                                (const_int 0))
19787             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19788                         (mem:BLK (match_operand 5 "register_operand" "")))
19789             (const_int 0)))
19790      (use (match_operand:SI 3 "immediate_operand" ""))
19791      (use (reg:CC FLAGS_REG))
19792      (clobber (match_operand 0 "register_operand" ""))
19793      (clobber (match_operand 1 "register_operand" ""))
19794      (clobber (match_operand 2 "register_operand" ""))])
19795    (set (match_operand:QI 7 "register_operand" "")
19796         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19797    (set (match_operand:QI 8 "register_operand" "")
19798         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19799    (set (reg FLAGS_REG)
19800         (compare (match_dup 7) (match_dup 8)))
19801   ]
19802   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19803   [(parallel[
19804      (set (reg:CC FLAGS_REG)
19805           (if_then_else:CC (ne (match_dup 6)
19806                                (const_int 0))
19807             (compare:CC (mem:BLK (match_dup 4))
19808                         (mem:BLK (match_dup 5)))
19809             (const_int 0)))
19810      (use (match_dup 3))
19811      (use (reg:CC FLAGS_REG))
19812      (clobber (match_dup 0))
19813      (clobber (match_dup 1))
19814      (clobber (match_dup 2))])]
19815   "")
19816
19817
19818 \f
19819 ;; Conditional move instructions.
19820
19821 (define_expand "movdicc"
19822   [(set (match_operand:DI 0 "register_operand" "")
19823         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19824                          (match_operand:DI 2 "general_operand" "")
19825                          (match_operand:DI 3 "general_operand" "")))]
19826   "TARGET_64BIT"
19827   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19828
19829 (define_insn "x86_movdicc_0_m1_rex64"
19830   [(set (match_operand:DI 0 "register_operand" "=r")
19831         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19832           (const_int -1)
19833           (const_int 0)))
19834    (clobber (reg:CC FLAGS_REG))]
19835   "TARGET_64BIT"
19836   "sbb{q}\t%0, %0"
19837   ; Since we don't have the proper number of operands for an alu insn,
19838   ; fill in all the blanks.
19839   [(set_attr "type" "alu")
19840    (set_attr "pent_pair" "pu")
19841    (set_attr "memory" "none")
19842    (set_attr "imm_disp" "false")
19843    (set_attr "mode" "DI")
19844    (set_attr "length_immediate" "0")])
19845
19846 (define_insn "*x86_movdicc_0_m1_se"
19847   [(set (match_operand:DI 0 "register_operand" "=r")
19848         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19849                          (const_int 1)
19850                          (const_int 0)))
19851    (clobber (reg:CC FLAGS_REG))]
19852   ""
19853   "sbb{q}\t%0, %0"
19854   [(set_attr "type" "alu")
19855    (set_attr "pent_pair" "pu")
19856    (set_attr "memory" "none")
19857    (set_attr "imm_disp" "false")
19858    (set_attr "mode" "DI")
19859    (set_attr "length_immediate" "0")])
19860
19861 (define_insn "*movdicc_c_rex64"
19862   [(set (match_operand:DI 0 "register_operand" "=r,r")
19863         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19864                                 [(reg FLAGS_REG) (const_int 0)])
19865                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19866                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19867   "TARGET_64BIT && TARGET_CMOVE
19868    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19869   "@
19870    cmov%O2%C1\t{%2, %0|%0, %2}
19871    cmov%O2%c1\t{%3, %0|%0, %3}"
19872   [(set_attr "type" "icmov")
19873    (set_attr "mode" "DI")])
19874
19875 (define_expand "movsicc"
19876   [(set (match_operand:SI 0 "register_operand" "")
19877         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19878                          (match_operand:SI 2 "general_operand" "")
19879                          (match_operand:SI 3 "general_operand" "")))]
19880   ""
19881   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19882
19883 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19884 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19885 ;; So just document what we're doing explicitly.
19886
19887 (define_insn "x86_movsicc_0_m1"
19888   [(set (match_operand:SI 0 "register_operand" "=r")
19889         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19890           (const_int -1)
19891           (const_int 0)))
19892    (clobber (reg:CC FLAGS_REG))]
19893   ""
19894   "sbb{l}\t%0, %0"
19895   ; Since we don't have the proper number of operands for an alu insn,
19896   ; fill in all the blanks.
19897   [(set_attr "type" "alu")
19898    (set_attr "pent_pair" "pu")
19899    (set_attr "memory" "none")
19900    (set_attr "imm_disp" "false")
19901    (set_attr "mode" "SI")
19902    (set_attr "length_immediate" "0")])
19903
19904 (define_insn "*x86_movsicc_0_m1_se"
19905   [(set (match_operand:SI 0 "register_operand" "=r")
19906         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19907                          (const_int 1)
19908                          (const_int 0)))
19909    (clobber (reg:CC FLAGS_REG))]
19910   ""
19911   "sbb{l}\t%0, %0"
19912   [(set_attr "type" "alu")
19913    (set_attr "pent_pair" "pu")
19914    (set_attr "memory" "none")
19915    (set_attr "imm_disp" "false")
19916    (set_attr "mode" "SI")
19917    (set_attr "length_immediate" "0")])
19918
19919 (define_insn "*movsicc_noc"
19920   [(set (match_operand:SI 0 "register_operand" "=r,r")
19921         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19922                                 [(reg FLAGS_REG) (const_int 0)])
19923                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19924                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19925   "TARGET_CMOVE
19926    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19927   "@
19928    cmov%O2%C1\t{%2, %0|%0, %2}
19929    cmov%O2%c1\t{%3, %0|%0, %3}"
19930   [(set_attr "type" "icmov")
19931    (set_attr "mode" "SI")])
19932
19933 (define_expand "movhicc"
19934   [(set (match_operand:HI 0 "register_operand" "")
19935         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19936                          (match_operand:HI 2 "general_operand" "")
19937                          (match_operand:HI 3 "general_operand" "")))]
19938   "TARGET_HIMODE_MATH"
19939   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19940
19941 (define_insn "*movhicc_noc"
19942   [(set (match_operand:HI 0 "register_operand" "=r,r")
19943         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19944                                 [(reg FLAGS_REG) (const_int 0)])
19945                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19946                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19947   "TARGET_CMOVE
19948    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19949   "@
19950    cmov%O2%C1\t{%2, %0|%0, %2}
19951    cmov%O2%c1\t{%3, %0|%0, %3}"
19952   [(set_attr "type" "icmov")
19953    (set_attr "mode" "HI")])
19954
19955 (define_expand "movqicc"
19956   [(set (match_operand:QI 0 "register_operand" "")
19957         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19958                          (match_operand:QI 2 "general_operand" "")
19959                          (match_operand:QI 3 "general_operand" "")))]
19960   "TARGET_QIMODE_MATH"
19961   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19962
19963 (define_insn_and_split "*movqicc_noc"
19964   [(set (match_operand:QI 0 "register_operand" "=r,r")
19965         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19966                                 [(match_operand 4 "flags_reg_operand" "")
19967                                  (const_int 0)])
19968                       (match_operand:QI 2 "register_operand" "r,0")
19969                       (match_operand:QI 3 "register_operand" "0,r")))]
19970   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19971   "#"
19972   "&& reload_completed"
19973   [(set (match_dup 0)
19974         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19975                       (match_dup 2)
19976                       (match_dup 3)))]
19977   "operands[0] = gen_lowpart (SImode, operands[0]);
19978    operands[2] = gen_lowpart (SImode, operands[2]);
19979    operands[3] = gen_lowpart (SImode, operands[3]);"
19980   [(set_attr "type" "icmov")
19981    (set_attr "mode" "SI")])
19982
19983 (define_expand "mov<mode>cc"
19984   [(set (match_operand:X87MODEF 0 "register_operand" "")
19985         (if_then_else:X87MODEF
19986           (match_operand 1 "comparison_operator" "")
19987           (match_operand:X87MODEF 2 "register_operand" "")
19988           (match_operand:X87MODEF 3 "register_operand" "")))]
19989   "(TARGET_80387 && TARGET_CMOVE)
19990    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19991   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19992
19993 (define_insn "*movsfcc_1_387"
19994   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19995         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19996                                 [(reg FLAGS_REG) (const_int 0)])
19997                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19998                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19999   "TARGET_80387 && TARGET_CMOVE
20000    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20001   "@
20002    fcmov%F1\t{%2, %0|%0, %2}
20003    fcmov%f1\t{%3, %0|%0, %3}
20004    cmov%O2%C1\t{%2, %0|%0, %2}
20005    cmov%O2%c1\t{%3, %0|%0, %3}"
20006   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20007    (set_attr "mode" "SF,SF,SI,SI")])
20008
20009 (define_insn "*movdfcc_1"
20010   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20011         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20012                                 [(reg FLAGS_REG) (const_int 0)])
20013                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20014                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20015   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20016    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20017   "@
20018    fcmov%F1\t{%2, %0|%0, %2}
20019    fcmov%f1\t{%3, %0|%0, %3}
20020    #
20021    #"
20022   [(set_attr "type" "fcmov,fcmov,multi,multi")
20023    (set_attr "mode" "DF")])
20024
20025 (define_insn "*movdfcc_1_rex64"
20026   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20027         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20028                                 [(reg FLAGS_REG) (const_int 0)])
20029                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20030                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20031   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20032    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20033   "@
20034    fcmov%F1\t{%2, %0|%0, %2}
20035    fcmov%f1\t{%3, %0|%0, %3}
20036    cmov%O2%C1\t{%2, %0|%0, %2}
20037    cmov%O2%c1\t{%3, %0|%0, %3}"
20038   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20039    (set_attr "mode" "DF")])
20040
20041 (define_split
20042   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20043         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20044                                 [(match_operand 4 "flags_reg_operand" "")
20045                                  (const_int 0)])
20046                       (match_operand:DF 2 "nonimmediate_operand" "")
20047                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20048   "!TARGET_64BIT && reload_completed"
20049   [(set (match_dup 2)
20050         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20051                       (match_dup 5)
20052                       (match_dup 6)))
20053    (set (match_dup 3)
20054         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20055                       (match_dup 7)
20056                       (match_dup 8)))]
20057   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20058    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20059
20060 (define_insn "*movxfcc_1"
20061   [(set (match_operand:XF 0 "register_operand" "=f,f")
20062         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20063                                 [(reg FLAGS_REG) (const_int 0)])
20064                       (match_operand:XF 2 "register_operand" "f,0")
20065                       (match_operand:XF 3 "register_operand" "0,f")))]
20066   "TARGET_80387 && TARGET_CMOVE"
20067   "@
20068    fcmov%F1\t{%2, %0|%0, %2}
20069    fcmov%f1\t{%3, %0|%0, %3}"
20070   [(set_attr "type" "fcmov")
20071    (set_attr "mode" "XF")])
20072
20073 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20074 ;; the scalar versions to have only XMM registers as operands.
20075
20076 ;; SSE5 conditional move
20077 (define_insn "*sse5_pcmov_<mode>"
20078   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20079         (if_then_else:MODEF
20080           (match_operand:MODEF 1 "register_operand" "x,0")
20081           (match_operand:MODEF 2 "register_operand" "0,x")
20082           (match_operand:MODEF 3 "register_operand" "x,x")))]
20083   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20084   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20085   [(set_attr "type" "sse4arg")])
20086
20087 ;; These versions of the min/max patterns are intentionally ignorant of
20088 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20089 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20090 ;; are undefined in this condition, we're certain this is correct.
20091
20092 (define_insn "*avx_<code><mode>3"
20093   [(set (match_operand:MODEF 0 "register_operand" "=x")
20094         (smaxmin:MODEF
20095           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20096           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20097   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20098   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20099   [(set_attr "type" "sseadd")
20100    (set_attr "prefix" "vex")
20101    (set_attr "mode" "<MODE>")])
20102
20103 (define_insn "<code><mode>3"
20104   [(set (match_operand:MODEF 0 "register_operand" "=x")
20105         (smaxmin:MODEF
20106           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20107           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20108   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20109   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20110   [(set_attr "type" "sseadd")
20111    (set_attr "mode" "<MODE>")])
20112
20113 ;; These versions of the min/max patterns implement exactly the operations
20114 ;;   min = (op1 < op2 ? op1 : op2)
20115 ;;   max = (!(op1 < op2) ? op1 : op2)
20116 ;; Their operands are not commutative, and thus they may be used in the
20117 ;; presence of -0.0 and NaN.
20118
20119 (define_insn "*avx_ieee_smin<mode>3"
20120   [(set (match_operand:MODEF 0 "register_operand" "=x")
20121         (unspec:MODEF
20122           [(match_operand:MODEF 1 "register_operand" "x")
20123            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20124          UNSPEC_IEEE_MIN))]
20125   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20126   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20127   [(set_attr "type" "sseadd")
20128    (set_attr "prefix" "vex")
20129    (set_attr "mode" "<MODE>")])
20130
20131 (define_insn "*ieee_smin<mode>3"
20132   [(set (match_operand:MODEF 0 "register_operand" "=x")
20133         (unspec:MODEF
20134           [(match_operand:MODEF 1 "register_operand" "0")
20135            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20136          UNSPEC_IEEE_MIN))]
20137   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20138   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20139   [(set_attr "type" "sseadd")
20140    (set_attr "mode" "<MODE>")])
20141
20142 (define_insn "*avx_ieee_smax<mode>3"
20143   [(set (match_operand:MODEF 0 "register_operand" "=x")
20144         (unspec:MODEF
20145           [(match_operand:MODEF 1 "register_operand" "0")
20146            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20147          UNSPEC_IEEE_MAX))]
20148   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20149   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20150   [(set_attr "type" "sseadd")
20151    (set_attr "prefix" "vex")
20152    (set_attr "mode" "<MODE>")])
20153
20154 (define_insn "*ieee_smax<mode>3"
20155   [(set (match_operand:MODEF 0 "register_operand" "=x")
20156         (unspec:MODEF
20157           [(match_operand:MODEF 1 "register_operand" "0")
20158            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20159          UNSPEC_IEEE_MAX))]
20160   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20161   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20162   [(set_attr "type" "sseadd")
20163    (set_attr "mode" "<MODE>")])
20164
20165 ;; Make two stack loads independent:
20166 ;;   fld aa              fld aa
20167 ;;   fld %st(0)     ->   fld bb
20168 ;;   fmul bb             fmul %st(1), %st
20169 ;;
20170 ;; Actually we only match the last two instructions for simplicity.
20171 (define_peephole2
20172   [(set (match_operand 0 "fp_register_operand" "")
20173         (match_operand 1 "fp_register_operand" ""))
20174    (set (match_dup 0)
20175         (match_operator 2 "binary_fp_operator"
20176            [(match_dup 0)
20177             (match_operand 3 "memory_operand" "")]))]
20178   "REGNO (operands[0]) != REGNO (operands[1])"
20179   [(set (match_dup 0) (match_dup 3))
20180    (set (match_dup 0) (match_dup 4))]
20181
20182   ;; The % modifier is not operational anymore in peephole2's, so we have to
20183   ;; swap the operands manually in the case of addition and multiplication.
20184   "if (COMMUTATIVE_ARITH_P (operands[2]))
20185      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20186                                  operands[0], operands[1]);
20187    else
20188      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20189                                  operands[1], operands[0]);")
20190
20191 ;; Conditional addition patterns
20192 (define_expand "add<mode>cc"
20193   [(match_operand:SWI 0 "register_operand" "")
20194    (match_operand 1 "comparison_operator" "")
20195    (match_operand:SWI 2 "register_operand" "")
20196    (match_operand:SWI 3 "const_int_operand" "")]
20197   ""
20198   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20199
20200 \f
20201 ;; Misc patterns (?)
20202
20203 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20204 ;; Otherwise there will be nothing to keep
20205 ;;
20206 ;; [(set (reg ebp) (reg esp))]
20207 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20208 ;;  (clobber (eflags)]
20209 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20210 ;;
20211 ;; in proper program order.
20212 (define_insn "pro_epilogue_adjust_stack_1"
20213   [(set (match_operand:SI 0 "register_operand" "=r,r")
20214         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20215                  (match_operand:SI 2 "immediate_operand" "i,i")))
20216    (clobber (reg:CC FLAGS_REG))
20217    (clobber (mem:BLK (scratch)))]
20218   "!TARGET_64BIT"
20219 {
20220   switch (get_attr_type (insn))
20221     {
20222     case TYPE_IMOV:
20223       return "mov{l}\t{%1, %0|%0, %1}";
20224
20225     case TYPE_ALU:
20226       if (CONST_INT_P (operands[2])
20227           && (INTVAL (operands[2]) == 128
20228               || (INTVAL (operands[2]) < 0
20229                   && INTVAL (operands[2]) != -128)))
20230         {
20231           operands[2] = GEN_INT (-INTVAL (operands[2]));
20232           return "sub{l}\t{%2, %0|%0, %2}";
20233         }
20234       return "add{l}\t{%2, %0|%0, %2}";
20235
20236     case TYPE_LEA:
20237       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20238       return "lea{l}\t{%a2, %0|%0, %a2}";
20239
20240     default:
20241       gcc_unreachable ();
20242     }
20243 }
20244   [(set (attr "type")
20245         (cond [(eq_attr "alternative" "0")
20246                  (const_string "alu")
20247                (match_operand:SI 2 "const0_operand" "")
20248                  (const_string "imov")
20249               ]
20250               (const_string "lea")))
20251    (set_attr "mode" "SI")])
20252
20253 (define_insn "pro_epilogue_adjust_stack_rex64"
20254   [(set (match_operand:DI 0 "register_operand" "=r,r")
20255         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20256                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20257    (clobber (reg:CC FLAGS_REG))
20258    (clobber (mem:BLK (scratch)))]
20259   "TARGET_64BIT"
20260 {
20261   switch (get_attr_type (insn))
20262     {
20263     case TYPE_IMOV:
20264       return "mov{q}\t{%1, %0|%0, %1}";
20265
20266     case TYPE_ALU:
20267       if (CONST_INT_P (operands[2])
20268           /* Avoid overflows.  */
20269           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20270           && (INTVAL (operands[2]) == 128
20271               || (INTVAL (operands[2]) < 0
20272                   && INTVAL (operands[2]) != -128)))
20273         {
20274           operands[2] = GEN_INT (-INTVAL (operands[2]));
20275           return "sub{q}\t{%2, %0|%0, %2}";
20276         }
20277       return "add{q}\t{%2, %0|%0, %2}";
20278
20279     case TYPE_LEA:
20280       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20281       return "lea{q}\t{%a2, %0|%0, %a2}";
20282
20283     default:
20284       gcc_unreachable ();
20285     }
20286 }
20287   [(set (attr "type")
20288         (cond [(eq_attr "alternative" "0")
20289                  (const_string "alu")
20290                (match_operand:DI 2 "const0_operand" "")
20291                  (const_string "imov")
20292               ]
20293               (const_string "lea")))
20294    (set_attr "mode" "DI")])
20295
20296 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20297   [(set (match_operand:DI 0 "register_operand" "=r,r")
20298         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20299                  (match_operand:DI 3 "immediate_operand" "i,i")))
20300    (use (match_operand:DI 2 "register_operand" "r,r"))
20301    (clobber (reg:CC FLAGS_REG))
20302    (clobber (mem:BLK (scratch)))]
20303   "TARGET_64BIT"
20304 {
20305   switch (get_attr_type (insn))
20306     {
20307     case TYPE_ALU:
20308       return "add{q}\t{%2, %0|%0, %2}";
20309
20310     case TYPE_LEA:
20311       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20312       return "lea{q}\t{%a2, %0|%0, %a2}";
20313
20314     default:
20315       gcc_unreachable ();
20316     }
20317 }
20318   [(set_attr "type" "alu,lea")
20319    (set_attr "mode" "DI")])
20320
20321 (define_insn "allocate_stack_worker_32"
20322   [(set (match_operand:SI 0 "register_operand" "=a")
20323         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20324                             UNSPECV_STACK_PROBE))
20325    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20326    (clobber (reg:CC FLAGS_REG))]
20327   "!TARGET_64BIT && TARGET_STACK_PROBE"
20328   "call\t___chkstk"
20329   [(set_attr "type" "multi")
20330    (set_attr "length" "5")])
20331
20332 (define_insn "allocate_stack_worker_64"
20333   [(set (match_operand:DI 0 "register_operand" "=a")
20334         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20335                             UNSPECV_STACK_PROBE))
20336    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20337    (clobber (reg:DI R10_REG))
20338    (clobber (reg:DI R11_REG))
20339    (clobber (reg:CC FLAGS_REG))]
20340   "TARGET_64BIT && TARGET_STACK_PROBE"
20341   "call\t___chkstk"
20342   [(set_attr "type" "multi")
20343    (set_attr "length" "5")])
20344
20345 (define_expand "allocate_stack"
20346   [(match_operand 0 "register_operand" "")
20347    (match_operand 1 "general_operand" "")]
20348   "TARGET_STACK_PROBE"
20349 {
20350   rtx x;
20351
20352 #ifndef CHECK_STACK_LIMIT
20353 #define CHECK_STACK_LIMIT 0
20354 #endif
20355
20356   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20357       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20358     {
20359       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20360                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20361       if (x != stack_pointer_rtx)
20362         emit_move_insn (stack_pointer_rtx, x);
20363     }
20364   else
20365     {
20366       x = copy_to_mode_reg (Pmode, operands[1]);
20367       if (TARGET_64BIT)
20368         x = gen_allocate_stack_worker_64 (x, x);
20369       else
20370         x = gen_allocate_stack_worker_32 (x, x);
20371       emit_insn (x);
20372     }
20373
20374   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20375   DONE;
20376 })
20377
20378 (define_expand "builtin_setjmp_receiver"
20379   [(label_ref (match_operand 0 "" ""))]
20380   "!TARGET_64BIT && flag_pic"
20381 {
20382 #if TARGET_MACHO
20383   if (TARGET_MACHO)
20384     {
20385       rtx xops[3];
20386       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20387       rtx label_rtx = gen_label_rtx ();
20388       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20389       xops[0] = xops[1] = picreg;
20390       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20391       ix86_expand_binary_operator (MINUS, SImode, xops);
20392     }
20393   else
20394 #endif
20395     emit_insn (gen_set_got (pic_offset_table_rtx));
20396   DONE;
20397 })
20398 \f
20399 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20400
20401 (define_split
20402   [(set (match_operand 0 "register_operand" "")
20403         (match_operator 3 "promotable_binary_operator"
20404            [(match_operand 1 "register_operand" "")
20405             (match_operand 2 "aligned_operand" "")]))
20406    (clobber (reg:CC FLAGS_REG))]
20407   "! TARGET_PARTIAL_REG_STALL && reload_completed
20408    && ((GET_MODE (operands[0]) == HImode
20409         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20410             /* ??? next two lines just !satisfies_constraint_K (...) */
20411             || !CONST_INT_P (operands[2])
20412             || satisfies_constraint_K (operands[2])))
20413        || (GET_MODE (operands[0]) == QImode
20414            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20415   [(parallel [(set (match_dup 0)
20416                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20417               (clobber (reg:CC FLAGS_REG))])]
20418   "operands[0] = gen_lowpart (SImode, operands[0]);
20419    operands[1] = gen_lowpart (SImode, operands[1]);
20420    if (GET_CODE (operands[3]) != ASHIFT)
20421      operands[2] = gen_lowpart (SImode, operands[2]);
20422    PUT_MODE (operands[3], SImode);")
20423
20424 ; Promote the QImode tests, as i386 has encoding of the AND
20425 ; instruction with 32-bit sign-extended immediate and thus the
20426 ; instruction size is unchanged, except in the %eax case for
20427 ; which it is increased by one byte, hence the ! optimize_size.
20428 (define_split
20429   [(set (match_operand 0 "flags_reg_operand" "")
20430         (match_operator 2 "compare_operator"
20431           [(and (match_operand 3 "aligned_operand" "")
20432                 (match_operand 4 "const_int_operand" ""))
20433            (const_int 0)]))
20434    (set (match_operand 1 "register_operand" "")
20435         (and (match_dup 3) (match_dup 4)))]
20436   "! TARGET_PARTIAL_REG_STALL && reload_completed
20437    && optimize_insn_for_speed_p ()
20438    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20439        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20440    /* Ensure that the operand will remain sign-extended immediate.  */
20441    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20442   [(parallel [(set (match_dup 0)
20443                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20444                                     (const_int 0)]))
20445               (set (match_dup 1)
20446                    (and:SI (match_dup 3) (match_dup 4)))])]
20447 {
20448   operands[4]
20449     = gen_int_mode (INTVAL (operands[4])
20450                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20451   operands[1] = gen_lowpart (SImode, operands[1]);
20452   operands[3] = gen_lowpart (SImode, operands[3]);
20453 })
20454
20455 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20456 ; the TEST instruction with 32-bit sign-extended immediate and thus
20457 ; the instruction size would at least double, which is not what we
20458 ; want even with ! optimize_size.
20459 (define_split
20460   [(set (match_operand 0 "flags_reg_operand" "")
20461         (match_operator 1 "compare_operator"
20462           [(and (match_operand:HI 2 "aligned_operand" "")
20463                 (match_operand:HI 3 "const_int_operand" ""))
20464            (const_int 0)]))]
20465   "! TARGET_PARTIAL_REG_STALL && reload_completed
20466    && ! TARGET_FAST_PREFIX
20467    && optimize_insn_for_speed_p ()
20468    /* Ensure that the operand will remain sign-extended immediate.  */
20469    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20470   [(set (match_dup 0)
20471         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20472                          (const_int 0)]))]
20473 {
20474   operands[3]
20475     = gen_int_mode (INTVAL (operands[3])
20476                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20477   operands[2] = gen_lowpart (SImode, operands[2]);
20478 })
20479
20480 (define_split
20481   [(set (match_operand 0 "register_operand" "")
20482         (neg (match_operand 1 "register_operand" "")))
20483    (clobber (reg:CC FLAGS_REG))]
20484   "! TARGET_PARTIAL_REG_STALL && reload_completed
20485    && (GET_MODE (operands[0]) == HImode
20486        || (GET_MODE (operands[0]) == QImode
20487            && (TARGET_PROMOTE_QImode
20488                || optimize_insn_for_size_p ())))"
20489   [(parallel [(set (match_dup 0)
20490                    (neg:SI (match_dup 1)))
20491               (clobber (reg:CC FLAGS_REG))])]
20492   "operands[0] = gen_lowpart (SImode, operands[0]);
20493    operands[1] = gen_lowpart (SImode, operands[1]);")
20494
20495 (define_split
20496   [(set (match_operand 0 "register_operand" "")
20497         (not (match_operand 1 "register_operand" "")))]
20498   "! TARGET_PARTIAL_REG_STALL && reload_completed
20499    && (GET_MODE (operands[0]) == HImode
20500        || (GET_MODE (operands[0]) == QImode
20501            && (TARGET_PROMOTE_QImode
20502                || optimize_insn_for_size_p ())))"
20503   [(set (match_dup 0)
20504         (not:SI (match_dup 1)))]
20505   "operands[0] = gen_lowpart (SImode, operands[0]);
20506    operands[1] = gen_lowpart (SImode, operands[1]);")
20507
20508 (define_split
20509   [(set (match_operand 0 "register_operand" "")
20510         (if_then_else (match_operator 1 "comparison_operator"
20511                                 [(reg FLAGS_REG) (const_int 0)])
20512                       (match_operand 2 "register_operand" "")
20513                       (match_operand 3 "register_operand" "")))]
20514   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20515    && (GET_MODE (operands[0]) == HImode
20516        || (GET_MODE (operands[0]) == QImode
20517            && (TARGET_PROMOTE_QImode
20518                || optimize_insn_for_size_p ())))"
20519   [(set (match_dup 0)
20520         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20521   "operands[0] = gen_lowpart (SImode, operands[0]);
20522    operands[2] = gen_lowpart (SImode, operands[2]);
20523    operands[3] = gen_lowpart (SImode, operands[3]);")
20524
20525 \f
20526 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20527 ;; transform a complex memory operation into two memory to register operations.
20528
20529 ;; Don't push memory operands
20530 (define_peephole2
20531   [(set (match_operand:SI 0 "push_operand" "")
20532         (match_operand:SI 1 "memory_operand" ""))
20533    (match_scratch:SI 2 "r")]
20534   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20535    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20536   [(set (match_dup 2) (match_dup 1))
20537    (set (match_dup 0) (match_dup 2))]
20538   "")
20539
20540 (define_peephole2
20541   [(set (match_operand:DI 0 "push_operand" "")
20542         (match_operand:DI 1 "memory_operand" ""))
20543    (match_scratch:DI 2 "r")]
20544   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20545    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20546   [(set (match_dup 2) (match_dup 1))
20547    (set (match_dup 0) (match_dup 2))]
20548   "")
20549
20550 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20551 ;; SImode pushes.
20552 (define_peephole2
20553   [(set (match_operand:SF 0 "push_operand" "")
20554         (match_operand:SF 1 "memory_operand" ""))
20555    (match_scratch:SF 2 "r")]
20556   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20557    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20558   [(set (match_dup 2) (match_dup 1))
20559    (set (match_dup 0) (match_dup 2))]
20560   "")
20561
20562 (define_peephole2
20563   [(set (match_operand:HI 0 "push_operand" "")
20564         (match_operand:HI 1 "memory_operand" ""))
20565    (match_scratch:HI 2 "r")]
20566   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20567    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20568   [(set (match_dup 2) (match_dup 1))
20569    (set (match_dup 0) (match_dup 2))]
20570   "")
20571
20572 (define_peephole2
20573   [(set (match_operand:QI 0 "push_operand" "")
20574         (match_operand:QI 1 "memory_operand" ""))
20575    (match_scratch:QI 2 "q")]
20576   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20577    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20578   [(set (match_dup 2) (match_dup 1))
20579    (set (match_dup 0) (match_dup 2))]
20580   "")
20581
20582 ;; Don't move an immediate directly to memory when the instruction
20583 ;; gets too big.
20584 (define_peephole2
20585   [(match_scratch:SI 1 "r")
20586    (set (match_operand:SI 0 "memory_operand" "")
20587         (const_int 0))]
20588   "optimize_insn_for_speed_p ()
20589    && ! TARGET_USE_MOV0
20590    && TARGET_SPLIT_LONG_MOVES
20591    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20592    && peep2_regno_dead_p (0, FLAGS_REG)"
20593   [(parallel [(set (match_dup 1) (const_int 0))
20594               (clobber (reg:CC FLAGS_REG))])
20595    (set (match_dup 0) (match_dup 1))]
20596   "")
20597
20598 (define_peephole2
20599   [(match_scratch:HI 1 "r")
20600    (set (match_operand:HI 0 "memory_operand" "")
20601         (const_int 0))]
20602   "optimize_insn_for_speed_p ()
20603    && ! TARGET_USE_MOV0
20604    && TARGET_SPLIT_LONG_MOVES
20605    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20606    && peep2_regno_dead_p (0, FLAGS_REG)"
20607   [(parallel [(set (match_dup 2) (const_int 0))
20608               (clobber (reg:CC FLAGS_REG))])
20609    (set (match_dup 0) (match_dup 1))]
20610   "operands[2] = gen_lowpart (SImode, operands[1]);")
20611
20612 (define_peephole2
20613   [(match_scratch:QI 1 "q")
20614    (set (match_operand:QI 0 "memory_operand" "")
20615         (const_int 0))]
20616   "optimize_insn_for_speed_p ()
20617    && ! TARGET_USE_MOV0
20618    && TARGET_SPLIT_LONG_MOVES
20619    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20620    && peep2_regno_dead_p (0, FLAGS_REG)"
20621   [(parallel [(set (match_dup 2) (const_int 0))
20622               (clobber (reg:CC FLAGS_REG))])
20623    (set (match_dup 0) (match_dup 1))]
20624   "operands[2] = gen_lowpart (SImode, operands[1]);")
20625
20626 (define_peephole2
20627   [(match_scratch:SI 2 "r")
20628    (set (match_operand:SI 0 "memory_operand" "")
20629         (match_operand:SI 1 "immediate_operand" ""))]
20630   "optimize_insn_for_speed_p ()
20631    && TARGET_SPLIT_LONG_MOVES
20632    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20633   [(set (match_dup 2) (match_dup 1))
20634    (set (match_dup 0) (match_dup 2))]
20635   "")
20636
20637 (define_peephole2
20638   [(match_scratch:HI 2 "r")
20639    (set (match_operand:HI 0 "memory_operand" "")
20640         (match_operand:HI 1 "immediate_operand" ""))]
20641   "optimize_insn_for_speed_p ()
20642    && TARGET_SPLIT_LONG_MOVES
20643    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20644   [(set (match_dup 2) (match_dup 1))
20645    (set (match_dup 0) (match_dup 2))]
20646   "")
20647
20648 (define_peephole2
20649   [(match_scratch:QI 2 "q")
20650    (set (match_operand:QI 0 "memory_operand" "")
20651         (match_operand:QI 1 "immediate_operand" ""))]
20652   "optimize_insn_for_speed_p ()
20653    && TARGET_SPLIT_LONG_MOVES
20654    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20655   [(set (match_dup 2) (match_dup 1))
20656    (set (match_dup 0) (match_dup 2))]
20657   "")
20658
20659 ;; Don't compare memory with zero, load and use a test instead.
20660 (define_peephole2
20661   [(set (match_operand 0 "flags_reg_operand" "")
20662         (match_operator 1 "compare_operator"
20663           [(match_operand:SI 2 "memory_operand" "")
20664            (const_int 0)]))
20665    (match_scratch:SI 3 "r")]
20666   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20667   [(set (match_dup 3) (match_dup 2))
20668    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20669   "")
20670
20671 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20672 ;; Don't split NOTs with a displacement operand, because resulting XOR
20673 ;; will not be pairable anyway.
20674 ;;
20675 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20676 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20677 ;; so this split helps here as well.
20678 ;;
20679 ;; Note: Can't do this as a regular split because we can't get proper
20680 ;; lifetime information then.
20681
20682 (define_peephole2
20683   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20684         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20685   "optimize_insn_for_speed_p ()
20686    && ((TARGET_NOT_UNPAIRABLE
20687         && (!MEM_P (operands[0])
20688             || !memory_displacement_operand (operands[0], SImode)))
20689        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20690    && peep2_regno_dead_p (0, FLAGS_REG)"
20691   [(parallel [(set (match_dup 0)
20692                    (xor:SI (match_dup 1) (const_int -1)))
20693               (clobber (reg:CC FLAGS_REG))])]
20694   "")
20695
20696 (define_peephole2
20697   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20698         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20699   "optimize_insn_for_speed_p ()
20700    && ((TARGET_NOT_UNPAIRABLE
20701         && (!MEM_P (operands[0])
20702             || !memory_displacement_operand (operands[0], HImode)))
20703        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20704    && peep2_regno_dead_p (0, FLAGS_REG)"
20705   [(parallel [(set (match_dup 0)
20706                    (xor:HI (match_dup 1) (const_int -1)))
20707               (clobber (reg:CC FLAGS_REG))])]
20708   "")
20709
20710 (define_peephole2
20711   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20712         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20713   "optimize_insn_for_speed_p ()
20714    && ((TARGET_NOT_UNPAIRABLE
20715         && (!MEM_P (operands[0])
20716             || !memory_displacement_operand (operands[0], QImode)))
20717        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20718    && peep2_regno_dead_p (0, FLAGS_REG)"
20719   [(parallel [(set (match_dup 0)
20720                    (xor:QI (match_dup 1) (const_int -1)))
20721               (clobber (reg:CC FLAGS_REG))])]
20722   "")
20723
20724 ;; Non pairable "test imm, reg" instructions can be translated to
20725 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20726 ;; byte opcode instead of two, have a short form for byte operands),
20727 ;; so do it for other CPUs as well.  Given that the value was dead,
20728 ;; this should not create any new dependencies.  Pass on the sub-word
20729 ;; versions if we're concerned about partial register stalls.
20730
20731 (define_peephole2
20732   [(set (match_operand 0 "flags_reg_operand" "")
20733         (match_operator 1 "compare_operator"
20734           [(and:SI (match_operand:SI 2 "register_operand" "")
20735                    (match_operand:SI 3 "immediate_operand" ""))
20736            (const_int 0)]))]
20737   "ix86_match_ccmode (insn, CCNOmode)
20738    && (true_regnum (operands[2]) != AX_REG
20739        || satisfies_constraint_K (operands[3]))
20740    && peep2_reg_dead_p (1, operands[2])"
20741   [(parallel
20742      [(set (match_dup 0)
20743            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20744                             (const_int 0)]))
20745       (set (match_dup 2)
20746            (and:SI (match_dup 2) (match_dup 3)))])]
20747   "")
20748
20749 ;; We don't need to handle HImode case, because it will be promoted to SImode
20750 ;; on ! TARGET_PARTIAL_REG_STALL
20751
20752 (define_peephole2
20753   [(set (match_operand 0 "flags_reg_operand" "")
20754         (match_operator 1 "compare_operator"
20755           [(and:QI (match_operand:QI 2 "register_operand" "")
20756                    (match_operand:QI 3 "immediate_operand" ""))
20757            (const_int 0)]))]
20758   "! TARGET_PARTIAL_REG_STALL
20759    && ix86_match_ccmode (insn, CCNOmode)
20760    && true_regnum (operands[2]) != AX_REG
20761    && peep2_reg_dead_p (1, operands[2])"
20762   [(parallel
20763      [(set (match_dup 0)
20764            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20765                             (const_int 0)]))
20766       (set (match_dup 2)
20767            (and:QI (match_dup 2) (match_dup 3)))])]
20768   "")
20769
20770 (define_peephole2
20771   [(set (match_operand 0 "flags_reg_operand" "")
20772         (match_operator 1 "compare_operator"
20773           [(and:SI
20774              (zero_extract:SI
20775                (match_operand 2 "ext_register_operand" "")
20776                (const_int 8)
20777                (const_int 8))
20778              (match_operand 3 "const_int_operand" ""))
20779            (const_int 0)]))]
20780   "! TARGET_PARTIAL_REG_STALL
20781    && ix86_match_ccmode (insn, CCNOmode)
20782    && true_regnum (operands[2]) != AX_REG
20783    && peep2_reg_dead_p (1, operands[2])"
20784   [(parallel [(set (match_dup 0)
20785                    (match_op_dup 1
20786                      [(and:SI
20787                         (zero_extract:SI
20788                           (match_dup 2)
20789                           (const_int 8)
20790                           (const_int 8))
20791                         (match_dup 3))
20792                       (const_int 0)]))
20793               (set (zero_extract:SI (match_dup 2)
20794                                     (const_int 8)
20795                                     (const_int 8))
20796                    (and:SI
20797                      (zero_extract:SI
20798                        (match_dup 2)
20799                        (const_int 8)
20800                        (const_int 8))
20801                      (match_dup 3)))])]
20802   "")
20803
20804 ;; Don't do logical operations with memory inputs.
20805 (define_peephole2
20806   [(match_scratch:SI 2 "r")
20807    (parallel [(set (match_operand:SI 0 "register_operand" "")
20808                    (match_operator:SI 3 "arith_or_logical_operator"
20809                      [(match_dup 0)
20810                       (match_operand:SI 1 "memory_operand" "")]))
20811               (clobber (reg:CC FLAGS_REG))])]
20812   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20813   [(set (match_dup 2) (match_dup 1))
20814    (parallel [(set (match_dup 0)
20815                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20816               (clobber (reg:CC FLAGS_REG))])]
20817   "")
20818
20819 (define_peephole2
20820   [(match_scratch:SI 2 "r")
20821    (parallel [(set (match_operand:SI 0 "register_operand" "")
20822                    (match_operator:SI 3 "arith_or_logical_operator"
20823                      [(match_operand:SI 1 "memory_operand" "")
20824                       (match_dup 0)]))
20825               (clobber (reg:CC FLAGS_REG))])]
20826   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20827   [(set (match_dup 2) (match_dup 1))
20828    (parallel [(set (match_dup 0)
20829                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20830               (clobber (reg:CC FLAGS_REG))])]
20831   "")
20832
20833 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20834 ;; refers to the destination of the load!
20835
20836 (define_peephole2
20837   [(set (match_operand:SI 0 "register_operand" "")
20838         (match_operand:SI 1 "register_operand" ""))
20839    (parallel [(set (match_dup 0)
20840                    (match_operator:SI 3 "commutative_operator"
20841                      [(match_dup 0)
20842                       (match_operand:SI 2 "memory_operand" "")]))
20843               (clobber (reg:CC FLAGS_REG))])]
20844   "REGNO (operands[0]) != REGNO (operands[1])
20845    && GENERAL_REGNO_P (REGNO (operands[0]))
20846    && GENERAL_REGNO_P (REGNO (operands[1]))"
20847   [(set (match_dup 0) (match_dup 4))
20848    (parallel [(set (match_dup 0)
20849                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20850               (clobber (reg:CC FLAGS_REG))])]
20851   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20852
20853 (define_peephole2
20854   [(set (match_operand 0 "register_operand" "")
20855         (match_operand 1 "register_operand" ""))
20856    (set (match_dup 0)
20857                    (match_operator 3 "commutative_operator"
20858                      [(match_dup 0)
20859                       (match_operand 2 "memory_operand" "")]))]
20860   "REGNO (operands[0]) != REGNO (operands[1])
20861    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
20862        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20863   [(set (match_dup 0) (match_dup 2))
20864    (set (match_dup 0)
20865         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20866   "")
20867
20868 ; Don't do logical operations with memory outputs
20869 ;
20870 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20871 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20872 ; the same decoder scheduling characteristics as the original.
20873
20874 (define_peephole2
20875   [(match_scratch:SI 2 "r")
20876    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20877                    (match_operator:SI 3 "arith_or_logical_operator"
20878                      [(match_dup 0)
20879                       (match_operand:SI 1 "nonmemory_operand" "")]))
20880               (clobber (reg:CC FLAGS_REG))])]
20881   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20882   [(set (match_dup 2) (match_dup 0))
20883    (parallel [(set (match_dup 2)
20884                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20885               (clobber (reg:CC FLAGS_REG))])
20886    (set (match_dup 0) (match_dup 2))]
20887   "")
20888
20889 (define_peephole2
20890   [(match_scratch:SI 2 "r")
20891    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20892                    (match_operator:SI 3 "arith_or_logical_operator"
20893                      [(match_operand:SI 1 "nonmemory_operand" "")
20894                       (match_dup 0)]))
20895               (clobber (reg:CC FLAGS_REG))])]
20896   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20897   [(set (match_dup 2) (match_dup 0))
20898    (parallel [(set (match_dup 2)
20899                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20900               (clobber (reg:CC FLAGS_REG))])
20901    (set (match_dup 0) (match_dup 2))]
20902   "")
20903
20904 ;; Attempt to always use XOR for zeroing registers.
20905 (define_peephole2
20906   [(set (match_operand 0 "register_operand" "")
20907         (match_operand 1 "const0_operand" ""))]
20908   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20909    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20910    && GENERAL_REG_P (operands[0])
20911    && peep2_regno_dead_p (0, FLAGS_REG)"
20912   [(parallel [(set (match_dup 0) (const_int 0))
20913               (clobber (reg:CC FLAGS_REG))])]
20914 {
20915   operands[0] = gen_lowpart (word_mode, operands[0]);
20916 })
20917
20918 (define_peephole2
20919   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20920         (const_int 0))]
20921   "(GET_MODE (operands[0]) == QImode
20922     || GET_MODE (operands[0]) == HImode)
20923    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20924    && peep2_regno_dead_p (0, FLAGS_REG)"
20925   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20926               (clobber (reg:CC FLAGS_REG))])])
20927
20928 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20929 (define_peephole2
20930   [(set (match_operand 0 "register_operand" "")
20931         (const_int -1))]
20932   "(GET_MODE (operands[0]) == HImode
20933     || GET_MODE (operands[0]) == SImode
20934     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20935    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20936    && peep2_regno_dead_p (0, FLAGS_REG)"
20937   [(parallel [(set (match_dup 0) (const_int -1))
20938               (clobber (reg:CC FLAGS_REG))])]
20939   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20940                               operands[0]);")
20941
20942 ;; Attempt to convert simple leas to adds. These can be created by
20943 ;; move expanders.
20944 (define_peephole2
20945   [(set (match_operand:SI 0 "register_operand" "")
20946         (plus:SI (match_dup 0)
20947                  (match_operand:SI 1 "nonmemory_operand" "")))]
20948   "peep2_regno_dead_p (0, FLAGS_REG)"
20949   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20950               (clobber (reg:CC FLAGS_REG))])]
20951   "")
20952
20953 (define_peephole2
20954   [(set (match_operand:SI 0 "register_operand" "")
20955         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20956                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20957   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20958   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20959               (clobber (reg:CC FLAGS_REG))])]
20960   "operands[2] = gen_lowpart (SImode, operands[2]);")
20961
20962 (define_peephole2
20963   [(set (match_operand:DI 0 "register_operand" "")
20964         (plus:DI (match_dup 0)
20965                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20966   "peep2_regno_dead_p (0, FLAGS_REG)"
20967   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20968               (clobber (reg:CC FLAGS_REG))])]
20969   "")
20970
20971 (define_peephole2
20972   [(set (match_operand:SI 0 "register_operand" "")
20973         (mult:SI (match_dup 0)
20974                  (match_operand:SI 1 "const_int_operand" "")))]
20975   "exact_log2 (INTVAL (operands[1])) >= 0
20976    && peep2_regno_dead_p (0, FLAGS_REG)"
20977   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20978               (clobber (reg:CC FLAGS_REG))])]
20979   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20980
20981 (define_peephole2
20982   [(set (match_operand:DI 0 "register_operand" "")
20983         (mult:DI (match_dup 0)
20984                  (match_operand:DI 1 "const_int_operand" "")))]
20985   "exact_log2 (INTVAL (operands[1])) >= 0
20986    && peep2_regno_dead_p (0, FLAGS_REG)"
20987   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20988               (clobber (reg:CC FLAGS_REG))])]
20989   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20990
20991 (define_peephole2
20992   [(set (match_operand:SI 0 "register_operand" "")
20993         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20994                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20995   "exact_log2 (INTVAL (operands[2])) >= 0
20996    && REGNO (operands[0]) == REGNO (operands[1])
20997    && peep2_regno_dead_p (0, FLAGS_REG)"
20998   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20999               (clobber (reg:CC FLAGS_REG))])]
21000   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21001
21002 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
21003 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
21004 ;; many CPUs it is also faster, since special hardware to avoid esp
21005 ;; dependencies is present.
21006
21007 ;; While some of these conversions may be done using splitters, we use peepholes
21008 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21009
21010 ;; Convert prologue esp subtractions to push.
21011 ;; We need register to push.  In order to keep verify_flow_info happy we have
21012 ;; two choices
21013 ;; - use scratch and clobber it in order to avoid dependencies
21014 ;; - use already live register
21015 ;; We can't use the second way right now, since there is no reliable way how to
21016 ;; verify that given register is live.  First choice will also most likely in
21017 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
21018 ;; call clobbered registers are dead.  We may want to use base pointer as an
21019 ;; alternative when no register is available later.
21020
21021 (define_peephole2
21022   [(match_scratch:SI 0 "r")
21023    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21024               (clobber (reg:CC FLAGS_REG))
21025               (clobber (mem:BLK (scratch)))])]
21026   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21027   [(clobber (match_dup 0))
21028    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21029               (clobber (mem:BLK (scratch)))])])
21030
21031 (define_peephole2
21032   [(match_scratch:SI 0 "r")
21033    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21034               (clobber (reg:CC FLAGS_REG))
21035               (clobber (mem:BLK (scratch)))])]
21036   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21037   [(clobber (match_dup 0))
21038    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21039    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21040               (clobber (mem:BLK (scratch)))])])
21041
21042 ;; Convert esp subtractions to push.
21043 (define_peephole2
21044   [(match_scratch:SI 0 "r")
21045    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21046               (clobber (reg:CC FLAGS_REG))])]
21047   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21048   [(clobber (match_dup 0))
21049    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21050
21051 (define_peephole2
21052   [(match_scratch:SI 0 "r")
21053    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21054               (clobber (reg:CC FLAGS_REG))])]
21055   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21056   [(clobber (match_dup 0))
21057    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21058    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21059
21060 ;; Convert epilogue deallocator to pop.
21061 (define_peephole2
21062   [(match_scratch:SI 0 "r")
21063    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21064               (clobber (reg:CC FLAGS_REG))
21065               (clobber (mem:BLK (scratch)))])]
21066   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21067   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21068               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21069               (clobber (mem:BLK (scratch)))])]
21070   "")
21071
21072 ;; Two pops case is tricky, since pop causes dependency on destination register.
21073 ;; We use two registers if available.
21074 (define_peephole2
21075   [(match_scratch:SI 0 "r")
21076    (match_scratch:SI 1 "r")
21077    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21078               (clobber (reg:CC FLAGS_REG))
21079               (clobber (mem:BLK (scratch)))])]
21080   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21081   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21082               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21083               (clobber (mem:BLK (scratch)))])
21084    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21085               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21086   "")
21087
21088 (define_peephole2
21089   [(match_scratch:SI 0 "r")
21090    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21091               (clobber (reg:CC FLAGS_REG))
21092               (clobber (mem:BLK (scratch)))])]
21093   "optimize_insn_for_size_p ()"
21094   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21095               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21096               (clobber (mem:BLK (scratch)))])
21097    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21098               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21099   "")
21100
21101 ;; Convert esp additions to pop.
21102 (define_peephole2
21103   [(match_scratch:SI 0 "r")
21104    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21105               (clobber (reg:CC FLAGS_REG))])]
21106   ""
21107   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21108               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21109   "")
21110
21111 ;; Two pops case is tricky, since pop causes dependency on destination register.
21112 ;; We use two registers if available.
21113 (define_peephole2
21114   [(match_scratch:SI 0 "r")
21115    (match_scratch:SI 1 "r")
21116    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21117               (clobber (reg:CC FLAGS_REG))])]
21118   ""
21119   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21120               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21121    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21122               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21123   "")
21124
21125 (define_peephole2
21126   [(match_scratch:SI 0 "r")
21127    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21128               (clobber (reg:CC FLAGS_REG))])]
21129   "optimize_insn_for_size_p ()"
21130   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21131               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21132    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21133               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21134   "")
21135 \f
21136 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21137 ;; required and register dies.  Similarly for 128 to -128.
21138 (define_peephole2
21139   [(set (match_operand 0 "flags_reg_operand" "")
21140         (match_operator 1 "compare_operator"
21141           [(match_operand 2 "register_operand" "")
21142            (match_operand 3 "const_int_operand" "")]))]
21143   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21144      && incdec_operand (operands[3], GET_MODE (operands[3])))
21145     || (!TARGET_FUSE_CMP_AND_BRANCH
21146         && INTVAL (operands[3]) == 128))
21147    && ix86_match_ccmode (insn, CCGCmode)
21148    && peep2_reg_dead_p (1, operands[2])"
21149   [(parallel [(set (match_dup 0)
21150                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21151               (clobber (match_dup 2))])]
21152   "")
21153 \f
21154 (define_peephole2
21155   [(match_scratch:DI 0 "r")
21156    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21157               (clobber (reg:CC FLAGS_REG))
21158               (clobber (mem:BLK (scratch)))])]
21159   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21160   [(clobber (match_dup 0))
21161    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21162               (clobber (mem:BLK (scratch)))])])
21163
21164 (define_peephole2
21165   [(match_scratch:DI 0 "r")
21166    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21167               (clobber (reg:CC FLAGS_REG))
21168               (clobber (mem:BLK (scratch)))])]
21169   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21170   [(clobber (match_dup 0))
21171    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21172    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21173               (clobber (mem:BLK (scratch)))])])
21174
21175 ;; Convert esp subtractions to push.
21176 (define_peephole2
21177   [(match_scratch:DI 0 "r")
21178    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21179               (clobber (reg:CC FLAGS_REG))])]
21180   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21181   [(clobber (match_dup 0))
21182    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21183
21184 (define_peephole2
21185   [(match_scratch:DI 0 "r")
21186    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21187               (clobber (reg:CC FLAGS_REG))])]
21188   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21189   [(clobber (match_dup 0))
21190    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21191    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21192
21193 ;; Convert epilogue deallocator to pop.
21194 (define_peephole2
21195   [(match_scratch:DI 0 "r")
21196    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21197               (clobber (reg:CC FLAGS_REG))
21198               (clobber (mem:BLK (scratch)))])]
21199   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21200   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21201               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21202               (clobber (mem:BLK (scratch)))])]
21203   "")
21204
21205 ;; Two pops case is tricky, since pop causes dependency on destination register.
21206 ;; We use two registers if available.
21207 (define_peephole2
21208   [(match_scratch:DI 0 "r")
21209    (match_scratch:DI 1 "r")
21210    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21211               (clobber (reg:CC FLAGS_REG))
21212               (clobber (mem:BLK (scratch)))])]
21213   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21214   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21215               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21216               (clobber (mem:BLK (scratch)))])
21217    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21218               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21219   "")
21220
21221 (define_peephole2
21222   [(match_scratch:DI 0 "r")
21223    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21224               (clobber (reg:CC FLAGS_REG))
21225               (clobber (mem:BLK (scratch)))])]
21226   "optimize_insn_for_size_p ()"
21227   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21228               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21229               (clobber (mem:BLK (scratch)))])
21230    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21231               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21232   "")
21233
21234 ;; Convert esp additions to pop.
21235 (define_peephole2
21236   [(match_scratch:DI 0 "r")
21237    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21238               (clobber (reg:CC FLAGS_REG))])]
21239   ""
21240   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21241               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21242   "")
21243
21244 ;; Two pops case is tricky, since pop causes dependency on destination register.
21245 ;; We use two registers if available.
21246 (define_peephole2
21247   [(match_scratch:DI 0 "r")
21248    (match_scratch:DI 1 "r")
21249    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21250               (clobber (reg:CC FLAGS_REG))])]
21251   ""
21252   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21253               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21254    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21255               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21256   "")
21257
21258 (define_peephole2
21259   [(match_scratch:DI 0 "r")
21260    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21261               (clobber (reg:CC FLAGS_REG))])]
21262   "optimize_insn_for_size_p ()"
21263   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21264               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21265    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21266               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21267   "")
21268 \f
21269 ;; Convert imul by three, five and nine into lea
21270 (define_peephole2
21271   [(parallel
21272     [(set (match_operand:SI 0 "register_operand" "")
21273           (mult:SI (match_operand:SI 1 "register_operand" "")
21274                    (match_operand:SI 2 "const_int_operand" "")))
21275      (clobber (reg:CC FLAGS_REG))])]
21276   "INTVAL (operands[2]) == 3
21277    || INTVAL (operands[2]) == 5
21278    || INTVAL (operands[2]) == 9"
21279   [(set (match_dup 0)
21280         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21281                  (match_dup 1)))]
21282   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21283
21284 (define_peephole2
21285   [(parallel
21286     [(set (match_operand:SI 0 "register_operand" "")
21287           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21288                    (match_operand:SI 2 "const_int_operand" "")))
21289      (clobber (reg:CC FLAGS_REG))])]
21290   "optimize_insn_for_speed_p ()
21291    && (INTVAL (operands[2]) == 3
21292        || INTVAL (operands[2]) == 5
21293        || INTVAL (operands[2]) == 9)"
21294   [(set (match_dup 0) (match_dup 1))
21295    (set (match_dup 0)
21296         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21297                  (match_dup 0)))]
21298   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21299
21300 (define_peephole2
21301   [(parallel
21302     [(set (match_operand:DI 0 "register_operand" "")
21303           (mult:DI (match_operand:DI 1 "register_operand" "")
21304                    (match_operand:DI 2 "const_int_operand" "")))
21305      (clobber (reg:CC FLAGS_REG))])]
21306   "TARGET_64BIT
21307    && (INTVAL (operands[2]) == 3
21308        || INTVAL (operands[2]) == 5
21309        || INTVAL (operands[2]) == 9)"
21310   [(set (match_dup 0)
21311         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21312                  (match_dup 1)))]
21313   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21314
21315 (define_peephole2
21316   [(parallel
21317     [(set (match_operand:DI 0 "register_operand" "")
21318           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21319                    (match_operand:DI 2 "const_int_operand" "")))
21320      (clobber (reg:CC FLAGS_REG))])]
21321   "TARGET_64BIT
21322    && optimize_insn_for_speed_p ()
21323    && (INTVAL (operands[2]) == 3
21324        || INTVAL (operands[2]) == 5
21325        || INTVAL (operands[2]) == 9)"
21326   [(set (match_dup 0) (match_dup 1))
21327    (set (match_dup 0)
21328         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21329                  (match_dup 0)))]
21330   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21331
21332 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21333 ;; imul $32bit_imm, reg, reg is direct decoded.
21334 (define_peephole2
21335   [(match_scratch:DI 3 "r")
21336    (parallel [(set (match_operand:DI 0 "register_operand" "")
21337                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21338                             (match_operand:DI 2 "immediate_operand" "")))
21339               (clobber (reg:CC FLAGS_REG))])]
21340   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21341    && !satisfies_constraint_K (operands[2])"
21342   [(set (match_dup 3) (match_dup 1))
21343    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21344               (clobber (reg:CC FLAGS_REG))])]
21345 "")
21346
21347 (define_peephole2
21348   [(match_scratch:SI 3 "r")
21349    (parallel [(set (match_operand:SI 0 "register_operand" "")
21350                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21351                             (match_operand:SI 2 "immediate_operand" "")))
21352               (clobber (reg:CC FLAGS_REG))])]
21353   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21354    && !satisfies_constraint_K (operands[2])"
21355   [(set (match_dup 3) (match_dup 1))
21356    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21357               (clobber (reg:CC FLAGS_REG))])]
21358 "")
21359
21360 (define_peephole2
21361   [(match_scratch:SI 3 "r")
21362    (parallel [(set (match_operand:DI 0 "register_operand" "")
21363                    (zero_extend:DI
21364                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21365                               (match_operand:SI 2 "immediate_operand" ""))))
21366               (clobber (reg:CC FLAGS_REG))])]
21367   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21368    && !satisfies_constraint_K (operands[2])"
21369   [(set (match_dup 3) (match_dup 1))
21370    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21371               (clobber (reg:CC FLAGS_REG))])]
21372 "")
21373
21374 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21375 ;; Convert it into imul reg, reg
21376 ;; It would be better to force assembler to encode instruction using long
21377 ;; immediate, but there is apparently no way to do so.
21378 (define_peephole2
21379   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21380                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21381                             (match_operand:DI 2 "const_int_operand" "")))
21382               (clobber (reg:CC FLAGS_REG))])
21383    (match_scratch:DI 3 "r")]
21384   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21385    && satisfies_constraint_K (operands[2])"
21386   [(set (match_dup 3) (match_dup 2))
21387    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21388               (clobber (reg:CC FLAGS_REG))])]
21389 {
21390   if (!rtx_equal_p (operands[0], operands[1]))
21391     emit_move_insn (operands[0], operands[1]);
21392 })
21393
21394 (define_peephole2
21395   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21396                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21397                             (match_operand:SI 2 "const_int_operand" "")))
21398               (clobber (reg:CC FLAGS_REG))])
21399    (match_scratch:SI 3 "r")]
21400   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21401    && satisfies_constraint_K (operands[2])"
21402   [(set (match_dup 3) (match_dup 2))
21403    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21404               (clobber (reg:CC FLAGS_REG))])]
21405 {
21406   if (!rtx_equal_p (operands[0], operands[1]))
21407     emit_move_insn (operands[0], operands[1]);
21408 })
21409
21410 (define_peephole2
21411   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21412                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21413                             (match_operand:HI 2 "immediate_operand" "")))
21414               (clobber (reg:CC FLAGS_REG))])
21415    (match_scratch:HI 3 "r")]
21416   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21417   [(set (match_dup 3) (match_dup 2))
21418    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21419               (clobber (reg:CC FLAGS_REG))])]
21420 {
21421   if (!rtx_equal_p (operands[0], operands[1]))
21422     emit_move_insn (operands[0], operands[1]);
21423 })
21424
21425 ;; After splitting up read-modify operations, array accesses with memory
21426 ;; operands might end up in form:
21427 ;;  sall    $2, %eax
21428 ;;  movl    4(%esp), %edx
21429 ;;  addl    %edx, %eax
21430 ;; instead of pre-splitting:
21431 ;;  sall    $2, %eax
21432 ;;  addl    4(%esp), %eax
21433 ;; Turn it into:
21434 ;;  movl    4(%esp), %edx
21435 ;;  leal    (%edx,%eax,4), %eax
21436
21437 (define_peephole2
21438   [(parallel [(set (match_operand 0 "register_operand" "")
21439                    (ashift (match_operand 1 "register_operand" "")
21440                            (match_operand 2 "const_int_operand" "")))
21441                (clobber (reg:CC FLAGS_REG))])
21442    (set (match_operand 3 "register_operand")
21443         (match_operand 4 "x86_64_general_operand" ""))
21444    (parallel [(set (match_operand 5 "register_operand" "")
21445                    (plus (match_operand 6 "register_operand" "")
21446                          (match_operand 7 "register_operand" "")))
21447                    (clobber (reg:CC FLAGS_REG))])]
21448   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21449    /* Validate MODE for lea.  */
21450    && ((!TARGET_PARTIAL_REG_STALL
21451         && (GET_MODE (operands[0]) == QImode
21452             || GET_MODE (operands[0]) == HImode))
21453        || GET_MODE (operands[0]) == SImode
21454        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21455    /* We reorder load and the shift.  */
21456    && !rtx_equal_p (operands[1], operands[3])
21457    && !reg_overlap_mentioned_p (operands[0], operands[4])
21458    /* Last PLUS must consist of operand 0 and 3.  */
21459    && !rtx_equal_p (operands[0], operands[3])
21460    && (rtx_equal_p (operands[3], operands[6])
21461        || rtx_equal_p (operands[3], operands[7]))
21462    && (rtx_equal_p (operands[0], operands[6])
21463        || rtx_equal_p (operands[0], operands[7]))
21464    /* The intermediate operand 0 must die or be same as output.  */
21465    && (rtx_equal_p (operands[0], operands[5])
21466        || peep2_reg_dead_p (3, operands[0]))"
21467   [(set (match_dup 3) (match_dup 4))
21468    (set (match_dup 0) (match_dup 1))]
21469 {
21470   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21471   int scale = 1 << INTVAL (operands[2]);
21472   rtx index = gen_lowpart (Pmode, operands[1]);
21473   rtx base = gen_lowpart (Pmode, operands[3]);
21474   rtx dest = gen_lowpart (mode, operands[5]);
21475
21476   operands[1] = gen_rtx_PLUS (Pmode, base,
21477                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21478   if (mode != Pmode)
21479     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21480   operands[0] = dest;
21481 })
21482 \f
21483 ;; Call-value patterns last so that the wildcard operand does not
21484 ;; disrupt insn-recog's switch tables.
21485
21486 (define_insn "*call_value_pop_0"
21487   [(set (match_operand 0 "" "")
21488         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21489               (match_operand:SI 2 "" "")))
21490    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21491                             (match_operand:SI 3 "immediate_operand" "")))]
21492   "!TARGET_64BIT"
21493 {
21494   if (SIBLING_CALL_P (insn))
21495     return "jmp\t%P1";
21496   else
21497     return "call\t%P1";
21498 }
21499   [(set_attr "type" "callv")])
21500
21501 (define_insn "*call_value_pop_1"
21502   [(set (match_operand 0 "" "")
21503         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
21504               (match_operand:SI 2 "" "")))
21505    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21506                             (match_operand:SI 3 "immediate_operand" "i")))]
21507   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
21508 {
21509   if (constant_call_address_operand (operands[1], Pmode))
21510     return "call\t%P1";
21511   return "call\t%A1";
21512 }
21513   [(set_attr "type" "callv")])
21514
21515 (define_insn "*sibcall_value_pop_1"
21516   [(set (match_operand 0 "" "")
21517         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21518               (match_operand:SI 2 "" "")))
21519    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21520                             (match_operand:SI 3 "immediate_operand" "i,i")))]
21521   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
21522   "@
21523    jmp\t%P1
21524    jmp\t%A1"
21525   [(set_attr "type" "callv")])
21526
21527 (define_insn "*call_value_0"
21528   [(set (match_operand 0 "" "")
21529         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21530               (match_operand:SI 2 "" "")))]
21531   "!TARGET_64BIT"
21532 {
21533   if (SIBLING_CALL_P (insn))
21534     return "jmp\t%P1";
21535   else
21536     return "call\t%P1";
21537 }
21538   [(set_attr "type" "callv")])
21539
21540 (define_insn "*call_value_0_rex64"
21541   [(set (match_operand 0 "" "")
21542         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21543               (match_operand:DI 2 "const_int_operand" "")))]
21544   "TARGET_64BIT"
21545 {
21546   if (SIBLING_CALL_P (insn))
21547     return "jmp\t%P1";
21548   else
21549     return "call\t%P1";
21550 }
21551   [(set_attr "type" "callv")])
21552
21553 (define_insn "*call_value_0_rex64_ms_sysv"
21554   [(set (match_operand 0 "" "")
21555         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21556               (match_operand:DI 2 "const_int_operand" "")))
21557    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21558    (clobber (reg:TI XMM6_REG))
21559    (clobber (reg:TI XMM7_REG))
21560    (clobber (reg:TI XMM8_REG))
21561    (clobber (reg:TI XMM9_REG))
21562    (clobber (reg:TI XMM10_REG))
21563    (clobber (reg:TI XMM11_REG))
21564    (clobber (reg:TI XMM12_REG))
21565    (clobber (reg:TI XMM13_REG))
21566    (clobber (reg:TI XMM14_REG))
21567    (clobber (reg:TI XMM15_REG))
21568    (clobber (reg:DI SI_REG))
21569    (clobber (reg:DI DI_REG))]
21570   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
21571 {
21572   if (SIBLING_CALL_P (insn))
21573     return "jmp\t%P1";
21574   else
21575     return "call\t%P1";
21576 }
21577   [(set_attr "type" "callv")])
21578
21579 (define_insn "*call_value_1"
21580   [(set (match_operand 0 "" "")
21581         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
21582               (match_operand:SI 2 "" "")))]
21583   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
21584 {
21585   if (constant_call_address_operand (operands[1], Pmode))
21586     return "call\t%P1";
21587   return "call\t%A1";
21588 }
21589   [(set_attr "type" "callv")])
21590
21591 (define_insn "*sibcall_value_1"
21592   [(set (match_operand 0 "" "")
21593         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21594               (match_operand:SI 2 "" "")))]
21595   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
21596   "@
21597    jmp\t%P1
21598    jmp\t%A1"
21599   [(set_attr "type" "callv")])
21600
21601 (define_insn "*call_value_1_rex64"
21602   [(set (match_operand 0 "" "")
21603         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21604               (match_operand:DI 2 "" "")))]
21605   "TARGET_64BIT && !SIBLING_CALL_P (insn)
21606    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21607 {
21608   if (constant_call_address_operand (operands[1], Pmode))
21609     return "call\t%P1";
21610   return "call\t%A1";
21611 }
21612   [(set_attr "type" "callv")])
21613
21614 (define_insn "*call_value_1_rex64_ms_sysv"
21615   [(set (match_operand 0 "" "")
21616         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21617               (match_operand:DI 2 "" "")))
21618    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21619    (clobber (reg:TI 27))
21620    (clobber (reg:TI 28))
21621    (clobber (reg:TI 45))
21622    (clobber (reg:TI 46))
21623    (clobber (reg:TI 47))
21624    (clobber (reg:TI 48))
21625    (clobber (reg:TI 49))
21626    (clobber (reg:TI 50))
21627    (clobber (reg:TI 51))
21628    (clobber (reg:TI 52))
21629    (clobber (reg:DI SI_REG))
21630    (clobber (reg:DI DI_REG))]
21631   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21632 {
21633   if (constant_call_address_operand (operands[1], Pmode))
21634     return "call\t%P1";
21635   return "call\t%A1";
21636 }
21637   [(set_attr "type" "callv")])
21638
21639 (define_insn "*call_value_1_rex64_large"
21640   [(set (match_operand 0 "" "")
21641         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21642               (match_operand:DI 2 "" "")))]
21643   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
21644   "call\t%A1"
21645   [(set_attr "type" "callv")])
21646
21647 (define_insn "*sibcall_value_1_rex64"
21648   [(set (match_operand 0 "" "")
21649         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21650               (match_operand:DI 2 "" "")))]
21651   "TARGET_64BIT && SIBLING_CALL_P (insn)"
21652   "@
21653    jmp\t%P1
21654    jmp\t%A1"
21655   [(set_attr "type" "callv")])
21656 \f
21657 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21658 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21659 ;; caught for use by garbage collectors and the like.  Using an insn that
21660 ;; maps to SIGILL makes it more likely the program will rightfully die.
21661 ;; Keeping with tradition, "6" is in honor of #UD.
21662 (define_insn "trap"
21663   [(trap_if (const_int 1) (const_int 6))]
21664   ""
21665   { return ASM_SHORT "0x0b0f"; }
21666   [(set_attr "length" "2")])
21667
21668 (define_expand "sse_prologue_save"
21669   [(parallel [(set (match_operand:BLK 0 "" "")
21670                    (unspec:BLK [(reg:DI 21)
21671                                 (reg:DI 22)
21672                                 (reg:DI 23)
21673                                 (reg:DI 24)
21674                                 (reg:DI 25)
21675                                 (reg:DI 26)
21676                                 (reg:DI 27)
21677                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21678               (use (match_operand:DI 1 "register_operand" ""))
21679               (use (match_operand:DI 2 "immediate_operand" ""))
21680               (use (label_ref:DI (match_operand 3 "" "")))])]
21681   "TARGET_64BIT"
21682   "")
21683
21684 (define_insn "*sse_prologue_save_insn"
21685   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21686                           (match_operand:DI 4 "const_int_operand" "n")))
21687         (unspec:BLK [(reg:DI 21)
21688                      (reg:DI 22)
21689                      (reg:DI 23)
21690                      (reg:DI 24)
21691                      (reg:DI 25)
21692                      (reg:DI 26)
21693                      (reg:DI 27)
21694                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21695    (use (match_operand:DI 1 "register_operand" "r"))
21696    (use (match_operand:DI 2 "const_int_operand" "i"))
21697    (use (label_ref:DI (match_operand 3 "" "X")))]
21698   "TARGET_64BIT
21699    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21700    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21701 {
21702   int i;
21703   operands[0] = gen_rtx_MEM (Pmode,
21704                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21705   /* VEX instruction with a REX prefix will #UD.  */
21706   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21707     gcc_unreachable ();
21708
21709   output_asm_insn ("jmp\t%A1", operands);
21710   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21711     {
21712       operands[4] = adjust_address (operands[0], DImode, i*16);
21713       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21714       PUT_MODE (operands[4], TImode);
21715       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21716         output_asm_insn ("rex", operands);
21717       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21718     }
21719   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21720                                      CODE_LABEL_NUMBER (operands[3]));
21721   return "";
21722 }
21723   [(set_attr "type" "other")
21724    (set_attr "length_immediate" "0")
21725    (set_attr "length_address" "0")
21726    (set (attr "length")
21727      (if_then_else
21728        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21729        (const_string "34")
21730        (const_string "42")))
21731    (set_attr "memory" "store")
21732    (set_attr "modrm" "0")
21733    (set_attr "prefix" "maybe_vex")
21734    (set_attr "mode" "DI")])
21735
21736 (define_expand "prefetch"
21737   [(prefetch (match_operand 0 "address_operand" "")
21738              (match_operand:SI 1 "const_int_operand" "")
21739              (match_operand:SI 2 "const_int_operand" ""))]
21740   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21741 {
21742   int rw = INTVAL (operands[1]);
21743   int locality = INTVAL (operands[2]);
21744
21745   gcc_assert (rw == 0 || rw == 1);
21746   gcc_assert (locality >= 0 && locality <= 3);
21747   gcc_assert (GET_MODE (operands[0]) == Pmode
21748               || GET_MODE (operands[0]) == VOIDmode);
21749
21750   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21751      supported by SSE counterpart or the SSE prefetch is not available
21752      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21753      of locality.  */
21754   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21755     operands[2] = GEN_INT (3);
21756   else
21757     operands[1] = const0_rtx;
21758 })
21759
21760 (define_insn "*prefetch_sse"
21761   [(prefetch (match_operand:SI 0 "address_operand" "p")
21762              (const_int 0)
21763              (match_operand:SI 1 "const_int_operand" ""))]
21764   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21765 {
21766   static const char * const patterns[4] = {
21767    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21768   };
21769
21770   int locality = INTVAL (operands[1]);
21771   gcc_assert (locality >= 0 && locality <= 3);
21772
21773   return patterns[locality];
21774 }
21775   [(set_attr "type" "sse")
21776    (set_attr "memory" "none")])
21777
21778 (define_insn "*prefetch_sse_rex"
21779   [(prefetch (match_operand:DI 0 "address_operand" "p")
21780              (const_int 0)
21781              (match_operand:SI 1 "const_int_operand" ""))]
21782   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21783 {
21784   static const char * const patterns[4] = {
21785    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21786   };
21787
21788   int locality = INTVAL (operands[1]);
21789   gcc_assert (locality >= 0 && locality <= 3);
21790
21791   return patterns[locality];
21792 }
21793   [(set_attr "type" "sse")
21794    (set_attr "memory" "none")])
21795
21796 (define_insn "*prefetch_3dnow"
21797   [(prefetch (match_operand:SI 0 "address_operand" "p")
21798              (match_operand:SI 1 "const_int_operand" "n")
21799              (const_int 3))]
21800   "TARGET_3DNOW && !TARGET_64BIT"
21801 {
21802   if (INTVAL (operands[1]) == 0)
21803     return "prefetch\t%a0";
21804   else
21805     return "prefetchw\t%a0";
21806 }
21807   [(set_attr "type" "mmx")
21808    (set_attr "memory" "none")])
21809
21810 (define_insn "*prefetch_3dnow_rex"
21811   [(prefetch (match_operand:DI 0 "address_operand" "p")
21812              (match_operand:SI 1 "const_int_operand" "n")
21813              (const_int 3))]
21814   "TARGET_3DNOW && TARGET_64BIT"
21815 {
21816   if (INTVAL (operands[1]) == 0)
21817     return "prefetch\t%a0";
21818   else
21819     return "prefetchw\t%a0";
21820 }
21821   [(set_attr "type" "mmx")
21822    (set_attr "memory" "none")])
21823
21824 (define_expand "stack_protect_set"
21825   [(match_operand 0 "memory_operand" "")
21826    (match_operand 1 "memory_operand" "")]
21827   ""
21828 {
21829 #ifdef TARGET_THREAD_SSP_OFFSET
21830   if (TARGET_64BIT)
21831     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21832                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21833   else
21834     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21835                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21836 #else
21837   if (TARGET_64BIT)
21838     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21839   else
21840     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21841 #endif
21842   DONE;
21843 })
21844
21845 (define_insn "stack_protect_set_si"
21846   [(set (match_operand:SI 0 "memory_operand" "=m")
21847         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21848    (set (match_scratch:SI 2 "=&r") (const_int 0))
21849    (clobber (reg:CC FLAGS_REG))]
21850   ""
21851   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21852   [(set_attr "type" "multi")])
21853
21854 (define_insn "stack_protect_set_di"
21855   [(set (match_operand:DI 0 "memory_operand" "=m")
21856         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21857    (set (match_scratch:DI 2 "=&r") (const_int 0))
21858    (clobber (reg:CC FLAGS_REG))]
21859   "TARGET_64BIT"
21860   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21861   [(set_attr "type" "multi")])
21862
21863 (define_insn "stack_tls_protect_set_si"
21864   [(set (match_operand:SI 0 "memory_operand" "=m")
21865         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21866    (set (match_scratch:SI 2 "=&r") (const_int 0))
21867    (clobber (reg:CC FLAGS_REG))]
21868   ""
21869   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21870   [(set_attr "type" "multi")])
21871
21872 (define_insn "stack_tls_protect_set_di"
21873   [(set (match_operand:DI 0 "memory_operand" "=m")
21874         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21875    (set (match_scratch:DI 2 "=&r") (const_int 0))
21876    (clobber (reg:CC FLAGS_REG))]
21877   "TARGET_64BIT"
21878   {
21879      /* The kernel uses a different segment register for performance reasons; a
21880         system call would not have to trash the userspace segment register,
21881         which would be expensive */
21882      if (ix86_cmodel != CM_KERNEL)
21883         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21884      else
21885         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21886   }
21887   [(set_attr "type" "multi")])
21888
21889 (define_expand "stack_protect_test"
21890   [(match_operand 0 "memory_operand" "")
21891    (match_operand 1 "memory_operand" "")
21892    (match_operand 2 "" "")]
21893   ""
21894 {
21895   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21896   ix86_compare_op0 = operands[0];
21897   ix86_compare_op1 = operands[1];
21898   ix86_compare_emitted = flags;
21899
21900 #ifdef TARGET_THREAD_SSP_OFFSET
21901   if (TARGET_64BIT)
21902     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21903                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21904   else
21905     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21906                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21907 #else
21908   if (TARGET_64BIT)
21909     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21910   else
21911     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21912 #endif
21913   emit_jump_insn (gen_beq (operands[2]));
21914   DONE;
21915 })
21916
21917 (define_insn "stack_protect_test_si"
21918   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21919         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21920                      (match_operand:SI 2 "memory_operand" "m")]
21921                     UNSPEC_SP_TEST))
21922    (clobber (match_scratch:SI 3 "=&r"))]
21923   ""
21924   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21925   [(set_attr "type" "multi")])
21926
21927 (define_insn "stack_protect_test_di"
21928   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21929         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21930                      (match_operand:DI 2 "memory_operand" "m")]
21931                     UNSPEC_SP_TEST))
21932    (clobber (match_scratch:DI 3 "=&r"))]
21933   "TARGET_64BIT"
21934   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21935   [(set_attr "type" "multi")])
21936
21937 (define_insn "stack_tls_protect_test_si"
21938   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21939         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21940                      (match_operand:SI 2 "const_int_operand" "i")]
21941                     UNSPEC_SP_TLS_TEST))
21942    (clobber (match_scratch:SI 3 "=r"))]
21943   ""
21944   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21945   [(set_attr "type" "multi")])
21946
21947 (define_insn "stack_tls_protect_test_di"
21948   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21949         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21950                      (match_operand:DI 2 "const_int_operand" "i")]
21951                     UNSPEC_SP_TLS_TEST))
21952    (clobber (match_scratch:DI 3 "=r"))]
21953   "TARGET_64BIT"
21954   {
21955      /* The kernel uses a different segment register for performance reasons; a
21956         system call would not have to trash the userspace segment register,
21957         which would be expensive */
21958      if (ix86_cmodel != CM_KERNEL)
21959         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21960      else
21961         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21962   }
21963   [(set_attr "type" "multi")])
21964
21965 (define_mode_iterator CRC32MODE [QI HI SI])
21966 (define_mode_attr crc32modesuffix [(QI "{b}") (HI "{w}") (SI "{l}")])
21967 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21968
21969 (define_insn "sse4_2_crc32<mode>"
21970   [(set (match_operand:SI 0 "register_operand" "=r")
21971         (unspec:SI
21972           [(match_operand:SI 1 "register_operand" "0")
21973            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21974           UNSPEC_CRC32))]
21975   "TARGET_SSE4_2"
21976   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21977   [(set_attr "type" "sselog1")
21978    (set_attr "prefix_rep" "1")
21979    (set_attr "prefix_extra" "1")
21980    (set_attr "mode" "SI")])
21981
21982 (define_insn "sse4_2_crc32di"
21983   [(set (match_operand:DI 0 "register_operand" "=r")
21984         (unspec:DI
21985           [(match_operand:DI 1 "register_operand" "0")
21986            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21987           UNSPEC_CRC32))]
21988   "TARGET_SSE4_2 && TARGET_64BIT"
21989   "crc32{q}\t{%2, %0|%0, %2}"
21990   [(set_attr "type" "sselog1")
21991    (set_attr "prefix_rep" "1")
21992    (set_attr "prefix_extra" "1")
21993    (set_attr "mode" "DI")])
21994
21995 (include "mmx.md")
21996 (include "sse.md")
21997 (include "sync.md")