OSDN Git Service

9592f91ff7ee364d26bd28b4daf05bcd04b95574
[pf3gnuchains/gcc-fork.git] / 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
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
79    ; Other random patterns
80    (UNSPEC_SCAS                 30)
81    (UNSPEC_FNSTSW               31)
82    (UNSPEC_SAHF                 32)
83    (UNSPEC_FSTCW                33)
84    (UNSPEC_ADD_CARRY            34)
85    (UNSPEC_FLDCW                35)
86    (UNSPEC_REP                  36)
87    (UNSPEC_EH_RETURN            37)
88    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
89    (UNSPEC_TRUNC_NOOP           39)
90
91    ; For SSE/MMX support:
92    (UNSPEC_FIX_NOTRUNC          40)
93    (UNSPEC_MASKMOV              41)
94    (UNSPEC_MOVMSK               42)
95    (UNSPEC_MOVNT                43)
96    (UNSPEC_MOVU                 44)
97    (UNSPEC_RCP                  45)
98    (UNSPEC_RSQRT                46)
99    (UNSPEC_SFENCE               47)
100    (UNSPEC_PFRCP                49)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
109    (UNSPEC_MS_TO_SYSV_CALL      48)
110
111    ; Generic math support
112    (UNSPEC_COPYSIGN             50)
113    (UNSPEC_IEEE_MIN             51)     ; not commutative
114    (UNSPEC_IEEE_MAX             52)     ; not commutative
115
116    ; x87 Floating point
117    (UNSPEC_SIN                  60)
118    (UNSPEC_COS                  61)
119    (UNSPEC_FPATAN               62)
120    (UNSPEC_FYL2X                63)
121    (UNSPEC_FYL2XP1              64)
122    (UNSPEC_FRNDINT              65)
123    (UNSPEC_FIST                 66)
124    (UNSPEC_F2XM1                67)
125    (UNSPEC_TAN                  68)
126    (UNSPEC_FXAM                 69)
127
128    ; x87 Rounding
129    (UNSPEC_FRNDINT_FLOOR        70)
130    (UNSPEC_FRNDINT_CEIL         71)
131    (UNSPEC_FRNDINT_TRUNC        72)
132    (UNSPEC_FRNDINT_MASK_PM      73)
133    (UNSPEC_FIST_FLOOR           74)
134    (UNSPEC_FIST_CEIL            75)
135
136    ; x87 Double output FP
137    (UNSPEC_SINCOS_COS           80)
138    (UNSPEC_SINCOS_SIN           81)
139    (UNSPEC_XTRACT_FRACT         84)
140    (UNSPEC_XTRACT_EXP           85)
141    (UNSPEC_FSCALE_FRACT         86)
142    (UNSPEC_FSCALE_EXP           87)
143    (UNSPEC_FPREM_F              88)
144    (UNSPEC_FPREM_U              89)
145    (UNSPEC_FPREM1_F             90)
146    (UNSPEC_FPREM1_U             91)
147
148    (UNSPEC_C2_FLAG              95)
149    (UNSPEC_FXAM_MEM             96)
150
151    ; SSP patterns
152    (UNSPEC_SP_SET               100)
153    (UNSPEC_SP_TEST              101)
154    (UNSPEC_SP_TLS_SET           102)
155    (UNSPEC_SP_TLS_TEST          103)
156
157    ; SSSE3
158    (UNSPEC_PSHUFB               120)
159    (UNSPEC_PSIGN                121)
160    (UNSPEC_PALIGNR              122)
161
162    ; For SSE4A support
163    (UNSPEC_EXTRQI               130)
164    (UNSPEC_EXTRQ                131)
165    (UNSPEC_INSERTQI             132)
166    (UNSPEC_INSERTQ              133)
167
168    ; For SSE4.1 support
169    (UNSPEC_BLENDV               134)
170    (UNSPEC_INSERTPS             135)
171    (UNSPEC_DP                   136)
172    (UNSPEC_MOVNTDQA             137)
173    (UNSPEC_MPSADBW              138)
174    (UNSPEC_PHMINPOSUW           139)
175    (UNSPEC_PTEST                140)
176    (UNSPEC_ROUND                141)
177
178    ; For SSE4.2 support
179    (UNSPEC_CRC32                143)
180    (UNSPEC_PCMPESTR             144)
181    (UNSPEC_PCMPISTR             145)
182
183    ;; For SSE5
184    (UNSPEC_SSE5_INTRINSIC       150)
185    (UNSPEC_SSE5_UNSIGNED_CMP    151)
186    (UNSPEC_SSE5_TRUEFALSE       152)
187    (UNSPEC_SSE5_PERMUTE         153)
188    (UNSPEC_FRCZ                 154)
189    (UNSPEC_CVTPH2PS             155)
190    (UNSPEC_CVTPS2PH             156)
191
192    ; For AES support
193    (UNSPEC_AESENC               159)
194    (UNSPEC_AESENCLAST           160)
195    (UNSPEC_AESDEC               161)
196    (UNSPEC_AESDECLAST           162)
197    (UNSPEC_AESIMC               163)
198    (UNSPEC_AESKEYGENASSIST      164)
199
200    ; For PCLMUL support
201    (UNSPEC_PCLMUL               165)
202
203    ; For AVX support
204    (UNSPEC_PCMP                 166)
205    (UNSPEC_VPERMIL              167)
206    (UNSPEC_VPERMIL2F128         168)
207    (UNSPEC_MASKLOAD             169)
208    (UNSPEC_MASKSTORE            170)
209    (UNSPEC_CAST                 171)
210    (UNSPEC_VTESTP               172)
211   ])
212
213 (define_constants
214   [(UNSPECV_BLOCKAGE            0)
215    (UNSPECV_STACK_PROBE         1)
216    (UNSPECV_EMMS                2)
217    (UNSPECV_LDMXCSR             3)
218    (UNSPECV_STMXCSR             4)
219    (UNSPECV_FEMMS               5)
220    (UNSPECV_CLFLUSH             6)
221    (UNSPECV_ALIGN               7)
222    (UNSPECV_MONITOR             8)
223    (UNSPECV_MWAIT               9)
224    (UNSPECV_CMPXCHG             10)
225    (UNSPECV_XCHG                12)
226    (UNSPECV_LOCK                13)
227    (UNSPECV_PROLOGUE_USE        14)
228    (UNSPECV_CLD                 15)
229    (UNSPECV_VZEROALL            16)
230    (UNSPECV_VZEROUPPER          17)
231   ])
232
233 ;; Constants to represent pcomtrue/pcomfalse variants
234 (define_constants
235   [(PCOM_FALSE                  0)
236    (PCOM_TRUE                   1)
237    (COM_FALSE_S                 2)
238    (COM_FALSE_P                 3)
239    (COM_TRUE_S                  4)
240    (COM_TRUE_P                  5)
241   ])
242
243 ;; Constants used in the SSE5 pperm instruction
244 (define_constants
245   [(PPERM_SRC                   0x00)   /* copy source */
246    (PPERM_INVERT                0x20)   /* invert source */
247    (PPERM_REVERSE               0x40)   /* bit reverse source */
248    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
249    (PPERM_ZERO                  0x80)   /* all 0's */
250    (PPERM_ONES                  0xa0)   /* all 1's */
251    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
252    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
253    (PPERM_SRC1                  0x00)   /* use first source byte */
254    (PPERM_SRC2                  0x10)   /* use second source byte */
255    ])
256
257 ;; Registers by name.
258 (define_constants
259   [(AX_REG                       0)
260    (DX_REG                       1)
261    (CX_REG                       2)
262    (BX_REG                       3)
263    (SI_REG                       4)
264    (DI_REG                       5)
265    (BP_REG                       6)
266    (SP_REG                       7)
267    (ST0_REG                      8)
268    (ST1_REG                      9)
269    (ST2_REG                     10)
270    (ST3_REG                     11)
271    (ST4_REG                     12)
272    (ST5_REG                     13)
273    (ST6_REG                     14)
274    (ST7_REG                     15)
275    (FLAGS_REG                   17)
276    (FPSR_REG                    18)
277    (FPCR_REG                    19)
278    (XMM0_REG                    21)
279    (XMM1_REG                    22)
280    (XMM2_REG                    23)
281    (XMM3_REG                    24)
282    (XMM4_REG                    25)
283    (XMM5_REG                    26)
284    (XMM6_REG                    27)
285    (XMM7_REG                    28)
286    (MM0_REG                     29)
287    (MM1_REG                     30)
288    (MM2_REG                     31)
289    (MM3_REG                     32)
290    (MM4_REG                     33)
291    (MM5_REG                     34)
292    (MM6_REG                     35)
293    (MM7_REG                     36)
294    (R8_REG                      37)
295    (R9_REG                      38)
296    (R10_REG                     39)
297    (R11_REG                     40)
298    (R13_REG                     42)
299    (XMM8_REG                    45)
300    (XMM9_REG                    46)
301    (XMM10_REG                   47)
302    (XMM11_REG                   48)
303    (XMM12_REG                   49)
304    (XMM13_REG                   50)
305    (XMM14_REG                   51)
306    (XMM15_REG                   52)
307   ])
308
309 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
310 ;; from i386.c.
311
312 ;; In C guard expressions, put expressions which may be compile-time
313 ;; constants first.  This allows for better optimization.  For
314 ;; example, write "TARGET_64BIT && reload_completed", not
315 ;; "reload_completed && TARGET_64BIT".
316
317 \f
318 ;; Processor type.
319 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
320                     generic64,amdfam10"
321   (const (symbol_ref "ix86_schedule")))
322
323 ;; A basic instruction type.  Refinements due to arguments to be
324 ;; provided in other attributes.
325 (define_attr "type"
326   "other,multi,
327    alu,alu1,negnot,imov,imovx,lea,
328    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
329    icmp,test,ibr,setcc,icmov,
330    push,pop,call,callv,leave,
331    str,bitmanip,
332    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
333    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
334    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
335    ssemuladd,sse4arg,
336    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
337   (const_string "other"))
338
339 ;; Main data type used by the insn
340 (define_attr "mode"
341   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
342   (const_string "unknown"))
343
344 ;; The CPU unit operations uses.
345 (define_attr "unit" "integer,i387,sse,mmx,unknown"
346   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
347            (const_string "i387")
348          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
349                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
350                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
351            (const_string "sse")
352          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
353            (const_string "mmx")
354          (eq_attr "type" "other")
355            (const_string "unknown")]
356          (const_string "integer")))
357
358 ;; The (bounding maximum) length of an instruction immediate.
359 (define_attr "length_immediate" ""
360   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
361                           bitmanip")
362            (const_int 0)
363          (eq_attr "unit" "i387,sse,mmx")
364            (const_int 0)
365          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
366                           imul,icmp,push,pop")
367            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
368          (eq_attr "type" "imov,test")
369            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
370          (eq_attr "type" "call")
371            (if_then_else (match_operand 0 "constant_call_address_operand" "")
372              (const_int 4)
373              (const_int 0))
374          (eq_attr "type" "callv")
375            (if_then_else (match_operand 1 "constant_call_address_operand" "")
376              (const_int 4)
377              (const_int 0))
378          ;; We don't know the size before shorten_branches.  Expect
379          ;; the instruction to fit for better scheduling.
380          (eq_attr "type" "ibr")
381            (const_int 1)
382          ]
383          (symbol_ref "/* Update immediate_length and other attributes! */
384                       gcc_unreachable (),1")))
385
386 ;; The (bounding maximum) length of an instruction address.
387 (define_attr "length_address" ""
388   (cond [(eq_attr "type" "str,other,multi,fxch")
389            (const_int 0)
390          (and (eq_attr "type" "call")
391               (match_operand 0 "constant_call_address_operand" ""))
392              (const_int 0)
393          (and (eq_attr "type" "callv")
394               (match_operand 1 "constant_call_address_operand" ""))
395              (const_int 0)
396          ]
397          (symbol_ref "ix86_attr_length_address_default (insn)")))
398
399 ;; Set when length prefix is used.
400 (define_attr "prefix_data16" ""
401   (if_then_else (ior (eq_attr "mode" "HI")
402                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
403     (const_int 1)
404     (const_int 0)))
405
406 ;; Set when string REP prefix is used.
407 (define_attr "prefix_rep" ""
408   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
409     (const_int 1)
410     (const_int 0)))
411
412 ;; Set when 0f opcode prefix is used.
413 (define_attr "prefix_0f" ""
414   (if_then_else
415     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
416          (eq_attr "unit" "sse,mmx"))
417     (const_int 1)
418     (const_int 0)))
419
420 ;; Set when REX opcode prefix is used.
421 (define_attr "prefix_rex" ""
422   (cond [(and (eq_attr "mode" "DI")
423               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
424            (const_int 1)
425          (and (eq_attr "mode" "QI")
426               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
427                   (const_int 0)))
428            (const_int 1)
429          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
430              (const_int 0))
431            (const_int 1)
432         ]
433         (const_int 0)))
434
435 ;; There are also additional prefixes in SSSE3.
436 (define_attr "prefix_extra" "" (const_int 0))
437
438 ;; Prefix used: original, VEX or maybe VEX.
439 (define_attr "prefix" "orig,vex,maybe_vex"
440   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
441     (const_string "vex")
442     (const_string "orig")))
443
444 ;; There is a 8bit immediate for VEX.
445 (define_attr "prefix_vex_imm8" "" (const_int 0))
446
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
449
450 ;; The length of VEX prefix
451 (define_attr "length_vex" ""
452   (if_then_else (eq_attr "prefix_0f" "1")
453     (if_then_else (eq_attr "prefix_vex_w" "1")
454       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
455       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
456     (if_then_else (eq_attr "prefix_vex_w" "1")
457       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
458       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
459
460 ;; Set when modrm byte is used.
461 (define_attr "modrm" ""
462   (cond [(eq_attr "type" "str,leave")
463            (const_int 0)
464          (eq_attr "unit" "i387")
465            (const_int 0)
466          (and (eq_attr "type" "incdec")
467               (ior (match_operand:SI 1 "register_operand" "")
468                    (match_operand:HI 1 "register_operand" "")))
469            (const_int 0)
470          (and (eq_attr "type" "push")
471               (not (match_operand 1 "memory_operand" "")))
472            (const_int 0)
473          (and (eq_attr "type" "pop")
474               (not (match_operand 0 "memory_operand" "")))
475            (const_int 0)
476          (and (eq_attr "type" "imov")
477               (ior (and (match_operand 0 "register_operand" "")
478                         (match_operand 1 "immediate_operand" ""))
479                    (ior (and (match_operand 0 "ax_reg_operand" "")
480                              (match_operand 1 "memory_displacement_only_operand" ""))
481                         (and (match_operand 0 "memory_displacement_only_operand" "")
482                              (match_operand 1 "ax_reg_operand" "")))))
483            (const_int 0)
484          (and (eq_attr "type" "call")
485               (match_operand 0 "constant_call_address_operand" ""))
486              (const_int 0)
487          (and (eq_attr "type" "callv")
488               (match_operand 1 "constant_call_address_operand" ""))
489              (const_int 0)
490          ]
491          (const_int 1)))
492
493 ;; The (bounding maximum) length of an instruction in bytes.
494 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
495 ;; Later we may want to split them and compute proper length as for
496 ;; other insns.
497 (define_attr "length" ""
498   (cond [(eq_attr "type" "other,multi,fistp,frndint")
499            (const_int 16)
500          (eq_attr "type" "fcmp")
501            (const_int 4)
502          (eq_attr "unit" "i387")
503            (plus (const_int 2)
504                  (plus (attr "prefix_data16")
505                        (attr "length_address")))
506          (ior (eq_attr "prefix" "vex")
507               (and (eq_attr "prefix" "maybe_vex")
508                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
509            (plus (attr "length_vex")
510                  (plus (attr "prefix_vex_imm8")
511                        (plus (attr "modrm")
512                              (attr "length_address"))))]
513          (plus (plus (attr "modrm")
514                      (plus (attr "prefix_0f")
515                            (plus (attr "prefix_rex")
516                                  (plus (attr "prefix_extra")
517                                        (const_int 1)))))
518                (plus (attr "prefix_rep")
519                      (plus (attr "prefix_data16")
520                            (plus (attr "length_immediate")
521                                  (attr "length_address")))))))
522
523 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
524 ;; `store' if there is a simple memory reference therein, or `unknown'
525 ;; if the instruction is complex.
526
527 (define_attr "memory" "none,load,store,both,unknown"
528   (cond [(eq_attr "type" "other,multi,str")
529            (const_string "unknown")
530          (eq_attr "type" "lea,fcmov,fpspc")
531            (const_string "none")
532          (eq_attr "type" "fistp,leave")
533            (const_string "both")
534          (eq_attr "type" "frndint")
535            (const_string "load")
536          (eq_attr "type" "push")
537            (if_then_else (match_operand 1 "memory_operand" "")
538              (const_string "both")
539              (const_string "store"))
540          (eq_attr "type" "pop")
541            (if_then_else (match_operand 0 "memory_operand" "")
542              (const_string "both")
543              (const_string "load"))
544          (eq_attr "type" "setcc")
545            (if_then_else (match_operand 0 "memory_operand" "")
546              (const_string "store")
547              (const_string "none"))
548          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
549            (if_then_else (ior (match_operand 0 "memory_operand" "")
550                               (match_operand 1 "memory_operand" ""))
551              (const_string "load")
552              (const_string "none"))
553          (eq_attr "type" "ibr")
554            (if_then_else (match_operand 0 "memory_operand" "")
555              (const_string "load")
556              (const_string "none"))
557          (eq_attr "type" "call")
558            (if_then_else (match_operand 0 "constant_call_address_operand" "")
559              (const_string "none")
560              (const_string "load"))
561          (eq_attr "type" "callv")
562            (if_then_else (match_operand 1 "constant_call_address_operand" "")
563              (const_string "none")
564              (const_string "load"))
565          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
566               (match_operand 1 "memory_operand" ""))
567            (const_string "both")
568          (and (match_operand 0 "memory_operand" "")
569               (match_operand 1 "memory_operand" ""))
570            (const_string "both")
571          (match_operand 0 "memory_operand" "")
572            (const_string "store")
573          (match_operand 1 "memory_operand" "")
574            (const_string "load")
575          (and (eq_attr "type"
576                  "!alu1,negnot,ishift1,
577                    imov,imovx,icmp,test,bitmanip,
578                    fmov,fcmp,fsgn,
579                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
580                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
581               (match_operand 2 "memory_operand" ""))
582            (const_string "load")
583          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
584               (match_operand 3 "memory_operand" ""))
585            (const_string "load")
586         ]
587         (const_string "none")))
588
589 ;; Indicates if an instruction has both an immediate and a displacement.
590
591 (define_attr "imm_disp" "false,true,unknown"
592   (cond [(eq_attr "type" "other,multi")
593            (const_string "unknown")
594          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
595               (and (match_operand 0 "memory_displacement_operand" "")
596                    (match_operand 1 "immediate_operand" "")))
597            (const_string "true")
598          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
599               (and (match_operand 0 "memory_displacement_operand" "")
600                    (match_operand 2 "immediate_operand" "")))
601            (const_string "true")
602         ]
603         (const_string "false")))
604
605 ;; Indicates if an FP operation has an integer source.
606
607 (define_attr "fp_int_src" "false,true"
608   (const_string "false"))
609
610 ;; Defines rounding mode of an FP operation.
611
612 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
613   (const_string "any"))
614
615 ;; Describe a user's asm statement.
616 (define_asm_attributes
617   [(set_attr "length" "128")
618    (set_attr "type" "multi")])
619
620 ;; All integer comparison codes.
621 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
622
623 ;; All floating-point comparison codes.
624 (define_code_iterator fp_cond [unordered ordered
625                                uneq unge ungt unle unlt ltgt ])
626
627 (define_code_iterator plusminus [plus minus])
628
629 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
630
631 ;; Base name for define_insn
632 (define_code_attr plusminus_insn
633   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
634    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
635
636 ;; Base name for insn mnemonic.
637 (define_code_attr plusminus_mnemonic
638   [(plus "add") (ss_plus "adds") (us_plus "addus")
639    (minus "sub") (ss_minus "subs") (us_minus "subus")])
640
641 ;; Mark commutative operators as such in constraints.
642 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
643                         (minus "") (ss_minus "") (us_minus "")])
644
645 ;; Mapping of signed max and min
646 (define_code_iterator smaxmin [smax smin])
647
648 ;; Mapping of unsigned max and min
649 (define_code_iterator umaxmin [umax umin])
650
651 ;; Mapping of signed/unsigned max and min
652 (define_code_iterator maxmin [smax smin umax umin])
653
654 ;; Base name for integer and FP insn mnemonic
655 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
656                                  (umax "maxu") (umin "minu")])
657 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
658
659 ;; Mapping of parallel logic operators
660 (define_code_iterator plogic [and ior xor])
661
662 ;; Base name for insn mnemonic.
663 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
664
665 ;; Mapping of abs neg operators
666 (define_code_iterator absneg [abs neg])
667
668 ;; Base name for x87 insn mnemonic.
669 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
670
671 ;; All single word integer modes.
672 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
673
674 ;; Single word integer modes without QImode.
675 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
676
677 ;; Instruction suffix for integer modes.
678 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
679
680 ;; Register class for integer modes.
681 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
682
683 ;; Immediate operand constraint for integer modes.
684 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
685
686 ;; General operand predicate for integer modes.
687 (define_mode_attr general_operand
688         [(QI "general_operand")
689          (HI "general_operand")
690          (SI "general_operand")
691          (DI "x86_64_general_operand")])
692
693 ;; SSE and x87 SFmode and DFmode floating point modes
694 (define_mode_iterator MODEF [SF DF])
695
696 ;; All x87 floating point modes
697 (define_mode_iterator X87MODEF [SF DF XF])
698
699 ;; All integer modes handled by x87 fisttp operator.
700 (define_mode_iterator X87MODEI [HI SI DI])
701
702 ;; All integer modes handled by integer x87 operators.
703 (define_mode_iterator X87MODEI12 [HI SI])
704
705 ;; All integer modes handled by SSE cvtts?2si* operators.
706 (define_mode_iterator SSEMODEI24 [SI DI])
707
708 ;; SSE asm suffix for floating point modes
709 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
710
711 ;; SSE vector mode corresponding to a scalar mode
712 (define_mode_attr ssevecmode
713   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
714
715 ;; Instruction suffix for REX 64bit operators.
716 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
717
718 ;; This mode iterator allows :P to be used for patterns that operate on
719 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
720 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
721
722 \f
723 ;; Scheduling descriptions
724
725 (include "pentium.md")
726 (include "ppro.md")
727 (include "k6.md")
728 (include "athlon.md")
729 (include "geode.md")
730
731 \f
732 ;; Operand and operator predicates and constraints
733
734 (include "predicates.md")
735 (include "constraints.md")
736
737 \f
738 ;; Compare instructions.
739
740 ;; All compare insns have expanders that save the operands away without
741 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
742 ;; after the cmp) will actually emit the cmpM.
743
744 (define_expand "cmpti"
745   [(set (reg:CC FLAGS_REG)
746         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
747                     (match_operand:TI 1 "x86_64_general_operand" "")))]
748   "TARGET_64BIT"
749 {
750   if (MEM_P (operands[0]) && MEM_P (operands[1]))
751     operands[0] = force_reg (TImode, operands[0]);
752   ix86_compare_op0 = operands[0];
753   ix86_compare_op1 = operands[1];
754   DONE;
755 })
756
757 (define_expand "cmpdi"
758   [(set (reg:CC FLAGS_REG)
759         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
760                     (match_operand:DI 1 "x86_64_general_operand" "")))]
761   ""
762 {
763   if (MEM_P (operands[0]) && MEM_P (operands[1]))
764     operands[0] = force_reg (DImode, operands[0]);
765   ix86_compare_op0 = operands[0];
766   ix86_compare_op1 = operands[1];
767   DONE;
768 })
769
770 (define_expand "cmpsi"
771   [(set (reg:CC FLAGS_REG)
772         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
773                     (match_operand:SI 1 "general_operand" "")))]
774   ""
775 {
776   if (MEM_P (operands[0]) && MEM_P (operands[1]))
777     operands[0] = force_reg (SImode, operands[0]);
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmphi"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
786                     (match_operand:HI 1 "general_operand" "")))]
787   ""
788 {
789   if (MEM_P (operands[0]) && MEM_P (operands[1]))
790     operands[0] = force_reg (HImode, operands[0]);
791   ix86_compare_op0 = operands[0];
792   ix86_compare_op1 = operands[1];
793   DONE;
794 })
795
796 (define_expand "cmpqi"
797   [(set (reg:CC FLAGS_REG)
798         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
799                     (match_operand:QI 1 "general_operand" "")))]
800   "TARGET_QIMODE_MATH"
801 {
802   if (MEM_P (operands[0]) && MEM_P (operands[1]))
803     operands[0] = force_reg (QImode, operands[0]);
804   ix86_compare_op0 = operands[0];
805   ix86_compare_op1 = operands[1];
806   DONE;
807 })
808
809 (define_insn "cmpdi_ccno_1_rex64"
810   [(set (reg FLAGS_REG)
811         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
812                  (match_operand:DI 1 "const0_operand" "")))]
813   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
814   "@
815    test{q}\t%0, %0
816    cmp{q}\t{%1, %0|%0, %1}"
817   [(set_attr "type" "test,icmp")
818    (set_attr "length_immediate" "0,1")
819    (set_attr "mode" "DI")])
820
821 (define_insn "*cmpdi_minus_1_rex64"
822   [(set (reg FLAGS_REG)
823         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
824                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
825                  (const_int 0)))]
826   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
827   "cmp{q}\t{%1, %0|%0, %1}"
828   [(set_attr "type" "icmp")
829    (set_attr "mode" "DI")])
830
831 (define_expand "cmpdi_1_rex64"
832   [(set (reg:CC FLAGS_REG)
833         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
834                     (match_operand:DI 1 "general_operand" "")))]
835   "TARGET_64BIT"
836   "")
837
838 (define_insn "cmpdi_1_insn_rex64"
839   [(set (reg FLAGS_REG)
840         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
841                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
842   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
843   "cmp{q}\t{%1, %0|%0, %1}"
844   [(set_attr "type" "icmp")
845    (set_attr "mode" "DI")])
846
847
848 (define_insn "*cmpsi_ccno_1"
849   [(set (reg FLAGS_REG)
850         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
851                  (match_operand:SI 1 "const0_operand" "")))]
852   "ix86_match_ccmode (insn, CCNOmode)"
853   "@
854    test{l}\t%0, %0
855    cmp{l}\t{%1, %0|%0, %1}"
856   [(set_attr "type" "test,icmp")
857    (set_attr "length_immediate" "0,1")
858    (set_attr "mode" "SI")])
859
860 (define_insn "*cmpsi_minus_1"
861   [(set (reg FLAGS_REG)
862         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
863                            (match_operand:SI 1 "general_operand" "ri,mr"))
864                  (const_int 0)))]
865   "ix86_match_ccmode (insn, CCGOCmode)"
866   "cmp{l}\t{%1, %0|%0, %1}"
867   [(set_attr "type" "icmp")
868    (set_attr "mode" "SI")])
869
870 (define_expand "cmpsi_1"
871   [(set (reg:CC FLAGS_REG)
872         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
873                     (match_operand:SI 1 "general_operand" "")))]
874   ""
875   "")
876
877 (define_insn "*cmpsi_1_insn"
878   [(set (reg FLAGS_REG)
879         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
880                  (match_operand:SI 1 "general_operand" "ri,mr")))]
881   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
882     && ix86_match_ccmode (insn, CCmode)"
883   "cmp{l}\t{%1, %0|%0, %1}"
884   [(set_attr "type" "icmp")
885    (set_attr "mode" "SI")])
886
887 (define_insn "*cmphi_ccno_1"
888   [(set (reg FLAGS_REG)
889         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
890                  (match_operand:HI 1 "const0_operand" "")))]
891   "ix86_match_ccmode (insn, CCNOmode)"
892   "@
893    test{w}\t%0, %0
894    cmp{w}\t{%1, %0|%0, %1}"
895   [(set_attr "type" "test,icmp")
896    (set_attr "length_immediate" "0,1")
897    (set_attr "mode" "HI")])
898
899 (define_insn "*cmphi_minus_1"
900   [(set (reg FLAGS_REG)
901         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
902                            (match_operand:HI 1 "general_operand" "rn,mr"))
903                  (const_int 0)))]
904   "ix86_match_ccmode (insn, CCGOCmode)"
905   "cmp{w}\t{%1, %0|%0, %1}"
906   [(set_attr "type" "icmp")
907    (set_attr "mode" "HI")])
908
909 (define_insn "*cmphi_1"
910   [(set (reg FLAGS_REG)
911         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
912                  (match_operand:HI 1 "general_operand" "rn,mr")))]
913   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
914    && ix86_match_ccmode (insn, CCmode)"
915   "cmp{w}\t{%1, %0|%0, %1}"
916   [(set_attr "type" "icmp")
917    (set_attr "mode" "HI")])
918
919 (define_insn "*cmpqi_ccno_1"
920   [(set (reg FLAGS_REG)
921         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
922                  (match_operand:QI 1 "const0_operand" "")))]
923   "ix86_match_ccmode (insn, CCNOmode)"
924   "@
925    test{b}\t%0, %0
926    cmp{b}\t{$0, %0|%0, 0}"
927   [(set_attr "type" "test,icmp")
928    (set_attr "length_immediate" "0,1")
929    (set_attr "mode" "QI")])
930
931 (define_insn "*cmpqi_1"
932   [(set (reg FLAGS_REG)
933         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
934                  (match_operand:QI 1 "general_operand" "qn,mq")))]
935   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
936     && ix86_match_ccmode (insn, CCmode)"
937   "cmp{b}\t{%1, %0|%0, %1}"
938   [(set_attr "type" "icmp")
939    (set_attr "mode" "QI")])
940
941 (define_insn "*cmpqi_minus_1"
942   [(set (reg FLAGS_REG)
943         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
944                            (match_operand:QI 1 "general_operand" "qn,mq"))
945                  (const_int 0)))]
946   "ix86_match_ccmode (insn, CCGOCmode)"
947   "cmp{b}\t{%1, %0|%0, %1}"
948   [(set_attr "type" "icmp")
949    (set_attr "mode" "QI")])
950
951 (define_insn "*cmpqi_ext_1"
952   [(set (reg FLAGS_REG)
953         (compare
954           (match_operand:QI 0 "general_operand" "Qm")
955           (subreg:QI
956             (zero_extract:SI
957               (match_operand 1 "ext_register_operand" "Q")
958               (const_int 8)
959               (const_int 8)) 0)))]
960   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
961   "cmp{b}\t{%h1, %0|%0, %h1}"
962   [(set_attr "type" "icmp")
963    (set_attr "mode" "QI")])
964
965 (define_insn "*cmpqi_ext_1_rex64"
966   [(set (reg FLAGS_REG)
967         (compare
968           (match_operand:QI 0 "register_operand" "Q")
969           (subreg:QI
970             (zero_extract:SI
971               (match_operand 1 "ext_register_operand" "Q")
972               (const_int 8)
973               (const_int 8)) 0)))]
974   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
975   "cmp{b}\t{%h1, %0|%0, %h1}"
976   [(set_attr "type" "icmp")
977    (set_attr "mode" "QI")])
978
979 (define_insn "*cmpqi_ext_2"
980   [(set (reg FLAGS_REG)
981         (compare
982           (subreg:QI
983             (zero_extract:SI
984               (match_operand 0 "ext_register_operand" "Q")
985               (const_int 8)
986               (const_int 8)) 0)
987           (match_operand:QI 1 "const0_operand" "")))]
988   "ix86_match_ccmode (insn, CCNOmode)"
989   "test{b}\t%h0, %h0"
990   [(set_attr "type" "test")
991    (set_attr "length_immediate" "0")
992    (set_attr "mode" "QI")])
993
994 (define_expand "cmpqi_ext_3"
995   [(set (reg:CC FLAGS_REG)
996         (compare:CC
997           (subreg:QI
998             (zero_extract:SI
999               (match_operand 0 "ext_register_operand" "")
1000               (const_int 8)
1001               (const_int 8)) 0)
1002           (match_operand:QI 1 "general_operand" "")))]
1003   ""
1004   "")
1005
1006 (define_insn "cmpqi_ext_3_insn"
1007   [(set (reg FLAGS_REG)
1008         (compare
1009           (subreg:QI
1010             (zero_extract:SI
1011               (match_operand 0 "ext_register_operand" "Q")
1012               (const_int 8)
1013               (const_int 8)) 0)
1014           (match_operand:QI 1 "general_operand" "Qmn")))]
1015   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1016   "cmp{b}\t{%1, %h0|%h0, %1}"
1017   [(set_attr "type" "icmp")
1018    (set_attr "mode" "QI")])
1019
1020 (define_insn "cmpqi_ext_3_insn_rex64"
1021   [(set (reg FLAGS_REG)
1022         (compare
1023           (subreg:QI
1024             (zero_extract:SI
1025               (match_operand 0 "ext_register_operand" "Q")
1026               (const_int 8)
1027               (const_int 8)) 0)
1028           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1029   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1030   "cmp{b}\t{%1, %h0|%h0, %1}"
1031   [(set_attr "type" "icmp")
1032    (set_attr "mode" "QI")])
1033
1034 (define_insn "*cmpqi_ext_4"
1035   [(set (reg FLAGS_REG)
1036         (compare
1037           (subreg:QI
1038             (zero_extract:SI
1039               (match_operand 0 "ext_register_operand" "Q")
1040               (const_int 8)
1041               (const_int 8)) 0)
1042           (subreg:QI
1043             (zero_extract:SI
1044               (match_operand 1 "ext_register_operand" "Q")
1045               (const_int 8)
1046               (const_int 8)) 0)))]
1047   "ix86_match_ccmode (insn, CCmode)"
1048   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1049   [(set_attr "type" "icmp")
1050    (set_attr "mode" "QI")])
1051
1052 ;; These implement float point compares.
1053 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1054 ;; which would allow mix and match FP modes on the compares.  Which is what
1055 ;; the old patterns did, but with many more of them.
1056
1057 (define_expand "cmpxf"
1058   [(set (reg:CC FLAGS_REG)
1059         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1060                     (match_operand:XF 1 "nonmemory_operand" "")))]
1061   "TARGET_80387"
1062 {
1063   ix86_compare_op0 = operands[0];
1064   ix86_compare_op1 = operands[1];
1065   DONE;
1066 })
1067
1068 (define_expand "cmp<mode>"
1069   [(set (reg:CC FLAGS_REG)
1070         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1071                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1072   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1073 {
1074   ix86_compare_op0 = operands[0];
1075   ix86_compare_op1 = operands[1];
1076   DONE;
1077 })
1078
1079 ;; FP compares, step 1:
1080 ;; Set the FP condition codes.
1081 ;;
1082 ;; CCFPmode     compare with exceptions
1083 ;; CCFPUmode    compare with no exceptions
1084
1085 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1086 ;; used to manage the reg stack popping would not be preserved.
1087
1088 (define_insn "*cmpfp_0"
1089   [(set (match_operand:HI 0 "register_operand" "=a")
1090         (unspec:HI
1091           [(compare:CCFP
1092              (match_operand 1 "register_operand" "f")
1093              (match_operand 2 "const0_operand" ""))]
1094         UNSPEC_FNSTSW))]
1095   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1096    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1097   "* return output_fp_compare (insn, operands, 0, 0);"
1098   [(set_attr "type" "multi")
1099    (set_attr "unit" "i387")
1100    (set (attr "mode")
1101      (cond [(match_operand:SF 1 "" "")
1102               (const_string "SF")
1103             (match_operand:DF 1 "" "")
1104               (const_string "DF")
1105            ]
1106            (const_string "XF")))])
1107
1108 (define_insn_and_split "*cmpfp_0_cc"
1109   [(set (reg:CCFP FLAGS_REG)
1110         (compare:CCFP
1111           (match_operand 1 "register_operand" "f")
1112           (match_operand 2 "const0_operand" "")))
1113    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1114   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1115    && TARGET_SAHF && !TARGET_CMOVE
1116    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1117   "#"
1118   "&& reload_completed"
1119   [(set (match_dup 0)
1120         (unspec:HI
1121           [(compare:CCFP (match_dup 1)(match_dup 2))]
1122         UNSPEC_FNSTSW))
1123    (set (reg:CC FLAGS_REG)
1124         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1125   ""
1126   [(set_attr "type" "multi")
1127    (set_attr "unit" "i387")
1128    (set (attr "mode")
1129      (cond [(match_operand:SF 1 "" "")
1130               (const_string "SF")
1131             (match_operand:DF 1 "" "")
1132               (const_string "DF")
1133            ]
1134            (const_string "XF")))])
1135
1136 (define_insn "*cmpfp_xf"
1137   [(set (match_operand:HI 0 "register_operand" "=a")
1138         (unspec:HI
1139           [(compare:CCFP
1140              (match_operand:XF 1 "register_operand" "f")
1141              (match_operand:XF 2 "register_operand" "f"))]
1142           UNSPEC_FNSTSW))]
1143   "TARGET_80387"
1144   "* return output_fp_compare (insn, operands, 0, 0);"
1145   [(set_attr "type" "multi")
1146    (set_attr "unit" "i387")
1147    (set_attr "mode" "XF")])
1148
1149 (define_insn_and_split "*cmpfp_xf_cc"
1150   [(set (reg:CCFP FLAGS_REG)
1151         (compare:CCFP
1152           (match_operand:XF 1 "register_operand" "f")
1153           (match_operand:XF 2 "register_operand" "f")))
1154    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1155   "TARGET_80387
1156    && TARGET_SAHF && !TARGET_CMOVE"
1157   "#"
1158   "&& reload_completed"
1159   [(set (match_dup 0)
1160         (unspec:HI
1161           [(compare:CCFP (match_dup 1)(match_dup 2))]
1162         UNSPEC_FNSTSW))
1163    (set (reg:CC FLAGS_REG)
1164         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1165   ""
1166   [(set_attr "type" "multi")
1167    (set_attr "unit" "i387")
1168    (set_attr "mode" "XF")])
1169
1170 (define_insn "*cmpfp_<mode>"
1171   [(set (match_operand:HI 0 "register_operand" "=a")
1172         (unspec:HI
1173           [(compare:CCFP
1174              (match_operand:MODEF 1 "register_operand" "f")
1175              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1176           UNSPEC_FNSTSW))]
1177   "TARGET_80387"
1178   "* return output_fp_compare (insn, operands, 0, 0);"
1179   [(set_attr "type" "multi")
1180    (set_attr "unit" "i387")
1181    (set_attr "mode" "<MODE>")])
1182
1183 (define_insn_and_split "*cmpfp_<mode>_cc"
1184   [(set (reg:CCFP FLAGS_REG)
1185         (compare:CCFP
1186           (match_operand:MODEF 1 "register_operand" "f")
1187           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1188    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1189   "TARGET_80387
1190    && TARGET_SAHF && !TARGET_CMOVE"
1191   "#"
1192   "&& reload_completed"
1193   [(set (match_dup 0)
1194         (unspec:HI
1195           [(compare:CCFP (match_dup 1)(match_dup 2))]
1196         UNSPEC_FNSTSW))
1197    (set (reg:CC FLAGS_REG)
1198         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1199   ""
1200   [(set_attr "type" "multi")
1201    (set_attr "unit" "i387")
1202    (set_attr "mode" "<MODE>")])
1203
1204 (define_insn "*cmpfp_u"
1205   [(set (match_operand:HI 0 "register_operand" "=a")
1206         (unspec:HI
1207           [(compare:CCFPU
1208              (match_operand 1 "register_operand" "f")
1209              (match_operand 2 "register_operand" "f"))]
1210           UNSPEC_FNSTSW))]
1211   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213   "* return output_fp_compare (insn, operands, 0, 1);"
1214   [(set_attr "type" "multi")
1215    (set_attr "unit" "i387")
1216    (set (attr "mode")
1217      (cond [(match_operand:SF 1 "" "")
1218               (const_string "SF")
1219             (match_operand:DF 1 "" "")
1220               (const_string "DF")
1221            ]
1222            (const_string "XF")))])
1223
1224 (define_insn_and_split "*cmpfp_u_cc"
1225   [(set (reg:CCFPU FLAGS_REG)
1226         (compare:CCFPU
1227           (match_operand 1 "register_operand" "f")
1228           (match_operand 2 "register_operand" "f")))
1229    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1230   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231    && TARGET_SAHF && !TARGET_CMOVE
1232    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1233   "#"
1234   "&& reload_completed"
1235   [(set (match_dup 0)
1236         (unspec:HI
1237           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1238         UNSPEC_FNSTSW))
1239    (set (reg:CC FLAGS_REG)
1240         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1241   ""
1242   [(set_attr "type" "multi")
1243    (set_attr "unit" "i387")
1244    (set (attr "mode")
1245      (cond [(match_operand:SF 1 "" "")
1246               (const_string "SF")
1247             (match_operand:DF 1 "" "")
1248               (const_string "DF")
1249            ]
1250            (const_string "XF")))])
1251
1252 (define_insn "*cmpfp_<mode>"
1253   [(set (match_operand:HI 0 "register_operand" "=a")
1254         (unspec:HI
1255           [(compare:CCFP
1256              (match_operand 1 "register_operand" "f")
1257              (match_operator 3 "float_operator"
1258                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1259           UNSPEC_FNSTSW))]
1260   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1261    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1262    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1263   "* return output_fp_compare (insn, operands, 0, 0);"
1264   [(set_attr "type" "multi")
1265    (set_attr "unit" "i387")
1266    (set_attr "fp_int_src" "true")
1267    (set_attr "mode" "<MODE>")])
1268
1269 (define_insn_and_split "*cmpfp_<mode>_cc"
1270   [(set (reg:CCFP FLAGS_REG)
1271         (compare:CCFP
1272           (match_operand 1 "register_operand" "f")
1273           (match_operator 3 "float_operator"
1274             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1275    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1276   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1277    && TARGET_SAHF && !TARGET_CMOVE
1278    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1279    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1280   "#"
1281   "&& reload_completed"
1282   [(set (match_dup 0)
1283         (unspec:HI
1284           [(compare:CCFP
1285              (match_dup 1)
1286              (match_op_dup 3 [(match_dup 2)]))]
1287         UNSPEC_FNSTSW))
1288    (set (reg:CC FLAGS_REG)
1289         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290   ""
1291   [(set_attr "type" "multi")
1292    (set_attr "unit" "i387")
1293    (set_attr "fp_int_src" "true")
1294    (set_attr "mode" "<MODE>")])
1295
1296 ;; FP compares, step 2
1297 ;; Move the fpsw to ax.
1298
1299 (define_insn "x86_fnstsw_1"
1300   [(set (match_operand:HI 0 "register_operand" "=a")
1301         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1302   "TARGET_80387"
1303   "fnstsw\t%0"
1304   [(set_attr "length" "2")
1305    (set_attr "mode" "SI")
1306    (set_attr "unit" "i387")])
1307
1308 ;; FP compares, step 3
1309 ;; Get ax into flags, general case.
1310
1311 (define_insn "x86_sahf_1"
1312   [(set (reg:CC FLAGS_REG)
1313         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1314                    UNSPEC_SAHF))]
1315   "TARGET_SAHF"
1316 {
1317 #ifdef HAVE_AS_IX86_SAHF
1318   return "sahf";
1319 #else
1320   return ".byte\t0x9e";
1321 #endif
1322 }
1323   [(set_attr "length" "1")
1324    (set_attr "athlon_decode" "vector")
1325    (set_attr "amdfam10_decode" "direct")
1326    (set_attr "mode" "SI")])
1327
1328 ;; Pentium Pro can do steps 1 through 3 in one go.
1329 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1330 (define_insn "*cmpfp_i_mixed"
1331   [(set (reg:CCFP FLAGS_REG)
1332         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1333                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1334   "TARGET_MIX_SSE_I387
1335    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1336    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1337   "* return output_fp_compare (insn, operands, 1, 0);"
1338   [(set_attr "type" "fcmp,ssecomi")
1339    (set_attr "prefix" "orig,maybe_vex")
1340    (set (attr "mode")
1341      (if_then_else (match_operand:SF 1 "" "")
1342         (const_string "SF")
1343         (const_string "DF")))
1344    (set_attr "athlon_decode" "vector")
1345    (set_attr "amdfam10_decode" "direct")])
1346
1347 (define_insn "*cmpfp_i_sse"
1348   [(set (reg:CCFP FLAGS_REG)
1349         (compare:CCFP (match_operand 0 "register_operand" "x")
1350                       (match_operand 1 "nonimmediate_operand" "xm")))]
1351   "TARGET_SSE_MATH
1352    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1353    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1354   "* return output_fp_compare (insn, operands, 1, 0);"
1355   [(set_attr "type" "ssecomi")
1356    (set_attr "prefix" "maybe_vex")
1357    (set (attr "mode")
1358      (if_then_else (match_operand:SF 1 "" "")
1359         (const_string "SF")
1360         (const_string "DF")))
1361    (set_attr "athlon_decode" "vector")
1362    (set_attr "amdfam10_decode" "direct")])
1363
1364 (define_insn "*cmpfp_i_i387"
1365   [(set (reg:CCFP FLAGS_REG)
1366         (compare:CCFP (match_operand 0 "register_operand" "f")
1367                       (match_operand 1 "register_operand" "f")))]
1368   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1369    && TARGET_CMOVE
1370    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1371    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372   "* return output_fp_compare (insn, operands, 1, 0);"
1373   [(set_attr "type" "fcmp")
1374    (set (attr "mode")
1375      (cond [(match_operand:SF 1 "" "")
1376               (const_string "SF")
1377             (match_operand:DF 1 "" "")
1378               (const_string "DF")
1379            ]
1380            (const_string "XF")))
1381    (set_attr "athlon_decode" "vector")
1382    (set_attr "amdfam10_decode" "direct")])
1383
1384 (define_insn "*cmpfp_iu_mixed"
1385   [(set (reg:CCFPU FLAGS_REG)
1386         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1387                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1388   "TARGET_MIX_SSE_I387
1389    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1390    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1391   "* return output_fp_compare (insn, operands, 1, 1);"
1392   [(set_attr "type" "fcmp,ssecomi")
1393    (set_attr "prefix" "orig,maybe_vex")
1394    (set (attr "mode")
1395      (if_then_else (match_operand:SF 1 "" "")
1396         (const_string "SF")
1397         (const_string "DF")))
1398    (set_attr "athlon_decode" "vector")
1399    (set_attr "amdfam10_decode" "direct")])
1400
1401 (define_insn "*cmpfp_iu_sse"
1402   [(set (reg:CCFPU FLAGS_REG)
1403         (compare:CCFPU (match_operand 0 "register_operand" "x")
1404                        (match_operand 1 "nonimmediate_operand" "xm")))]
1405   "TARGET_SSE_MATH
1406    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1407    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1408   "* return output_fp_compare (insn, operands, 1, 1);"
1409   [(set_attr "type" "ssecomi")
1410    (set_attr "prefix" "maybe_vex")
1411    (set (attr "mode")
1412      (if_then_else (match_operand:SF 1 "" "")
1413         (const_string "SF")
1414         (const_string "DF")))
1415    (set_attr "athlon_decode" "vector")
1416    (set_attr "amdfam10_decode" "direct")])
1417
1418 (define_insn "*cmpfp_iu_387"
1419   [(set (reg:CCFPU FLAGS_REG)
1420         (compare:CCFPU (match_operand 0 "register_operand" "f")
1421                        (match_operand 1 "register_operand" "f")))]
1422   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1423    && TARGET_CMOVE
1424    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1425    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1426   "* return output_fp_compare (insn, operands, 1, 1);"
1427   [(set_attr "type" "fcmp")
1428    (set (attr "mode")
1429      (cond [(match_operand:SF 1 "" "")
1430               (const_string "SF")
1431             (match_operand:DF 1 "" "")
1432               (const_string "DF")
1433            ]
1434            (const_string "XF")))
1435    (set_attr "athlon_decode" "vector")
1436    (set_attr "amdfam10_decode" "direct")])
1437 \f
1438 ;; Move instructions.
1439
1440 ;; General case of fullword move.
1441
1442 (define_expand "movsi"
1443   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1444         (match_operand:SI 1 "general_operand" ""))]
1445   ""
1446   "ix86_expand_move (SImode, operands); DONE;")
1447
1448 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1449 ;; general_operand.
1450 ;;
1451 ;; %%% We don't use a post-inc memory reference because x86 is not a
1452 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1453 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1454 ;; targets without our curiosities, and it is just as easy to represent
1455 ;; this differently.
1456
1457 (define_insn "*pushsi2"
1458   [(set (match_operand:SI 0 "push_operand" "=<")
1459         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1460   "!TARGET_64BIT"
1461   "push{l}\t%1"
1462   [(set_attr "type" "push")
1463    (set_attr "mode" "SI")])
1464
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushsi2_rex64"
1467   [(set (match_operand:SI 0 "push_operand" "=X")
1468         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1469   "TARGET_64BIT"
1470   "push{q}\t%q1"
1471   [(set_attr "type" "push")
1472    (set_attr "mode" "SI")])
1473
1474 (define_insn "*pushsi2_prologue"
1475   [(set (match_operand:SI 0 "push_operand" "=<")
1476         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1477    (clobber (mem:BLK (scratch)))]
1478   "!TARGET_64BIT"
1479   "push{l}\t%1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "SI")])
1482
1483 (define_insn "*popsi1_epilogue"
1484   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1485         (mem:SI (reg:SI SP_REG)))
1486    (set (reg:SI SP_REG)
1487         (plus:SI (reg:SI SP_REG) (const_int 4)))
1488    (clobber (mem:BLK (scratch)))]
1489   "!TARGET_64BIT"
1490   "pop{l}\t%0"
1491   [(set_attr "type" "pop")
1492    (set_attr "mode" "SI")])
1493
1494 (define_insn "popsi1"
1495   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1496         (mem:SI (reg:SI SP_REG)))
1497    (set (reg:SI SP_REG)
1498         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1499   "!TARGET_64BIT"
1500   "pop{l}\t%0"
1501   [(set_attr "type" "pop")
1502    (set_attr "mode" "SI")])
1503
1504 (define_insn "*movsi_xor"
1505   [(set (match_operand:SI 0 "register_operand" "=r")
1506         (match_operand:SI 1 "const0_operand" ""))
1507    (clobber (reg:CC FLAGS_REG))]
1508   "reload_completed"
1509   "xor{l}\t%0, %0"
1510   [(set_attr "type" "alu1")
1511    (set_attr "mode" "SI")
1512    (set_attr "length_immediate" "0")])
1513
1514 (define_insn "*movsi_or"
1515   [(set (match_operand:SI 0 "register_operand" "=r")
1516         (match_operand:SI 1 "immediate_operand" "i"))
1517    (clobber (reg:CC FLAGS_REG))]
1518   "reload_completed
1519    && operands[1] == constm1_rtx"
1520 {
1521   operands[1] = constm1_rtx;
1522   return "or{l}\t{%1, %0|%0, %1}";
1523 }
1524   [(set_attr "type" "alu1")
1525    (set_attr "mode" "SI")
1526    (set_attr "length_immediate" "1")])
1527
1528 (define_insn "*movsi_1"
1529   [(set (match_operand:SI 0 "nonimmediate_operand"
1530                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1531         (match_operand:SI 1 "general_operand"
1532                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1533   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1534 {
1535   switch (get_attr_type (insn))
1536     {
1537     case TYPE_SSELOG1:
1538       if (get_attr_mode (insn) == MODE_TI)
1539         return "%vpxor\t%0, %d0";
1540       return "%vxorps\t%0, %d0";
1541
1542     case TYPE_SSEMOV:
1543       switch (get_attr_mode (insn))
1544         {
1545         case MODE_TI:
1546           return "%vmovdqa\t{%1, %0|%0, %1}";
1547         case MODE_V4SF:
1548           return "%vmovaps\t{%1, %0|%0, %1}";
1549         case MODE_SI:
1550           return "%vmovd\t{%1, %0|%0, %1}";
1551         case MODE_SF:
1552           return "%vmovss\t{%1, %0|%0, %1}";
1553         default:
1554           gcc_unreachable ();
1555         }
1556
1557     case TYPE_MMX:
1558       return "pxor\t%0, %0";
1559
1560     case TYPE_MMXMOV:
1561       if (get_attr_mode (insn) == MODE_DI)
1562         return "movq\t{%1, %0|%0, %1}";
1563       return "movd\t{%1, %0|%0, %1}";
1564
1565     case TYPE_LEA:
1566       return "lea{l}\t{%1, %0|%0, %1}";
1567
1568     default:
1569       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1570       return "mov{l}\t{%1, %0|%0, %1}";
1571     }
1572 }
1573   [(set (attr "type")
1574      (cond [(eq_attr "alternative" "2")
1575               (const_string "mmx")
1576             (eq_attr "alternative" "3,4,5")
1577               (const_string "mmxmov")
1578             (eq_attr "alternative" "6")
1579               (const_string "sselog1")
1580             (eq_attr "alternative" "7,8,9,10,11")
1581               (const_string "ssemov")
1582             (match_operand:DI 1 "pic_32bit_operand" "")
1583               (const_string "lea")
1584            ]
1585            (const_string "imov")))
1586    (set (attr "prefix")
1587      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1588        (const_string "orig")
1589        (const_string "maybe_vex")))
1590    (set (attr "mode")
1591      (cond [(eq_attr "alternative" "2,3")
1592               (const_string "DI")
1593             (eq_attr "alternative" "6,7")
1594               (if_then_else
1595                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1596                 (const_string "V4SF")
1597                 (const_string "TI"))
1598             (and (eq_attr "alternative" "8,9,10,11")
1599                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1600               (const_string "SF")
1601            ]
1602            (const_string "SI")))])
1603
1604 ;; Stores and loads of ax to arbitrary constant address.
1605 ;; We fake an second form of instruction to force reload to load address
1606 ;; into register when rax is not available
1607 (define_insn "*movabssi_1_rex64"
1608   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1609         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1610   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1611   "@
1612    movabs{l}\t{%1, %P0|%P0, %1}
1613    mov{l}\t{%1, %a0|%a0, %1}"
1614   [(set_attr "type" "imov")
1615    (set_attr "modrm" "0,*")
1616    (set_attr "length_address" "8,0")
1617    (set_attr "length_immediate" "0,*")
1618    (set_attr "memory" "store")
1619    (set_attr "mode" "SI")])
1620
1621 (define_insn "*movabssi_2_rex64"
1622   [(set (match_operand:SI 0 "register_operand" "=a,r")
1623         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1624   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1625   "@
1626    movabs{l}\t{%P1, %0|%0, %P1}
1627    mov{l}\t{%a1, %0|%0, %a1}"
1628   [(set_attr "type" "imov")
1629    (set_attr "modrm" "0,*")
1630    (set_attr "length_address" "8,0")
1631    (set_attr "length_immediate" "0")
1632    (set_attr "memory" "load")
1633    (set_attr "mode" "SI")])
1634
1635 (define_insn "*swapsi"
1636   [(set (match_operand:SI 0 "register_operand" "+r")
1637         (match_operand:SI 1 "register_operand" "+r"))
1638    (set (match_dup 1)
1639         (match_dup 0))]
1640   ""
1641   "xchg{l}\t%1, %0"
1642   [(set_attr "type" "imov")
1643    (set_attr "mode" "SI")
1644    (set_attr "pent_pair" "np")
1645    (set_attr "athlon_decode" "vector")
1646    (set_attr "amdfam10_decode" "double")])
1647
1648 (define_expand "movhi"
1649   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1650         (match_operand:HI 1 "general_operand" ""))]
1651   ""
1652   "ix86_expand_move (HImode, operands); DONE;")
1653
1654 (define_insn "*pushhi2"
1655   [(set (match_operand:HI 0 "push_operand" "=X")
1656         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1657   "!TARGET_64BIT"
1658   "push{l}\t%k1"
1659   [(set_attr "type" "push")
1660    (set_attr "mode" "SI")])
1661
1662 ;; For 64BIT abi we always round up to 8 bytes.
1663 (define_insn "*pushhi2_rex64"
1664   [(set (match_operand:HI 0 "push_operand" "=X")
1665         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1666   "TARGET_64BIT"
1667   "push{q}\t%q1"
1668   [(set_attr "type" "push")
1669    (set_attr "mode" "DI")])
1670
1671 (define_insn "*movhi_1"
1672   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1673         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1674   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1675 {
1676   switch (get_attr_type (insn))
1677     {
1678     case TYPE_IMOVX:
1679       /* movzwl is faster than movw on p2 due to partial word stalls,
1680          though not as fast as an aligned movl.  */
1681       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1682     default:
1683       if (get_attr_mode (insn) == MODE_SI)
1684         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1685       else
1686         return "mov{w}\t{%1, %0|%0, %1}";
1687     }
1688 }
1689   [(set (attr "type")
1690      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1691               (const_string "imov")
1692             (and (eq_attr "alternative" "0")
1693                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1694                           (const_int 0))
1695                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1696                           (const_int 0))))
1697               (const_string "imov")
1698             (and (eq_attr "alternative" "1,2")
1699                  (match_operand:HI 1 "aligned_operand" ""))
1700               (const_string "imov")
1701             (and (ne (symbol_ref "TARGET_MOVX")
1702                      (const_int 0))
1703                  (eq_attr "alternative" "0,2"))
1704               (const_string "imovx")
1705            ]
1706            (const_string "imov")))
1707     (set (attr "mode")
1708       (cond [(eq_attr "type" "imovx")
1709                (const_string "SI")
1710              (and (eq_attr "alternative" "1,2")
1711                   (match_operand:HI 1 "aligned_operand" ""))
1712                (const_string "SI")
1713              (and (eq_attr "alternative" "0")
1714                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1715                            (const_int 0))
1716                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1717                            (const_int 0))))
1718                (const_string "SI")
1719             ]
1720             (const_string "HI")))])
1721
1722 ;; Stores and loads of ax to arbitrary constant address.
1723 ;; We fake an second form of instruction to force reload to load address
1724 ;; into register when rax is not available
1725 (define_insn "*movabshi_1_rex64"
1726   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1727         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1728   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1729   "@
1730    movabs{w}\t{%1, %P0|%P0, %1}
1731    mov{w}\t{%1, %a0|%a0, %1}"
1732   [(set_attr "type" "imov")
1733    (set_attr "modrm" "0,*")
1734    (set_attr "length_address" "8,0")
1735    (set_attr "length_immediate" "0,*")
1736    (set_attr "memory" "store")
1737    (set_attr "mode" "HI")])
1738
1739 (define_insn "*movabshi_2_rex64"
1740   [(set (match_operand:HI 0 "register_operand" "=a,r")
1741         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1742   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1743   "@
1744    movabs{w}\t{%P1, %0|%0, %P1}
1745    mov{w}\t{%a1, %0|%0, %a1}"
1746   [(set_attr "type" "imov")
1747    (set_attr "modrm" "0,*")
1748    (set_attr "length_address" "8,0")
1749    (set_attr "length_immediate" "0")
1750    (set_attr "memory" "load")
1751    (set_attr "mode" "HI")])
1752
1753 (define_insn "*swaphi_1"
1754   [(set (match_operand:HI 0 "register_operand" "+r")
1755         (match_operand:HI 1 "register_operand" "+r"))
1756    (set (match_dup 1)
1757         (match_dup 0))]
1758   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1759   "xchg{l}\t%k1, %k0"
1760   [(set_attr "type" "imov")
1761    (set_attr "mode" "SI")
1762    (set_attr "pent_pair" "np")
1763    (set_attr "athlon_decode" "vector")
1764    (set_attr "amdfam10_decode" "double")])
1765
1766 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1767 (define_insn "*swaphi_2"
1768   [(set (match_operand:HI 0 "register_operand" "+r")
1769         (match_operand:HI 1 "register_operand" "+r"))
1770    (set (match_dup 1)
1771         (match_dup 0))]
1772   "TARGET_PARTIAL_REG_STALL"
1773   "xchg{w}\t%1, %0"
1774   [(set_attr "type" "imov")
1775    (set_attr "mode" "HI")
1776    (set_attr "pent_pair" "np")
1777    (set_attr "athlon_decode" "vector")])
1778
1779 (define_expand "movstricthi"
1780   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1781         (match_operand:HI 1 "general_operand" ""))]
1782   ""
1783 {
1784   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1785     FAIL;
1786   /* Don't generate memory->memory moves, go through a register */
1787   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1788     operands[1] = force_reg (HImode, operands[1]);
1789 })
1790
1791 (define_insn "*movstricthi_1"
1792   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1793         (match_operand:HI 1 "general_operand" "rn,m"))]
1794   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1795    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1796   "mov{w}\t{%1, %0|%0, %1}"
1797   [(set_attr "type" "imov")
1798    (set_attr "mode" "HI")])
1799
1800 (define_insn "*movstricthi_xor"
1801   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1802         (match_operand:HI 1 "const0_operand" ""))
1803    (clobber (reg:CC FLAGS_REG))]
1804   "reload_completed"
1805   "xor{w}\t%0, %0"
1806   [(set_attr "type" "alu1")
1807    (set_attr "mode" "HI")
1808    (set_attr "length_immediate" "0")])
1809
1810 (define_expand "movqi"
1811   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1812         (match_operand:QI 1 "general_operand" ""))]
1813   ""
1814   "ix86_expand_move (QImode, operands); DONE;")
1815
1816 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1817 ;; "push a byte".  But actually we use pushl, which has the effect
1818 ;; of rounding the amount pushed up to a word.
1819
1820 (define_insn "*pushqi2"
1821   [(set (match_operand:QI 0 "push_operand" "=X")
1822         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1823   "!TARGET_64BIT"
1824   "push{l}\t%k1"
1825   [(set_attr "type" "push")
1826    (set_attr "mode" "SI")])
1827
1828 ;; For 64BIT abi we always round up to 8 bytes.
1829 (define_insn "*pushqi2_rex64"
1830   [(set (match_operand:QI 0 "push_operand" "=X")
1831         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1832   "TARGET_64BIT"
1833   "push{q}\t%q1"
1834   [(set_attr "type" "push")
1835    (set_attr "mode" "DI")])
1836
1837 ;; Situation is quite tricky about when to choose full sized (SImode) move
1838 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1839 ;; partial register dependency machines (such as AMD Athlon), where QImode
1840 ;; moves issue extra dependency and for partial register stalls machines
1841 ;; that don't use QImode patterns (and QImode move cause stall on the next
1842 ;; instruction).
1843 ;;
1844 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1845 ;; register stall machines with, where we use QImode instructions, since
1846 ;; partial register stall can be caused there.  Then we use movzx.
1847 (define_insn "*movqi_1"
1848   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1849         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1850   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1851 {
1852   switch (get_attr_type (insn))
1853     {
1854     case TYPE_IMOVX:
1855       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1856       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1857     default:
1858       if (get_attr_mode (insn) == MODE_SI)
1859         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1860       else
1861         return "mov{b}\t{%1, %0|%0, %1}";
1862     }
1863 }
1864   [(set (attr "type")
1865      (cond [(and (eq_attr "alternative" "5")
1866                  (not (match_operand:QI 1 "aligned_operand" "")))
1867               (const_string "imovx")
1868             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1869               (const_string "imov")
1870             (and (eq_attr "alternative" "3")
1871                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1872                           (const_int 0))
1873                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1874                           (const_int 0))))
1875               (const_string "imov")
1876             (eq_attr "alternative" "3,5")
1877               (const_string "imovx")
1878             (and (ne (symbol_ref "TARGET_MOVX")
1879                      (const_int 0))
1880                  (eq_attr "alternative" "2"))
1881               (const_string "imovx")
1882            ]
1883            (const_string "imov")))
1884    (set (attr "mode")
1885       (cond [(eq_attr "alternative" "3,4,5")
1886                (const_string "SI")
1887              (eq_attr "alternative" "6")
1888                (const_string "QI")
1889              (eq_attr "type" "imovx")
1890                (const_string "SI")
1891              (and (eq_attr "type" "imov")
1892                   (and (eq_attr "alternative" "0,1")
1893                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1894                                 (const_int 0))
1895                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1896                                      (const_int 0))
1897                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1898                                      (const_int 0))))))
1899                (const_string "SI")
1900              ;; Avoid partial register stalls when not using QImode arithmetic
1901              (and (eq_attr "type" "imov")
1902                   (and (eq_attr "alternative" "0,1")
1903                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1904                                 (const_int 0))
1905                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1906                                 (const_int 0)))))
1907                (const_string "SI")
1908            ]
1909            (const_string "QI")))])
1910
1911 (define_insn "*swapqi_1"
1912   [(set (match_operand:QI 0 "register_operand" "+r")
1913         (match_operand:QI 1 "register_operand" "+r"))
1914    (set (match_dup 1)
1915         (match_dup 0))]
1916   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1917   "xchg{l}\t%k1, %k0"
1918   [(set_attr "type" "imov")
1919    (set_attr "mode" "SI")
1920    (set_attr "pent_pair" "np")
1921    (set_attr "athlon_decode" "vector")
1922    (set_attr "amdfam10_decode" "vector")])
1923
1924 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1925 (define_insn "*swapqi_2"
1926   [(set (match_operand:QI 0 "register_operand" "+q")
1927         (match_operand:QI 1 "register_operand" "+q"))
1928    (set (match_dup 1)
1929         (match_dup 0))]
1930   "TARGET_PARTIAL_REG_STALL"
1931   "xchg{b}\t%1, %0"
1932   [(set_attr "type" "imov")
1933    (set_attr "mode" "QI")
1934    (set_attr "pent_pair" "np")
1935    (set_attr "athlon_decode" "vector")])
1936
1937 (define_expand "movstrictqi"
1938   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1939         (match_operand:QI 1 "general_operand" ""))]
1940   ""
1941 {
1942   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1943     FAIL;
1944   /* Don't generate memory->memory moves, go through a register.  */
1945   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1946     operands[1] = force_reg (QImode, operands[1]);
1947 })
1948
1949 (define_insn "*movstrictqi_1"
1950   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1951         (match_operand:QI 1 "general_operand" "*qn,m"))]
1952   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1953    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1954   "mov{b}\t{%1, %0|%0, %1}"
1955   [(set_attr "type" "imov")
1956    (set_attr "mode" "QI")])
1957
1958 (define_insn "*movstrictqi_xor"
1959   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1960         (match_operand:QI 1 "const0_operand" ""))
1961    (clobber (reg:CC FLAGS_REG))]
1962   "reload_completed"
1963   "xor{b}\t%0, %0"
1964   [(set_attr "type" "alu1")
1965    (set_attr "mode" "QI")
1966    (set_attr "length_immediate" "0")])
1967
1968 (define_insn "*movsi_extv_1"
1969   [(set (match_operand:SI 0 "register_operand" "=R")
1970         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1971                          (const_int 8)
1972                          (const_int 8)))]
1973   ""
1974   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1975   [(set_attr "type" "imovx")
1976    (set_attr "mode" "SI")])
1977
1978 (define_insn "*movhi_extv_1"
1979   [(set (match_operand:HI 0 "register_operand" "=R")
1980         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1981                          (const_int 8)
1982                          (const_int 8)))]
1983   ""
1984   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1985   [(set_attr "type" "imovx")
1986    (set_attr "mode" "SI")])
1987
1988 (define_insn "*movqi_extv_1"
1989   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1990         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1991                          (const_int 8)
1992                          (const_int 8)))]
1993   "!TARGET_64BIT"
1994 {
1995   switch (get_attr_type (insn))
1996     {
1997     case TYPE_IMOVX:
1998       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1999     default:
2000       return "mov{b}\t{%h1, %0|%0, %h1}";
2001     }
2002 }
2003   [(set (attr "type")
2004      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2005                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2006                              (ne (symbol_ref "TARGET_MOVX")
2007                                  (const_int 0))))
2008         (const_string "imovx")
2009         (const_string "imov")))
2010    (set (attr "mode")
2011      (if_then_else (eq_attr "type" "imovx")
2012         (const_string "SI")
2013         (const_string "QI")))])
2014
2015 (define_insn "*movqi_extv_1_rex64"
2016   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2017         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2018                          (const_int 8)
2019                          (const_int 8)))]
2020   "TARGET_64BIT"
2021 {
2022   switch (get_attr_type (insn))
2023     {
2024     case TYPE_IMOVX:
2025       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2026     default:
2027       return "mov{b}\t{%h1, %0|%0, %h1}";
2028     }
2029 }
2030   [(set (attr "type")
2031      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2032                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2033                              (ne (symbol_ref "TARGET_MOVX")
2034                                  (const_int 0))))
2035         (const_string "imovx")
2036         (const_string "imov")))
2037    (set (attr "mode")
2038      (if_then_else (eq_attr "type" "imovx")
2039         (const_string "SI")
2040         (const_string "QI")))])
2041
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsqi_1_rex64"
2046   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2048   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2049   "@
2050    movabs{b}\t{%1, %P0|%P0, %1}
2051    mov{b}\t{%1, %a0|%a0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "modrm" "0,*")
2054    (set_attr "length_address" "8,0")
2055    (set_attr "length_immediate" "0,*")
2056    (set_attr "memory" "store")
2057    (set_attr "mode" "QI")])
2058
2059 (define_insn "*movabsqi_2_rex64"
2060   [(set (match_operand:QI 0 "register_operand" "=a,r")
2061         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2063   "@
2064    movabs{b}\t{%P1, %0|%0, %P1}
2065    mov{b}\t{%a1, %0|%0, %a1}"
2066   [(set_attr "type" "imov")
2067    (set_attr "modrm" "0,*")
2068    (set_attr "length_address" "8,0")
2069    (set_attr "length_immediate" "0")
2070    (set_attr "memory" "load")
2071    (set_attr "mode" "QI")])
2072
2073 (define_insn "*movdi_extzv_1"
2074   [(set (match_operand:DI 0 "register_operand" "=R")
2075         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2076                          (const_int 8)
2077                          (const_int 8)))]
2078   "TARGET_64BIT"
2079   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2080   [(set_attr "type" "imovx")
2081    (set_attr "mode" "DI")])
2082
2083 (define_insn "*movsi_extzv_1"
2084   [(set (match_operand:SI 0 "register_operand" "=R")
2085         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2086                          (const_int 8)
2087                          (const_int 8)))]
2088   ""
2089   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2090   [(set_attr "type" "imovx")
2091    (set_attr "mode" "SI")])
2092
2093 (define_insn "*movqi_extzv_2"
2094   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2095         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2096                                     (const_int 8)
2097                                     (const_int 8)) 0))]
2098   "!TARGET_64BIT"
2099 {
2100   switch (get_attr_type (insn))
2101     {
2102     case TYPE_IMOVX:
2103       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2104     default:
2105       return "mov{b}\t{%h1, %0|%0, %h1}";
2106     }
2107 }
2108   [(set (attr "type")
2109      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2110                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2111                              (ne (symbol_ref "TARGET_MOVX")
2112                                  (const_int 0))))
2113         (const_string "imovx")
2114         (const_string "imov")))
2115    (set (attr "mode")
2116      (if_then_else (eq_attr "type" "imovx")
2117         (const_string "SI")
2118         (const_string "QI")))])
2119
2120 (define_insn "*movqi_extzv_2_rex64"
2121   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2122         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2123                                     (const_int 8)
2124                                     (const_int 8)) 0))]
2125   "TARGET_64BIT"
2126 {
2127   switch (get_attr_type (insn))
2128     {
2129     case TYPE_IMOVX:
2130       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2131     default:
2132       return "mov{b}\t{%h1, %0|%0, %h1}";
2133     }
2134 }
2135   [(set (attr "type")
2136      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2137                         (ne (symbol_ref "TARGET_MOVX")
2138                             (const_int 0)))
2139         (const_string "imovx")
2140         (const_string "imov")))
2141    (set (attr "mode")
2142      (if_then_else (eq_attr "type" "imovx")
2143         (const_string "SI")
2144         (const_string "QI")))])
2145
2146 (define_insn "movsi_insv_1"
2147   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2148                          (const_int 8)
2149                          (const_int 8))
2150         (match_operand:SI 1 "general_operand" "Qmn"))]
2151   "!TARGET_64BIT"
2152   "mov{b}\t{%b1, %h0|%h0, %b1}"
2153   [(set_attr "type" "imov")
2154    (set_attr "mode" "QI")])
2155
2156 (define_insn "*movsi_insv_1_rex64"
2157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2158                          (const_int 8)
2159                          (const_int 8))
2160         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2161   "TARGET_64BIT"
2162   "mov{b}\t{%b1, %h0|%h0, %b1}"
2163   [(set_attr "type" "imov")
2164    (set_attr "mode" "QI")])
2165
2166 (define_insn "movdi_insv_1_rex64"
2167   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2168                          (const_int 8)
2169                          (const_int 8))
2170         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2171   "TARGET_64BIT"
2172   "mov{b}\t{%b1, %h0|%h0, %b1}"
2173   [(set_attr "type" "imov")
2174    (set_attr "mode" "QI")])
2175
2176 (define_insn "*movqi_insv_2"
2177   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2178                          (const_int 8)
2179                          (const_int 8))
2180         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2181                      (const_int 8)))]
2182   ""
2183   "mov{b}\t{%h1, %h0|%h0, %h1}"
2184   [(set_attr "type" "imov")
2185    (set_attr "mode" "QI")])
2186
2187 (define_expand "movdi"
2188   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2189         (match_operand:DI 1 "general_operand" ""))]
2190   ""
2191   "ix86_expand_move (DImode, operands); DONE;")
2192
2193 (define_insn "*pushdi"
2194   [(set (match_operand:DI 0 "push_operand" "=<")
2195         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2196   "!TARGET_64BIT"
2197   "#")
2198
2199 (define_insn "*pushdi2_rex64"
2200   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2201         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2202   "TARGET_64BIT"
2203   "@
2204    push{q}\t%1
2205    #"
2206   [(set_attr "type" "push,multi")
2207    (set_attr "mode" "DI")])
2208
2209 ;; Convert impossible pushes of immediate to existing instructions.
2210 ;; First try to get scratch register and go through it.  In case this
2211 ;; fails, push sign extended lower part first and then overwrite
2212 ;; upper part by 32bit move.
2213 (define_peephole2
2214   [(match_scratch:DI 2 "r")
2215    (set (match_operand:DI 0 "push_operand" "")
2216         (match_operand:DI 1 "immediate_operand" ""))]
2217   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2218    && !x86_64_immediate_operand (operands[1], DImode)"
2219   [(set (match_dup 2) (match_dup 1))
2220    (set (match_dup 0) (match_dup 2))]
2221   "")
2222
2223 ;; We need to define this as both peepholer and splitter for case
2224 ;; peephole2 pass is not run.
2225 ;; "&& 1" is needed to keep it from matching the previous pattern.
2226 (define_peephole2
2227   [(set (match_operand:DI 0 "push_operand" "")
2228         (match_operand:DI 1 "immediate_operand" ""))]
2229   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2230    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2231   [(set (match_dup 0) (match_dup 1))
2232    (set (match_dup 2) (match_dup 3))]
2233   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2234    operands[1] = gen_lowpart (DImode, operands[2]);
2235    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2236                                                     GEN_INT (4)));
2237   ")
2238
2239 (define_split
2240   [(set (match_operand:DI 0 "push_operand" "")
2241         (match_operand:DI 1 "immediate_operand" ""))]
2242   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2243                     ? epilogue_completed : reload_completed)
2244    && !symbolic_operand (operands[1], DImode)
2245    && !x86_64_immediate_operand (operands[1], DImode)"
2246   [(set (match_dup 0) (match_dup 1))
2247    (set (match_dup 2) (match_dup 3))]
2248   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2249    operands[1] = gen_lowpart (DImode, operands[2]);
2250    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2251                                                     GEN_INT (4)));
2252   ")
2253
2254 (define_insn "*pushdi2_prologue_rex64"
2255   [(set (match_operand:DI 0 "push_operand" "=<")
2256         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2257    (clobber (mem:BLK (scratch)))]
2258   "TARGET_64BIT"
2259   "push{q}\t%1"
2260   [(set_attr "type" "push")
2261    (set_attr "mode" "DI")])
2262
2263 (define_insn "*popdi1_epilogue_rex64"
2264   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2265         (mem:DI (reg:DI SP_REG)))
2266    (set (reg:DI SP_REG)
2267         (plus:DI (reg:DI SP_REG) (const_int 8)))
2268    (clobber (mem:BLK (scratch)))]
2269   "TARGET_64BIT"
2270   "pop{q}\t%0"
2271   [(set_attr "type" "pop")
2272    (set_attr "mode" "DI")])
2273
2274 (define_insn "popdi1"
2275   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2276         (mem:DI (reg:DI SP_REG)))
2277    (set (reg:DI SP_REG)
2278         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2279   "TARGET_64BIT"
2280   "pop{q}\t%0"
2281   [(set_attr "type" "pop")
2282    (set_attr "mode" "DI")])
2283
2284 (define_insn "*movdi_xor_rex64"
2285   [(set (match_operand:DI 0 "register_operand" "=r")
2286         (match_operand:DI 1 "const0_operand" ""))
2287    (clobber (reg:CC FLAGS_REG))]
2288   "TARGET_64BIT
2289    && reload_completed"
2290   "xor{l}\t%k0, %k0";
2291   [(set_attr "type" "alu1")
2292    (set_attr "mode" "SI")
2293    (set_attr "length_immediate" "0")])
2294
2295 (define_insn "*movdi_or_rex64"
2296   [(set (match_operand:DI 0 "register_operand" "=r")
2297         (match_operand:DI 1 "const_int_operand" "i"))
2298    (clobber (reg:CC FLAGS_REG))]
2299   "TARGET_64BIT
2300    && reload_completed
2301    && operands[1] == constm1_rtx"
2302 {
2303   operands[1] = constm1_rtx;
2304   return "or{q}\t{%1, %0|%0, %1}";
2305 }
2306   [(set_attr "type" "alu1")
2307    (set_attr "mode" "DI")
2308    (set_attr "length_immediate" "1")])
2309
2310 (define_insn "*movdi_2"
2311   [(set (match_operand:DI 0 "nonimmediate_operand"
2312                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2313         (match_operand:DI 1 "general_operand"
2314                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2315   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2316   "@
2317    #
2318    #
2319    pxor\t%0, %0
2320    movq\t{%1, %0|%0, %1}
2321    movq\t{%1, %0|%0, %1}
2322    %vpxor\t%0, %d0
2323    %vmovq\t{%1, %0|%0, %1}
2324    %vmovdqa\t{%1, %0|%0, %1}
2325    %vmovq\t{%1, %0|%0, %1}
2326    xorps\t%0, %0
2327    movlps\t{%1, %0|%0, %1}
2328    movaps\t{%1, %0|%0, %1}
2329    movlps\t{%1, %0|%0, %1}"
2330   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2331    (set (attr "prefix")
2332      (if_then_else (eq_attr "alternative" "5,6,7,8")
2333        (const_string "vex")
2334        (const_string "orig")))
2335    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2336
2337 (define_split
2338   [(set (match_operand:DI 0 "push_operand" "")
2339         (match_operand:DI 1 "general_operand" ""))]
2340   "!TARGET_64BIT && reload_completed
2341    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2342   [(const_int 0)]
2343   "ix86_split_long_move (operands); DONE;")
2344
2345 ;; %%% This multiword shite has got to go.
2346 (define_split
2347   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2348         (match_operand:DI 1 "general_operand" ""))]
2349   "!TARGET_64BIT && reload_completed
2350    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2351    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2352   [(const_int 0)]
2353   "ix86_split_long_move (operands); DONE;")
2354
2355 (define_insn "*movdi_1_rex64"
2356   [(set (match_operand:DI 0 "nonimmediate_operand"
2357           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2358         (match_operand:DI 1 "general_operand"
2359           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2360   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2361 {
2362   switch (get_attr_type (insn))
2363     {
2364     case TYPE_SSECVT:
2365       if (SSE_REG_P (operands[0]))
2366         return "movq2dq\t{%1, %0|%0, %1}";
2367       else
2368         return "movdq2q\t{%1, %0|%0, %1}";
2369
2370     case TYPE_SSEMOV:
2371       if (TARGET_AVX)
2372         {
2373           if (get_attr_mode (insn) == MODE_TI)
2374             return "vmovdqa\t{%1, %0|%0, %1}";
2375           else
2376             return "vmovq\t{%1, %0|%0, %1}";
2377         }
2378
2379       if (get_attr_mode (insn) == MODE_TI)
2380         return "movdqa\t{%1, %0|%0, %1}";
2381       /* FALLTHRU */
2382
2383     case TYPE_MMXMOV:
2384       /* Moves from and into integer register is done using movd
2385          opcode with REX prefix.  */
2386       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2387         return "movd\t{%1, %0|%0, %1}";
2388       return "movq\t{%1, %0|%0, %1}";
2389
2390     case TYPE_SSELOG1:
2391       return "%vpxor\t%0, %d0";
2392
2393     case TYPE_MMX:
2394       return "pxor\t%0, %0";
2395
2396     case TYPE_MULTI:
2397       return "#";
2398
2399     case TYPE_LEA:
2400       return "lea{q}\t{%a1, %0|%0, %a1}";
2401
2402     default:
2403       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2404       if (get_attr_mode (insn) == MODE_SI)
2405         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2406       else if (which_alternative == 2)
2407         return "movabs{q}\t{%1, %0|%0, %1}";
2408       else
2409         return "mov{q}\t{%1, %0|%0, %1}";
2410     }
2411 }
2412   [(set (attr "type")
2413      (cond [(eq_attr "alternative" "5")
2414               (const_string "mmx")
2415             (eq_attr "alternative" "6,7,8,9,10")
2416               (const_string "mmxmov")
2417             (eq_attr "alternative" "11")
2418               (const_string "sselog1")
2419             (eq_attr "alternative" "12,13,14,15,16")
2420               (const_string "ssemov")
2421             (eq_attr "alternative" "17,18")
2422               (const_string "ssecvt")
2423             (eq_attr "alternative" "4")
2424               (const_string "multi")
2425             (match_operand:DI 1 "pic_32bit_operand" "")
2426               (const_string "lea")
2427            ]
2428            (const_string "imov")))
2429    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2430    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2431    (set (attr "prefix")
2432      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2433        (const_string "maybe_vex")
2434        (const_string "orig")))
2435    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2436
2437 ;; Stores and loads of ax to arbitrary constant address.
2438 ;; We fake an second form of instruction to force reload to load address
2439 ;; into register when rax is not available
2440 (define_insn "*movabsdi_1_rex64"
2441   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2442         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2443   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2444   "@
2445    movabs{q}\t{%1, %P0|%P0, %1}
2446    mov{q}\t{%1, %a0|%a0, %1}"
2447   [(set_attr "type" "imov")
2448    (set_attr "modrm" "0,*")
2449    (set_attr "length_address" "8,0")
2450    (set_attr "length_immediate" "0,*")
2451    (set_attr "memory" "store")
2452    (set_attr "mode" "DI")])
2453
2454 (define_insn "*movabsdi_2_rex64"
2455   [(set (match_operand:DI 0 "register_operand" "=a,r")
2456         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2457   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2458   "@
2459    movabs{q}\t{%P1, %0|%0, %P1}
2460    mov{q}\t{%a1, %0|%0, %a1}"
2461   [(set_attr "type" "imov")
2462    (set_attr "modrm" "0,*")
2463    (set_attr "length_address" "8,0")
2464    (set_attr "length_immediate" "0")
2465    (set_attr "memory" "load")
2466    (set_attr "mode" "DI")])
2467
2468 ;; Convert impossible stores of immediate to existing instructions.
2469 ;; First try to get scratch register and go through it.  In case this
2470 ;; fails, move by 32bit parts.
2471 (define_peephole2
2472   [(match_scratch:DI 2 "r")
2473    (set (match_operand:DI 0 "memory_operand" "")
2474         (match_operand:DI 1 "immediate_operand" ""))]
2475   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2476    && !x86_64_immediate_operand (operands[1], DImode)"
2477   [(set (match_dup 2) (match_dup 1))
2478    (set (match_dup 0) (match_dup 2))]
2479   "")
2480
2481 ;; We need to define this as both peepholer and splitter for case
2482 ;; peephole2 pass is not run.
2483 ;; "&& 1" is needed to keep it from matching the previous pattern.
2484 (define_peephole2
2485   [(set (match_operand:DI 0 "memory_operand" "")
2486         (match_operand:DI 1 "immediate_operand" ""))]
2487   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2488    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2489   [(set (match_dup 2) (match_dup 3))
2490    (set (match_dup 4) (match_dup 5))]
2491   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2492
2493 (define_split
2494   [(set (match_operand:DI 0 "memory_operand" "")
2495         (match_operand:DI 1 "immediate_operand" ""))]
2496   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2497                     ? epilogue_completed : reload_completed)
2498    && !symbolic_operand (operands[1], DImode)
2499    && !x86_64_immediate_operand (operands[1], DImode)"
2500   [(set (match_dup 2) (match_dup 3))
2501    (set (match_dup 4) (match_dup 5))]
2502   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2503
2504 (define_insn "*swapdi_rex64"
2505   [(set (match_operand:DI 0 "register_operand" "+r")
2506         (match_operand:DI 1 "register_operand" "+r"))
2507    (set (match_dup 1)
2508         (match_dup 0))]
2509   "TARGET_64BIT"
2510   "xchg{q}\t%1, %0"
2511   [(set_attr "type" "imov")
2512    (set_attr "mode" "DI")
2513    (set_attr "pent_pair" "np")
2514    (set_attr "athlon_decode" "vector")
2515    (set_attr "amdfam10_decode" "double")])
2516
2517 (define_expand "movoi"
2518   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2519         (match_operand:OI 1 "general_operand" ""))]
2520   "TARGET_AVX"
2521   "ix86_expand_move (OImode, operands); DONE;")
2522
2523 (define_insn "*movoi_internal"
2524   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2525         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2526   "TARGET_AVX
2527    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2528 {
2529   switch (which_alternative)
2530     {
2531     case 0:
2532       return "vxorps\t%0, %0, %0";
2533     case 1:
2534     case 2:
2535       if (misaligned_operand (operands[0], OImode)
2536           || misaligned_operand (operands[1], OImode))
2537         return "vmovdqu\t{%1, %0|%0, %1}";
2538       else
2539         return "vmovdqa\t{%1, %0|%0, %1}";
2540     default:
2541       gcc_unreachable ();
2542     }
2543 }
2544   [(set_attr "type" "sselog1,ssemov,ssemov")
2545    (set_attr "prefix" "vex")
2546    (set_attr "mode" "OI")])
2547
2548 (define_expand "movti"
2549   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2550         (match_operand:TI 1 "nonimmediate_operand" ""))]
2551   "TARGET_SSE || TARGET_64BIT"
2552 {
2553   if (TARGET_64BIT)
2554     ix86_expand_move (TImode, operands);
2555   else if (push_operand (operands[0], TImode))
2556     ix86_expand_push (TImode, operands[1]);
2557   else
2558     ix86_expand_vector_move (TImode, operands);
2559   DONE;
2560 })
2561
2562 (define_insn "*movti_internal"
2563   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2564         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2565   "TARGET_SSE && !TARGET_64BIT
2566    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2567 {
2568   switch (which_alternative)
2569     {
2570     case 0:
2571       if (get_attr_mode (insn) == MODE_V4SF)
2572         return "%vxorps\t%0, %d0";
2573       else
2574         return "%vpxor\t%0, %d0";
2575     case 1:
2576     case 2:
2577       /* TDmode values are passed as TImode on the stack.  Moving them
2578          to stack may result in unaligned memory access.  */
2579       if (misaligned_operand (operands[0], TImode)
2580           || misaligned_operand (operands[1], TImode))
2581         {
2582           if (get_attr_mode (insn) == MODE_V4SF)
2583             return "%vmovups\t{%1, %0|%0, %1}";
2584          else
2585            return "%vmovdqu\t{%1, %0|%0, %1}";
2586         }
2587       else
2588         {
2589           if (get_attr_mode (insn) == MODE_V4SF)
2590             return "%vmovaps\t{%1, %0|%0, %1}";
2591          else
2592            return "%vmovdqa\t{%1, %0|%0, %1}";
2593         }
2594     default:
2595       gcc_unreachable ();
2596     }
2597 }
2598   [(set_attr "type" "sselog1,ssemov,ssemov")
2599    (set_attr "prefix" "maybe_vex")
2600    (set (attr "mode")
2601         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2602                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2603                  (const_string "V4SF")
2604                (and (eq_attr "alternative" "2")
2605                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2606                         (const_int 0)))
2607                  (const_string "V4SF")]
2608               (const_string "TI")))])
2609
2610 (define_insn "*movti_rex64"
2611   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2612         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2613   "TARGET_64BIT
2614    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2615 {
2616   switch (which_alternative)
2617     {
2618     case 0:
2619     case 1:
2620       return "#";
2621     case 2:
2622       if (get_attr_mode (insn) == MODE_V4SF)
2623         return "%vxorps\t%0, %d0";
2624       else
2625         return "%vpxor\t%0, %d0";
2626     case 3:
2627     case 4:
2628       /* TDmode values are passed as TImode on the stack.  Moving them
2629          to stack may result in unaligned memory access.  */
2630       if (misaligned_operand (operands[0], TImode)
2631           || misaligned_operand (operands[1], TImode))
2632         {
2633           if (get_attr_mode (insn) == MODE_V4SF)
2634             return "%vmovups\t{%1, %0|%0, %1}";
2635          else
2636            return "%vmovdqu\t{%1, %0|%0, %1}";
2637         }
2638       else
2639         {
2640           if (get_attr_mode (insn) == MODE_V4SF)
2641             return "%vmovaps\t{%1, %0|%0, %1}";
2642          else
2643            return "%vmovdqa\t{%1, %0|%0, %1}";
2644         }
2645     default:
2646       gcc_unreachable ();
2647     }
2648 }
2649   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2650    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2651    (set (attr "mode")
2652         (cond [(eq_attr "alternative" "2,3")
2653                  (if_then_else
2654                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2655                        (const_int 0))
2656                    (const_string "V4SF")
2657                    (const_string "TI"))
2658                (eq_attr "alternative" "4")
2659                  (if_then_else
2660                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2661                             (const_int 0))
2662                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2663                             (const_int 0)))
2664                    (const_string "V4SF")
2665                    (const_string "TI"))]
2666                (const_string "DI")))])
2667
2668 (define_split
2669   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2670         (match_operand:TI 1 "general_operand" ""))]
2671   "reload_completed && !SSE_REG_P (operands[0])
2672    && !SSE_REG_P (operands[1])"
2673   [(const_int 0)]
2674   "ix86_split_long_move (operands); DONE;")
2675
2676 ;; This expands to what emit_move_complex would generate if we didn't
2677 ;; have a movti pattern.  Having this avoids problems with reload on
2678 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2679 ;; to have around all the time.
2680 (define_expand "movcdi"
2681   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2682         (match_operand:CDI 1 "general_operand" ""))]
2683   ""
2684 {
2685   if (push_operand (operands[0], CDImode))
2686     emit_move_complex_push (CDImode, operands[0], operands[1]);
2687   else
2688     emit_move_complex_parts (operands[0], operands[1]);
2689   DONE;
2690 })
2691
2692 (define_expand "movsf"
2693   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2694         (match_operand:SF 1 "general_operand" ""))]
2695   ""
2696   "ix86_expand_move (SFmode, operands); DONE;")
2697
2698 (define_insn "*pushsf"
2699   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2700         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2701   "!TARGET_64BIT"
2702 {
2703   /* Anything else should be already split before reg-stack.  */
2704   gcc_assert (which_alternative == 1);
2705   return "push{l}\t%1";
2706 }
2707   [(set_attr "type" "multi,push,multi")
2708    (set_attr "unit" "i387,*,*")
2709    (set_attr "mode" "SF,SI,SF")])
2710
2711 (define_insn "*pushsf_rex64"
2712   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2713         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2714   "TARGET_64BIT"
2715 {
2716   /* Anything else should be already split before reg-stack.  */
2717   gcc_assert (which_alternative == 1);
2718   return "push{q}\t%q1";
2719 }
2720   [(set_attr "type" "multi,push,multi")
2721    (set_attr "unit" "i387,*,*")
2722    (set_attr "mode" "SF,DI,SF")])
2723
2724 (define_split
2725   [(set (match_operand:SF 0 "push_operand" "")
2726         (match_operand:SF 1 "memory_operand" ""))]
2727   "reload_completed
2728    && MEM_P (operands[1])
2729    && (operands[2] = find_constant_src (insn))"
2730   [(set (match_dup 0)
2731         (match_dup 2))])
2732
2733
2734 ;; %%% Kill this when call knows how to work this out.
2735 (define_split
2736   [(set (match_operand:SF 0 "push_operand" "")
2737         (match_operand:SF 1 "any_fp_register_operand" ""))]
2738   "!TARGET_64BIT"
2739   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2740    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2741
2742 (define_split
2743   [(set (match_operand:SF 0 "push_operand" "")
2744         (match_operand:SF 1 "any_fp_register_operand" ""))]
2745   "TARGET_64BIT"
2746   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2747    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2748
2749 (define_insn "*movsf_1"
2750   [(set (match_operand:SF 0 "nonimmediate_operand"
2751           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2752         (match_operand:SF 1 "general_operand"
2753           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2754   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2755    && (reload_in_progress || reload_completed
2756        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2757        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2758            && standard_80387_constant_p (operands[1]))
2759        || GET_CODE (operands[1]) != CONST_DOUBLE
2760        || memory_operand (operands[0], SFmode))"
2761 {
2762   switch (which_alternative)
2763     {
2764     case 0:
2765     case 1:
2766       return output_387_reg_move (insn, operands);
2767
2768     case 2:
2769       return standard_80387_constant_opcode (operands[1]);
2770
2771     case 3:
2772     case 4:
2773       return "mov{l}\t{%1, %0|%0, %1}";
2774     case 5:
2775       if (get_attr_mode (insn) == MODE_TI)
2776         return "%vpxor\t%0, %d0";
2777       else
2778         return "%vxorps\t%0, %d0";
2779     case 6:
2780       if (get_attr_mode (insn) == MODE_V4SF)
2781         return "%vmovaps\t{%1, %0|%0, %1}";
2782       else
2783         return "%vmovss\t{%1, %d0|%d0, %1}";
2784     case 7:
2785       if (TARGET_AVX)
2786         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2787                                    : "vmovss\t{%1, %0|%0, %1}";
2788       else
2789         return "movss\t{%1, %0|%0, %1}";
2790     case 8:
2791       return "%vmovss\t{%1, %0|%0, %1}";
2792
2793     case 9: case 10: case 14: case 15:
2794       return "movd\t{%1, %0|%0, %1}";
2795     case 12: case 13:
2796       return "%vmovd\t{%1, %0|%0, %1}";
2797
2798     case 11:
2799       return "movq\t{%1, %0|%0, %1}";
2800
2801     default:
2802       gcc_unreachable ();
2803     }
2804 }
2805   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2806    (set (attr "prefix")
2807      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2808        (const_string "maybe_vex")
2809        (const_string "orig")))
2810    (set (attr "mode")
2811         (cond [(eq_attr "alternative" "3,4,9,10")
2812                  (const_string "SI")
2813                (eq_attr "alternative" "5")
2814                  (if_then_else
2815                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2816                                  (const_int 0))
2817                              (ne (symbol_ref "TARGET_SSE2")
2818                                  (const_int 0)))
2819                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2820                             (const_int 0)))
2821                    (const_string "TI")
2822                    (const_string "V4SF"))
2823                /* For architectures resolving dependencies on
2824                   whole SSE registers use APS move to break dependency
2825                   chains, otherwise use short move to avoid extra work.
2826
2827                   Do the same for architectures resolving dependencies on
2828                   the parts.  While in DF mode it is better to always handle
2829                   just register parts, the SF mode is different due to lack
2830                   of instructions to load just part of the register.  It is
2831                   better to maintain the whole registers in single format
2832                   to avoid problems on using packed logical operations.  */
2833                (eq_attr "alternative" "6")
2834                  (if_then_else
2835                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2836                             (const_int 0))
2837                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2838                             (const_int 0)))
2839                    (const_string "V4SF")
2840                    (const_string "SF"))
2841                (eq_attr "alternative" "11")
2842                  (const_string "DI")]
2843                (const_string "SF")))])
2844
2845 (define_insn "*swapsf"
2846   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2847         (match_operand:SF 1 "fp_register_operand" "+f"))
2848    (set (match_dup 1)
2849         (match_dup 0))]
2850   "reload_completed || TARGET_80387"
2851 {
2852   if (STACK_TOP_P (operands[0]))
2853     return "fxch\t%1";
2854   else
2855     return "fxch\t%0";
2856 }
2857   [(set_attr "type" "fxch")
2858    (set_attr "mode" "SF")])
2859
2860 (define_expand "movdf"
2861   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2862         (match_operand:DF 1 "general_operand" ""))]
2863   ""
2864   "ix86_expand_move (DFmode, operands); DONE;")
2865
2866 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2867 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2868 ;; On the average, pushdf using integers can be still shorter.  Allow this
2869 ;; pattern for optimize_size too.
2870
2871 (define_insn "*pushdf_nointeger"
2872   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2873         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2874   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2875 {
2876   /* This insn should be already split before reg-stack.  */
2877   gcc_unreachable ();
2878 }
2879   [(set_attr "type" "multi")
2880    (set_attr "unit" "i387,*,*,*")
2881    (set_attr "mode" "DF,SI,SI,DF")])
2882
2883 (define_insn "*pushdf_integer"
2884   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2885         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2886   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2887 {
2888   /* This insn should be already split before reg-stack.  */
2889   gcc_unreachable ();
2890 }
2891   [(set_attr "type" "multi")
2892    (set_attr "unit" "i387,*,*")
2893    (set_attr "mode" "DF,SI,DF")])
2894
2895 ;; %%% Kill this when call knows how to work this out.
2896 (define_split
2897   [(set (match_operand:DF 0 "push_operand" "")
2898         (match_operand:DF 1 "any_fp_register_operand" ""))]
2899   "reload_completed"
2900   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2901    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2902   "")
2903
2904 (define_split
2905   [(set (match_operand:DF 0 "push_operand" "")
2906         (match_operand:DF 1 "general_operand" ""))]
2907   "reload_completed"
2908   [(const_int 0)]
2909   "ix86_split_long_move (operands); DONE;")
2910
2911 ;; Moving is usually shorter when only FP registers are used. This separate
2912 ;; movdf pattern avoids the use of integer registers for FP operations
2913 ;; when optimizing for size.
2914
2915 (define_insn "*movdf_nointeger"
2916   [(set (match_operand:DF 0 "nonimmediate_operand"
2917                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2918         (match_operand:DF 1 "general_operand"
2919                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2920   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2921    && ((optimize_function_for_size_p (cfun)
2922        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2923    && (reload_in_progress || reload_completed
2924        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2925        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2926            && optimize_function_for_size_p (cfun)
2927            && !memory_operand (operands[0], DFmode)
2928            && standard_80387_constant_p (operands[1]))
2929        || GET_CODE (operands[1]) != CONST_DOUBLE
2930        || ((optimize_function_for_size_p (cfun)
2931             || !TARGET_MEMORY_MISMATCH_STALL
2932             || reload_in_progress || reload_completed)
2933            && memory_operand (operands[0], DFmode)))"
2934 {
2935   switch (which_alternative)
2936     {
2937     case 0:
2938     case 1:
2939       return output_387_reg_move (insn, operands);
2940
2941     case 2:
2942       return standard_80387_constant_opcode (operands[1]);
2943
2944     case 3:
2945     case 4:
2946       return "#";
2947     case 5:
2948       switch (get_attr_mode (insn))
2949         {
2950         case MODE_V4SF:
2951           return "%vxorps\t%0, %d0";
2952         case MODE_V2DF:
2953           return "%vxorpd\t%0, %d0";
2954         case MODE_TI:
2955           return "%vpxor\t%0, %d0";
2956         default:
2957           gcc_unreachable ();
2958         }
2959     case 6:
2960     case 7:
2961     case 8:
2962       switch (get_attr_mode (insn))
2963         {
2964         case MODE_V4SF:
2965           return "%vmovaps\t{%1, %0|%0, %1}";
2966         case MODE_V2DF:
2967           return "%vmovapd\t{%1, %0|%0, %1}";
2968         case MODE_TI:
2969           return "%vmovdqa\t{%1, %0|%0, %1}";
2970         case MODE_DI:
2971           return "%vmovq\t{%1, %0|%0, %1}";
2972         case MODE_DF:
2973           if (TARGET_AVX)
2974             {
2975               if (REG_P (operands[0]) && REG_P (operands[1]))
2976                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2977               else
2978                 return "vmovsd\t{%1, %0|%0, %1}";
2979             }
2980           else
2981             return "movsd\t{%1, %0|%0, %1}";
2982         case MODE_V1DF:
2983           if (TARGET_AVX)
2984             {
2985               if (REG_P (operands[0]))
2986                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2987               else
2988                 return "vmovlpd\t{%1, %0|%0, %1}";
2989             }
2990           else
2991             return "movlpd\t{%1, %0|%0, %1}";
2992         case MODE_V2SF:
2993           if (TARGET_AVX)
2994             {
2995               if (REG_P (operands[0]))
2996                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2997               else
2998                 return "vmovlps\t{%1, %0|%0, %1}";
2999             }
3000           else
3001             return "movlps\t{%1, %0|%0, %1}";
3002         default:
3003           gcc_unreachable ();
3004         }
3005
3006     default:
3007       gcc_unreachable ();
3008     }
3009 }
3010   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3011    (set (attr "prefix")
3012      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3013        (const_string "orig")
3014        (const_string "maybe_vex")))
3015    (set (attr "mode")
3016         (cond [(eq_attr "alternative" "0,1,2")
3017                  (const_string "DF")
3018                (eq_attr "alternative" "3,4")
3019                  (const_string "SI")
3020
3021                /* For SSE1, we have many fewer alternatives.  */
3022                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3023                  (cond [(eq_attr "alternative" "5,6")
3024                           (const_string "V4SF")
3025                        ]
3026                    (const_string "V2SF"))
3027
3028                /* xorps is one byte shorter.  */
3029                (eq_attr "alternative" "5")
3030                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3031                             (const_int 0))
3032                           (const_string "V4SF")
3033                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3034                             (const_int 0))
3035                           (const_string "TI")
3036                        ]
3037                        (const_string "V2DF"))
3038
3039                /* For architectures resolving dependencies on
3040                   whole SSE registers use APD move to break dependency
3041                   chains, otherwise use short move to avoid extra work.
3042
3043                   movaps encodes one byte shorter.  */
3044                (eq_attr "alternative" "6")
3045                  (cond
3046                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3047                         (const_int 0))
3048                       (const_string "V4SF")
3049                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3050                         (const_int 0))
3051                       (const_string "V2DF")
3052                    ]
3053                    (const_string "DF"))
3054                /* For architectures resolving dependencies on register
3055                   parts we may avoid extra work to zero out upper part
3056                   of register.  */
3057                (eq_attr "alternative" "7")
3058                  (if_then_else
3059                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3060                        (const_int 0))
3061                    (const_string "V1DF")
3062                    (const_string "DF"))
3063               ]
3064               (const_string "DF")))])
3065
3066 (define_insn "*movdf_integer_rex64"
3067   [(set (match_operand:DF 0 "nonimmediate_operand"
3068                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3069         (match_operand:DF 1 "general_operand"
3070                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3071   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3072    && (reload_in_progress || reload_completed
3073        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3074        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3075            && optimize_function_for_size_p (cfun)
3076            && standard_80387_constant_p (operands[1]))
3077        || GET_CODE (operands[1]) != CONST_DOUBLE
3078        || memory_operand (operands[0], DFmode))"
3079 {
3080   switch (which_alternative)
3081     {
3082     case 0:
3083     case 1:
3084       return output_387_reg_move (insn, operands);
3085
3086     case 2:
3087       return standard_80387_constant_opcode (operands[1]);
3088
3089     case 3:
3090     case 4:
3091       return "#";
3092
3093     case 5:
3094       switch (get_attr_mode (insn))
3095         {
3096         case MODE_V4SF:
3097           return "%vxorps\t%0, %d0";
3098         case MODE_V2DF:
3099           return "%vxorpd\t%0, %d0";
3100         case MODE_TI:
3101           return "%vpxor\t%0, %d0";
3102         default:
3103           gcc_unreachable ();
3104         }
3105     case 6:
3106     case 7:
3107     case 8:
3108       switch (get_attr_mode (insn))
3109         {
3110         case MODE_V4SF:
3111           return "%vmovaps\t{%1, %0|%0, %1}";
3112         case MODE_V2DF:
3113           return "%vmovapd\t{%1, %0|%0, %1}";
3114         case MODE_TI:
3115           return "%vmovdqa\t{%1, %0|%0, %1}";
3116         case MODE_DI:
3117           return "%vmovq\t{%1, %0|%0, %1}";
3118         case MODE_DF:
3119           if (TARGET_AVX)
3120             {
3121               if (REG_P (operands[0]) && REG_P (operands[1]))
3122                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3123               else
3124                 return "vmovsd\t{%1, %0|%0, %1}";
3125             }
3126           else
3127             return "movsd\t{%1, %0|%0, %1}";
3128         case MODE_V1DF:
3129           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3130         case MODE_V2SF:
3131           return "%vmovlps\t{%1, %d0|%d0, %1}";
3132         default:
3133           gcc_unreachable ();
3134         }
3135
3136     case 9:
3137     case 10:
3138     return "%vmovd\t{%1, %0|%0, %1}";
3139
3140     default:
3141       gcc_unreachable();
3142     }
3143 }
3144   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3145    (set (attr "prefix")
3146      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3147        (const_string "orig")
3148        (const_string "maybe_vex")))
3149    (set (attr "mode")
3150         (cond [(eq_attr "alternative" "0,1,2")
3151                  (const_string "DF")
3152                (eq_attr "alternative" "3,4,9,10")
3153                  (const_string "DI")
3154
3155                /* For SSE1, we have many fewer alternatives.  */
3156                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3157                  (cond [(eq_attr "alternative" "5,6")
3158                           (const_string "V4SF")
3159                        ]
3160                    (const_string "V2SF"))
3161
3162                /* xorps is one byte shorter.  */
3163                (eq_attr "alternative" "5")
3164                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3165                             (const_int 0))
3166                           (const_string "V4SF")
3167                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3168                             (const_int 0))
3169                           (const_string "TI")
3170                        ]
3171                        (const_string "V2DF"))
3172
3173                /* For architectures resolving dependencies on
3174                   whole SSE registers use APD move to break dependency
3175                   chains, otherwise use short move to avoid extra work.
3176
3177                   movaps encodes one byte shorter.  */
3178                (eq_attr "alternative" "6")
3179                  (cond
3180                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3181                         (const_int 0))
3182                       (const_string "V4SF")
3183                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3184                         (const_int 0))
3185                       (const_string "V2DF")
3186                    ]
3187                    (const_string "DF"))
3188                /* For architectures resolving dependencies on register
3189                   parts we may avoid extra work to zero out upper part
3190                   of register.  */
3191                (eq_attr "alternative" "7")
3192                  (if_then_else
3193                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3194                        (const_int 0))
3195                    (const_string "V1DF")
3196                    (const_string "DF"))
3197               ]
3198               (const_string "DF")))])
3199
3200 (define_insn "*movdf_integer"
3201   [(set (match_operand:DF 0 "nonimmediate_operand"
3202                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3203         (match_operand:DF 1 "general_operand"
3204                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3205   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3206    && optimize_function_for_speed_p (cfun)
3207    && TARGET_INTEGER_DFMODE_MOVES
3208    && (reload_in_progress || reload_completed
3209        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3210        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3211            && optimize_function_for_size_p (cfun)
3212            && standard_80387_constant_p (operands[1]))
3213        || GET_CODE (operands[1]) != CONST_DOUBLE
3214        || memory_operand (operands[0], DFmode))"
3215 {
3216   switch (which_alternative)
3217     {
3218     case 0:
3219     case 1:
3220       return output_387_reg_move (insn, operands);
3221
3222     case 2:
3223       return standard_80387_constant_opcode (operands[1]);
3224
3225     case 3:
3226     case 4:
3227       return "#";
3228
3229     case 5:
3230       switch (get_attr_mode (insn))
3231         {
3232         case MODE_V4SF:
3233           return "xorps\t%0, %0";
3234         case MODE_V2DF:
3235           return "xorpd\t%0, %0";
3236         case MODE_TI:
3237           return "pxor\t%0, %0";
3238         default:
3239           gcc_unreachable ();
3240         }
3241     case 6:
3242     case 7:
3243     case 8:
3244       switch (get_attr_mode (insn))
3245         {
3246         case MODE_V4SF:
3247           return "movaps\t{%1, %0|%0, %1}";
3248         case MODE_V2DF:
3249           return "movapd\t{%1, %0|%0, %1}";
3250         case MODE_TI:
3251           return "movdqa\t{%1, %0|%0, %1}";
3252         case MODE_DI:
3253           return "movq\t{%1, %0|%0, %1}";
3254         case MODE_DF:
3255           return "movsd\t{%1, %0|%0, %1}";
3256         case MODE_V1DF:
3257           return "movlpd\t{%1, %0|%0, %1}";
3258         case MODE_V2SF:
3259           return "movlps\t{%1, %0|%0, %1}";
3260         default:
3261           gcc_unreachable ();
3262         }
3263
3264     default:
3265       gcc_unreachable();
3266     }
3267 }
3268   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3269    (set (attr "mode")
3270         (cond [(eq_attr "alternative" "0,1,2")
3271                  (const_string "DF")
3272                (eq_attr "alternative" "3,4")
3273                  (const_string "SI")
3274
3275                /* For SSE1, we have many fewer alternatives.  */
3276                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3277                  (cond [(eq_attr "alternative" "5,6")
3278                           (const_string "V4SF")
3279                        ]
3280                    (const_string "V2SF"))
3281
3282                /* xorps is one byte shorter.  */
3283                (eq_attr "alternative" "5")
3284                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3285                             (const_int 0))
3286                           (const_string "V4SF")
3287                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3288                             (const_int 0))
3289                           (const_string "TI")
3290                        ]
3291                        (const_string "V2DF"))
3292
3293                /* For architectures resolving dependencies on
3294                   whole SSE registers use APD move to break dependency
3295                   chains, otherwise use short move to avoid extra work.
3296
3297                   movaps encodes one byte shorter.  */
3298                (eq_attr "alternative" "6")
3299                  (cond
3300                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3301                         (const_int 0))
3302                       (const_string "V4SF")
3303                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3304                         (const_int 0))
3305                       (const_string "V2DF")
3306                    ]
3307                    (const_string "DF"))
3308                /* For architectures resolving dependencies on register
3309                   parts we may avoid extra work to zero out upper part
3310                   of register.  */
3311                (eq_attr "alternative" "7")
3312                  (if_then_else
3313                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3314                        (const_int 0))
3315                    (const_string "V1DF")
3316                    (const_string "DF"))
3317               ]
3318               (const_string "DF")))])
3319
3320 (define_split
3321   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3322         (match_operand:DF 1 "general_operand" ""))]
3323   "reload_completed
3324    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3325    && ! (ANY_FP_REG_P (operands[0]) ||
3326          (GET_CODE (operands[0]) == SUBREG
3327           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3328    && ! (ANY_FP_REG_P (operands[1]) ||
3329          (GET_CODE (operands[1]) == SUBREG
3330           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3331   [(const_int 0)]
3332   "ix86_split_long_move (operands); DONE;")
3333
3334 (define_insn "*swapdf"
3335   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3336         (match_operand:DF 1 "fp_register_operand" "+f"))
3337    (set (match_dup 1)
3338         (match_dup 0))]
3339   "reload_completed || TARGET_80387"
3340 {
3341   if (STACK_TOP_P (operands[0]))
3342     return "fxch\t%1";
3343   else
3344     return "fxch\t%0";
3345 }
3346   [(set_attr "type" "fxch")
3347    (set_attr "mode" "DF")])
3348
3349 (define_expand "movxf"
3350   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3351         (match_operand:XF 1 "general_operand" ""))]
3352   ""
3353   "ix86_expand_move (XFmode, operands); DONE;")
3354
3355 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3356 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3357 ;; Pushing using integer instructions is longer except for constants
3358 ;; and direct memory references.
3359 ;; (assuming that any given constant is pushed only once, but this ought to be
3360 ;;  handled elsewhere).
3361
3362 (define_insn "*pushxf_nointeger"
3363   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3364         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3365   "optimize_function_for_size_p (cfun)"
3366 {
3367   /* This insn should be already split before reg-stack.  */
3368   gcc_unreachable ();
3369 }
3370   [(set_attr "type" "multi")
3371    (set_attr "unit" "i387,*,*")
3372    (set_attr "mode" "XF,SI,SI")])
3373
3374 (define_insn "*pushxf_integer"
3375   [(set (match_operand:XF 0 "push_operand" "=<,<")
3376         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3377   "optimize_function_for_speed_p (cfun)"
3378 {
3379   /* This insn should be already split before reg-stack.  */
3380   gcc_unreachable ();
3381 }
3382   [(set_attr "type" "multi")
3383    (set_attr "unit" "i387,*")
3384    (set_attr "mode" "XF,SI")])
3385
3386 (define_split
3387   [(set (match_operand 0 "push_operand" "")
3388         (match_operand 1 "general_operand" ""))]
3389   "reload_completed
3390    && (GET_MODE (operands[0]) == XFmode
3391        || GET_MODE (operands[0]) == DFmode)
3392    && !ANY_FP_REG_P (operands[1])"
3393   [(const_int 0)]
3394   "ix86_split_long_move (operands); DONE;")
3395
3396 (define_split
3397   [(set (match_operand:XF 0 "push_operand" "")
3398         (match_operand:XF 1 "any_fp_register_operand" ""))]
3399   ""
3400   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3401    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3402   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3403
3404 ;; Do not use integer registers when optimizing for size
3405 (define_insn "*movxf_nointeger"
3406   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3407         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3408   "optimize_function_for_size_p (cfun)
3409    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3410    && (reload_in_progress || reload_completed
3411        || standard_80387_constant_p (operands[1])
3412        || GET_CODE (operands[1]) != CONST_DOUBLE
3413        || memory_operand (operands[0], XFmode))"
3414 {
3415   switch (which_alternative)
3416     {
3417     case 0:
3418     case 1:
3419       return output_387_reg_move (insn, operands);
3420
3421     case 2:
3422       return standard_80387_constant_opcode (operands[1]);
3423
3424     case 3: case 4:
3425       return "#";
3426     default:
3427       gcc_unreachable ();
3428     }
3429 }
3430   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3431    (set_attr "mode" "XF,XF,XF,SI,SI")])
3432
3433 (define_insn "*movxf_integer"
3434   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3435         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3436   "optimize_function_for_speed_p (cfun)
3437    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3438    && (reload_in_progress || reload_completed
3439        || GET_CODE (operands[1]) != CONST_DOUBLE
3440        || memory_operand (operands[0], XFmode))"
3441 {
3442   switch (which_alternative)
3443     {
3444     case 0:
3445     case 1:
3446       return output_387_reg_move (insn, operands);
3447
3448     case 2:
3449       return standard_80387_constant_opcode (operands[1]);
3450
3451     case 3: case 4:
3452       return "#";
3453
3454     default:
3455       gcc_unreachable ();
3456     }
3457 }
3458   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3459    (set_attr "mode" "XF,XF,XF,SI,SI")])
3460
3461 (define_expand "movtf"
3462   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3463         (match_operand:TF 1 "nonimmediate_operand" ""))]
3464   "TARGET_SSE2"
3465 {
3466   ix86_expand_move (TFmode, operands);
3467   DONE;
3468 })
3469
3470 (define_insn "*movtf_internal"
3471   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3472         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3473   "TARGET_SSE2
3474    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3475 {
3476   switch (which_alternative)
3477     {
3478     case 0:
3479     case 1:
3480       if (get_attr_mode (insn) == MODE_V4SF)
3481         return "%vmovaps\t{%1, %0|%0, %1}";
3482       else
3483         return "%vmovdqa\t{%1, %0|%0, %1}";
3484     case 2:
3485       if (get_attr_mode (insn) == MODE_V4SF)
3486         return "%vxorps\t%0, %d0";
3487       else
3488         return "%vpxor\t%0, %d0";
3489     case 3:
3490     case 4:
3491         return "#";
3492     default:
3493       gcc_unreachable ();
3494     }
3495 }
3496   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3497    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3498    (set (attr "mode")
3499         (cond [(eq_attr "alternative" "0,2")
3500                  (if_then_else
3501                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3502                        (const_int 0))
3503                    (const_string "V4SF")
3504                    (const_string "TI"))
3505                (eq_attr "alternative" "1")
3506                  (if_then_else
3507                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3508                             (const_int 0))
3509                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3510                             (const_int 0)))
3511                    (const_string "V4SF")
3512                    (const_string "TI"))]
3513                (const_string "DI")))])
3514
3515 (define_insn "*pushtf_sse"
3516   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3517         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3518   "TARGET_SSE2"
3519 {
3520   /* This insn should be already split before reg-stack.  */
3521   gcc_unreachable ();
3522 }
3523   [(set_attr "type" "multi")
3524    (set_attr "unit" "sse,*,*")
3525    (set_attr "mode" "TF,SI,SI")])
3526
3527 (define_split
3528   [(set (match_operand:TF 0 "push_operand" "")
3529         (match_operand:TF 1 "general_operand" ""))]
3530   "TARGET_SSE2 && reload_completed
3531    && !SSE_REG_P (operands[1])"
3532   [(const_int 0)]
3533   "ix86_split_long_move (operands); DONE;")
3534
3535 (define_split
3536   [(set (match_operand:TF 0 "push_operand" "")
3537         (match_operand:TF 1 "any_fp_register_operand" ""))]
3538   "TARGET_SSE2"
3539   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3540    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3541   "")
3542
3543 (define_split
3544   [(set (match_operand 0 "nonimmediate_operand" "")
3545         (match_operand 1 "general_operand" ""))]
3546   "reload_completed
3547    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3548    && GET_MODE (operands[0]) == XFmode
3549    && ! (ANY_FP_REG_P (operands[0]) ||
3550          (GET_CODE (operands[0]) == SUBREG
3551           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3552    && ! (ANY_FP_REG_P (operands[1]) ||
3553          (GET_CODE (operands[1]) == SUBREG
3554           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3555   [(const_int 0)]
3556   "ix86_split_long_move (operands); DONE;")
3557
3558 (define_split
3559   [(set (match_operand 0 "register_operand" "")
3560         (match_operand 1 "memory_operand" ""))]
3561   "reload_completed
3562    && MEM_P (operands[1])
3563    && (GET_MODE (operands[0]) == TFmode
3564        || GET_MODE (operands[0]) == XFmode
3565        || GET_MODE (operands[0]) == SFmode
3566        || GET_MODE (operands[0]) == DFmode)
3567    && (operands[2] = find_constant_src (insn))"
3568   [(set (match_dup 0) (match_dup 2))]
3569 {
3570   rtx c = operands[2];
3571   rtx r = operands[0];
3572
3573   if (GET_CODE (r) == SUBREG)
3574     r = SUBREG_REG (r);
3575
3576   if (SSE_REG_P (r))
3577     {
3578       if (!standard_sse_constant_p (c))
3579         FAIL;
3580     }
3581   else if (FP_REG_P (r))
3582     {
3583       if (!standard_80387_constant_p (c))
3584         FAIL;
3585     }
3586   else if (MMX_REG_P (r))
3587     FAIL;
3588 })
3589
3590 (define_split
3591   [(set (match_operand 0 "register_operand" "")
3592         (float_extend (match_operand 1 "memory_operand" "")))]
3593   "reload_completed
3594    && MEM_P (operands[1])
3595    && (GET_MODE (operands[0]) == TFmode
3596        || GET_MODE (operands[0]) == XFmode
3597        || GET_MODE (operands[0]) == SFmode
3598        || GET_MODE (operands[0]) == DFmode)
3599    && (operands[2] = find_constant_src (insn))"
3600   [(set (match_dup 0) (match_dup 2))]
3601 {
3602   rtx c = operands[2];
3603   rtx r = operands[0];
3604
3605   if (GET_CODE (r) == SUBREG)
3606     r = SUBREG_REG (r);
3607
3608   if (SSE_REG_P (r))
3609     {
3610       if (!standard_sse_constant_p (c))
3611         FAIL;
3612     }
3613   else if (FP_REG_P (r))
3614     {
3615       if (!standard_80387_constant_p (c))
3616         FAIL;
3617     }
3618   else if (MMX_REG_P (r))
3619     FAIL;
3620 })
3621
3622 (define_insn "swapxf"
3623   [(set (match_operand:XF 0 "register_operand" "+f")
3624         (match_operand:XF 1 "register_operand" "+f"))
3625    (set (match_dup 1)
3626         (match_dup 0))]
3627   "TARGET_80387"
3628 {
3629   if (STACK_TOP_P (operands[0]))
3630     return "fxch\t%1";
3631   else
3632     return "fxch\t%0";
3633 }
3634   [(set_attr "type" "fxch")
3635    (set_attr "mode" "XF")])
3636
3637 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3638 (define_split
3639   [(set (match_operand:X87MODEF 0 "register_operand" "")
3640         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3641   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3642    && (standard_80387_constant_p (operands[1]) == 8
3643        || standard_80387_constant_p (operands[1]) == 9)"
3644   [(set (match_dup 0)(match_dup 1))
3645    (set (match_dup 0)
3646         (neg:X87MODEF (match_dup 0)))]
3647 {
3648   REAL_VALUE_TYPE r;
3649
3650   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3651   if (real_isnegzero (&r))
3652     operands[1] = CONST0_RTX (<MODE>mode);
3653   else
3654     operands[1] = CONST1_RTX (<MODE>mode);
3655 })
3656
3657 (define_split
3658   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3659         (match_operand:TF 1 "general_operand" ""))]
3660   "reload_completed
3661    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3662   [(const_int 0)]
3663   "ix86_split_long_move (operands); DONE;")
3664 \f
3665 ;; Zero extension instructions
3666
3667 (define_expand "zero_extendhisi2"
3668   [(set (match_operand:SI 0 "register_operand" "")
3669      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3670   ""
3671 {
3672   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3673     {
3674       operands[1] = force_reg (HImode, operands[1]);
3675       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3676       DONE;
3677     }
3678 })
3679
3680 (define_insn "zero_extendhisi2_and"
3681   [(set (match_operand:SI 0 "register_operand" "=r")
3682      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3683    (clobber (reg:CC FLAGS_REG))]
3684   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3685   "#"
3686   [(set_attr "type" "alu1")
3687    (set_attr "mode" "SI")])
3688
3689 (define_split
3690   [(set (match_operand:SI 0 "register_operand" "")
3691         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3692    (clobber (reg:CC FLAGS_REG))]
3693   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3694    && optimize_function_for_speed_p (cfun)"
3695   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3696               (clobber (reg:CC FLAGS_REG))])]
3697   "")
3698
3699 (define_insn "*zero_extendhisi2_movzwl"
3700   [(set (match_operand:SI 0 "register_operand" "=r")
3701      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3702   "!TARGET_ZERO_EXTEND_WITH_AND
3703    || optimize_function_for_size_p (cfun)"
3704   "movz{wl|x}\t{%1, %0|%0, %1}"
3705   [(set_attr "type" "imovx")
3706    (set_attr "mode" "SI")])
3707
3708 (define_expand "zero_extendqihi2"
3709   [(parallel
3710     [(set (match_operand:HI 0 "register_operand" "")
3711        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3712      (clobber (reg:CC FLAGS_REG))])]
3713   ""
3714   "")
3715
3716 (define_insn "*zero_extendqihi2_and"
3717   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3718      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3719    (clobber (reg:CC FLAGS_REG))]
3720   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3721   "#"
3722   [(set_attr "type" "alu1")
3723    (set_attr "mode" "HI")])
3724
3725 (define_insn "*zero_extendqihi2_movzbw_and"
3726   [(set (match_operand:HI 0 "register_operand" "=r,r")
3727      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3728    (clobber (reg:CC FLAGS_REG))]
3729   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3730   "#"
3731   [(set_attr "type" "imovx,alu1")
3732    (set_attr "mode" "HI")])
3733
3734 ; zero extend to SImode here to avoid partial register stalls
3735 (define_insn "*zero_extendqihi2_movzbl"
3736   [(set (match_operand:HI 0 "register_operand" "=r")
3737      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3738   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3739    && reload_completed"
3740   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3741   [(set_attr "type" "imovx")
3742    (set_attr "mode" "SI")])
3743
3744 ;; For the movzbw case strip only the clobber
3745 (define_split
3746   [(set (match_operand:HI 0 "register_operand" "")
3747         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3748    (clobber (reg:CC FLAGS_REG))]
3749   "reload_completed
3750    && (!TARGET_ZERO_EXTEND_WITH_AND
3751        || optimize_function_for_size_p (cfun))
3752    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3753   [(set (match_operand:HI 0 "register_operand" "")
3754         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3755
3756 ;; When source and destination does not overlap, clear destination
3757 ;; first and then do the movb
3758 (define_split
3759   [(set (match_operand:HI 0 "register_operand" "")
3760         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3761    (clobber (reg:CC FLAGS_REG))]
3762   "reload_completed
3763    && ANY_QI_REG_P (operands[0])
3764    && (TARGET_ZERO_EXTEND_WITH_AND
3765        && optimize_function_for_speed_p (cfun))
3766    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3767   [(set (match_dup 0) (const_int 0))
3768    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3769   "operands[2] = gen_lowpart (QImode, operands[0]);")
3770
3771 ;; Rest is handled by single and.
3772 (define_split
3773   [(set (match_operand:HI 0 "register_operand" "")
3774         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3775    (clobber (reg:CC FLAGS_REG))]
3776   "reload_completed
3777    && true_regnum (operands[0]) == true_regnum (operands[1])"
3778   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3779               (clobber (reg:CC FLAGS_REG))])]
3780   "")
3781
3782 (define_expand "zero_extendqisi2"
3783   [(parallel
3784     [(set (match_operand:SI 0 "register_operand" "")
3785        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3786      (clobber (reg:CC FLAGS_REG))])]
3787   ""
3788   "")
3789
3790 (define_insn "*zero_extendqisi2_and"
3791   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3792      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3793    (clobber (reg:CC FLAGS_REG))]
3794   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3795   "#"
3796   [(set_attr "type" "alu1")
3797    (set_attr "mode" "SI")])
3798
3799 (define_insn "*zero_extendqisi2_movzbw_and"
3800   [(set (match_operand:SI 0 "register_operand" "=r,r")
3801      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3802    (clobber (reg:CC FLAGS_REG))]
3803   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3804   "#"
3805   [(set_attr "type" "imovx,alu1")
3806    (set_attr "mode" "SI")])
3807
3808 (define_insn "*zero_extendqisi2_movzbw"
3809   [(set (match_operand:SI 0 "register_operand" "=r")
3810      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3811   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3812    && reload_completed"
3813   "movz{bl|x}\t{%1, %0|%0, %1}"
3814   [(set_attr "type" "imovx")
3815    (set_attr "mode" "SI")])
3816
3817 ;; For the movzbl case strip only the clobber
3818 (define_split
3819   [(set (match_operand:SI 0 "register_operand" "")
3820         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3821    (clobber (reg:CC FLAGS_REG))]
3822   "reload_completed
3823    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3824    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3825   [(set (match_dup 0)
3826         (zero_extend:SI (match_dup 1)))])
3827
3828 ;; When source and destination does not overlap, clear destination
3829 ;; first and then do the movb
3830 (define_split
3831   [(set (match_operand:SI 0 "register_operand" "")
3832         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3833    (clobber (reg:CC FLAGS_REG))]
3834   "reload_completed
3835    && ANY_QI_REG_P (operands[0])
3836    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3837    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3838    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3839   [(set (match_dup 0) (const_int 0))
3840    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3841   "operands[2] = gen_lowpart (QImode, operands[0]);")
3842
3843 ;; Rest is handled by single and.
3844 (define_split
3845   [(set (match_operand:SI 0 "register_operand" "")
3846         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3847    (clobber (reg:CC FLAGS_REG))]
3848   "reload_completed
3849    && true_regnum (operands[0]) == true_regnum (operands[1])"
3850   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3851               (clobber (reg:CC FLAGS_REG))])]
3852   "")
3853
3854 ;; %%% Kill me once multi-word ops are sane.
3855 (define_expand "zero_extendsidi2"
3856   [(set (match_operand:DI 0 "register_operand" "")
3857      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3858   ""
3859 {
3860   if (!TARGET_64BIT)
3861     {
3862       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3863       DONE;
3864     }
3865 })
3866
3867 (define_insn "zero_extendsidi2_32"
3868   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3869         (zero_extend:DI
3870          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3871    (clobber (reg:CC FLAGS_REG))]
3872   "!TARGET_64BIT"
3873   "@
3874    #
3875    #
3876    #
3877    movd\t{%1, %0|%0, %1}
3878    movd\t{%1, %0|%0, %1}
3879    %vmovd\t{%1, %0|%0, %1}
3880    %vmovd\t{%1, %0|%0, %1}"
3881   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3882    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3883    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3884
3885 (define_insn "zero_extendsidi2_rex64"
3886   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3887      (zero_extend:DI
3888        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3889   "TARGET_64BIT"
3890   "@
3891    mov\t{%k1, %k0|%k0, %k1}
3892    #
3893    movd\t{%1, %0|%0, %1}
3894    movd\t{%1, %0|%0, %1}
3895    %vmovd\t{%1, %0|%0, %1}
3896    %vmovd\t{%1, %0|%0, %1}"
3897   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3898    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3899    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3900
3901 (define_split
3902   [(set (match_operand:DI 0 "memory_operand" "")
3903      (zero_extend:DI (match_dup 0)))]
3904   "TARGET_64BIT"
3905   [(set (match_dup 4) (const_int 0))]
3906   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3907
3908 (define_split
3909   [(set (match_operand:DI 0 "register_operand" "")
3910         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3911    (clobber (reg:CC FLAGS_REG))]
3912   "!TARGET_64BIT && reload_completed
3913    && true_regnum (operands[0]) == true_regnum (operands[1])"
3914   [(set (match_dup 4) (const_int 0))]
3915   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3916
3917 (define_split
3918   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3919         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3920    (clobber (reg:CC FLAGS_REG))]
3921   "!TARGET_64BIT && reload_completed
3922    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3923   [(set (match_dup 3) (match_dup 1))
3924    (set (match_dup 4) (const_int 0))]
3925   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3926
3927 (define_insn "zero_extendhidi2"
3928   [(set (match_operand:DI 0 "register_operand" "=r")
3929      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3930   "TARGET_64BIT"
3931   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3932   [(set_attr "type" "imovx")
3933    (set_attr "mode" "DI")])
3934
3935 (define_insn "zero_extendqidi2"
3936   [(set (match_operand:DI 0 "register_operand" "=r")
3937      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3938   "TARGET_64BIT"
3939   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3940   [(set_attr "type" "imovx")
3941    (set_attr "mode" "DI")])
3942 \f
3943 ;; Sign extension instructions
3944
3945 (define_expand "extendsidi2"
3946   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3947                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3948               (clobber (reg:CC FLAGS_REG))
3949               (clobber (match_scratch:SI 2 ""))])]
3950   ""
3951 {
3952   if (TARGET_64BIT)
3953     {
3954       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3955       DONE;
3956     }
3957 })
3958
3959 (define_insn "*extendsidi2_1"
3960   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3961         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3962    (clobber (reg:CC FLAGS_REG))
3963    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3964   "!TARGET_64BIT"
3965   "#")
3966
3967 (define_insn "extendsidi2_rex64"
3968   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3969         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3970   "TARGET_64BIT"
3971   "@
3972    {cltq|cdqe}
3973    movs{lq|x}\t{%1,%0|%0, %1}"
3974   [(set_attr "type" "imovx")
3975    (set_attr "mode" "DI")
3976    (set_attr "prefix_0f" "0")
3977    (set_attr "modrm" "0,1")])
3978
3979 (define_insn "extendhidi2"
3980   [(set (match_operand:DI 0 "register_operand" "=r")
3981         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3982   "TARGET_64BIT"
3983   "movs{wq|x}\t{%1,%0|%0, %1}"
3984   [(set_attr "type" "imovx")
3985    (set_attr "mode" "DI")])
3986
3987 (define_insn "extendqidi2"
3988   [(set (match_operand:DI 0 "register_operand" "=r")
3989         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3990   "TARGET_64BIT"
3991   "movs{bq|x}\t{%1,%0|%0, %1}"
3992    [(set_attr "type" "imovx")
3993     (set_attr "mode" "DI")])
3994
3995 ;; Extend to memory case when source register does die.
3996 (define_split
3997   [(set (match_operand:DI 0 "memory_operand" "")
3998         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3999    (clobber (reg:CC FLAGS_REG))
4000    (clobber (match_operand:SI 2 "register_operand" ""))]
4001   "(reload_completed
4002     && dead_or_set_p (insn, operands[1])
4003     && !reg_mentioned_p (operands[1], operands[0]))"
4004   [(set (match_dup 3) (match_dup 1))
4005    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4006               (clobber (reg:CC FLAGS_REG))])
4007    (set (match_dup 4) (match_dup 1))]
4008   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4009
4010 ;; Extend to memory case when source register does not die.
4011 (define_split
4012   [(set (match_operand:DI 0 "memory_operand" "")
4013         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4014    (clobber (reg:CC FLAGS_REG))
4015    (clobber (match_operand:SI 2 "register_operand" ""))]
4016   "reload_completed"
4017   [(const_int 0)]
4018 {
4019   split_di (&operands[0], 1, &operands[3], &operands[4]);
4020
4021   emit_move_insn (operands[3], operands[1]);
4022
4023   /* Generate a cltd if possible and doing so it profitable.  */
4024   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4025       && true_regnum (operands[1]) == AX_REG
4026       && true_regnum (operands[2]) == DX_REG)
4027     {
4028       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4029     }
4030   else
4031     {
4032       emit_move_insn (operands[2], operands[1]);
4033       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4034     }
4035   emit_move_insn (operands[4], operands[2]);
4036   DONE;
4037 })
4038
4039 ;; Extend to register case.  Optimize case where source and destination
4040 ;; registers match and cases where we can use cltd.
4041 (define_split
4042   [(set (match_operand:DI 0 "register_operand" "")
4043         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4044    (clobber (reg:CC FLAGS_REG))
4045    (clobber (match_scratch:SI 2 ""))]
4046   "reload_completed"
4047   [(const_int 0)]
4048 {
4049   split_di (&operands[0], 1, &operands[3], &operands[4]);
4050
4051   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4052     emit_move_insn (operands[3], operands[1]);
4053
4054   /* Generate a cltd if possible and doing so it profitable.  */
4055   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4056       && true_regnum (operands[3]) == AX_REG)
4057     {
4058       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4059       DONE;
4060     }
4061
4062   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4063     emit_move_insn (operands[4], operands[1]);
4064
4065   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4066   DONE;
4067 })
4068
4069 (define_insn "extendhisi2"
4070   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4071         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4072   ""
4073 {
4074   switch (get_attr_prefix_0f (insn))
4075     {
4076     case 0:
4077       return "{cwtl|cwde}";
4078     default:
4079       return "movs{wl|x}\t{%1,%0|%0, %1}";
4080     }
4081 }
4082   [(set_attr "type" "imovx")
4083    (set_attr "mode" "SI")
4084    (set (attr "prefix_0f")
4085      ;; movsx is short decodable while cwtl is vector decoded.
4086      (if_then_else (and (eq_attr "cpu" "!k6")
4087                         (eq_attr "alternative" "0"))
4088         (const_string "0")
4089         (const_string "1")))
4090    (set (attr "modrm")
4091      (if_then_else (eq_attr "prefix_0f" "0")
4092         (const_string "0")
4093         (const_string "1")))])
4094
4095 (define_insn "*extendhisi2_zext"
4096   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4097         (zero_extend:DI
4098           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4099   "TARGET_64BIT"
4100 {
4101   switch (get_attr_prefix_0f (insn))
4102     {
4103     case 0:
4104       return "{cwtl|cwde}";
4105     default:
4106       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4107     }
4108 }
4109   [(set_attr "type" "imovx")
4110    (set_attr "mode" "SI")
4111    (set (attr "prefix_0f")
4112      ;; movsx is short decodable while cwtl is vector decoded.
4113      (if_then_else (and (eq_attr "cpu" "!k6")
4114                         (eq_attr "alternative" "0"))
4115         (const_string "0")
4116         (const_string "1")))
4117    (set (attr "modrm")
4118      (if_then_else (eq_attr "prefix_0f" "0")
4119         (const_string "0")
4120         (const_string "1")))])
4121
4122 (define_insn "extendqihi2"
4123   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4124         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4125   ""
4126 {
4127   switch (get_attr_prefix_0f (insn))
4128     {
4129     case 0:
4130       return "{cbtw|cbw}";
4131     default:
4132       return "movs{bw|x}\t{%1,%0|%0, %1}";
4133     }
4134 }
4135   [(set_attr "type" "imovx")
4136    (set_attr "mode" "HI")
4137    (set (attr "prefix_0f")
4138      ;; movsx is short decodable while cwtl is vector decoded.
4139      (if_then_else (and (eq_attr "cpu" "!k6")
4140                         (eq_attr "alternative" "0"))
4141         (const_string "0")
4142         (const_string "1")))
4143    (set (attr "modrm")
4144      (if_then_else (eq_attr "prefix_0f" "0")
4145         (const_string "0")
4146         (const_string "1")))])
4147
4148 (define_insn "extendqisi2"
4149   [(set (match_operand:SI 0 "register_operand" "=r")
4150         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4151   ""
4152   "movs{bl|x}\t{%1,%0|%0, %1}"
4153    [(set_attr "type" "imovx")
4154     (set_attr "mode" "SI")])
4155
4156 (define_insn "*extendqisi2_zext"
4157   [(set (match_operand:DI 0 "register_operand" "=r")
4158         (zero_extend:DI
4159           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4160   "TARGET_64BIT"
4161   "movs{bl|x}\t{%1,%k0|%k0, %1}"
4162    [(set_attr "type" "imovx")
4163     (set_attr "mode" "SI")])
4164 \f
4165 ;; Conversions between float and double.
4166
4167 ;; These are all no-ops in the model used for the 80387.  So just
4168 ;; emit moves.
4169
4170 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4171 (define_insn "*dummy_extendsfdf2"
4172   [(set (match_operand:DF 0 "push_operand" "=<")
4173         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4174   "0"
4175   "#")
4176
4177 (define_split
4178   [(set (match_operand:DF 0 "push_operand" "")
4179         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4180   ""
4181   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4182    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4183
4184 (define_insn "*dummy_extendsfxf2"
4185   [(set (match_operand:XF 0 "push_operand" "=<")
4186         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4187   "0"
4188   "#")
4189
4190 (define_split
4191   [(set (match_operand:XF 0 "push_operand" "")
4192         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4193   ""
4194   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4195    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4196   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4197
4198 (define_split
4199   [(set (match_operand:XF 0 "push_operand" "")
4200         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4201   ""
4202   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4203    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4204   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4205
4206 (define_expand "extendsfdf2"
4207   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4208         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4209   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4210 {
4211   /* ??? Needed for compress_float_constant since all fp constants
4212      are LEGITIMATE_CONSTANT_P.  */
4213   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4214     {
4215       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4216           && standard_80387_constant_p (operands[1]) > 0)
4217         {
4218           operands[1] = simplify_const_unary_operation
4219             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4220           emit_move_insn_1 (operands[0], operands[1]);
4221           DONE;
4222         }
4223       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4224     }
4225 })
4226
4227 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4228    cvtss2sd:
4229       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4230       cvtps2pd xmm2,xmm1
4231    We do the conversion post reload to avoid producing of 128bit spills
4232    that might lead to ICE on 32bit target.  The sequence unlikely combine
4233    anyway.  */
4234 (define_split
4235   [(set (match_operand:DF 0 "register_operand" "")
4236         (float_extend:DF
4237           (match_operand:SF 1 "nonimmediate_operand" "")))]
4238   "TARGET_USE_VECTOR_FP_CONVERTS
4239    && optimize_insn_for_speed_p ()
4240    && reload_completed && SSE_REG_P (operands[0])"
4241    [(set (match_dup 2)
4242          (float_extend:V2DF
4243            (vec_select:V2SF
4244              (match_dup 3)
4245              (parallel [(const_int 0) (const_int 1)]))))]
4246 {
4247   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4248   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4249   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4250      Try to avoid move when unpacking can be done in source.  */
4251   if (REG_P (operands[1]))
4252     {
4253       /* If it is unsafe to overwrite upper half of source, we need
4254          to move to destination and unpack there.  */
4255       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4256            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4257           && true_regnum (operands[0]) != true_regnum (operands[1]))
4258         {
4259           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4260           emit_move_insn (tmp, operands[1]);
4261         }
4262       else
4263         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4264       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4265     }
4266   else
4267     emit_insn (gen_vec_setv4sf_0 (operands[3],
4268                                   CONST0_RTX (V4SFmode), operands[1]));
4269 })
4270
4271 (define_insn "*extendsfdf2_mixed"
4272   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4273         (float_extend:DF
4274           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4275   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4276 {
4277   switch (which_alternative)
4278     {
4279     case 0:
4280     case 1:
4281       return output_387_reg_move (insn, operands);
4282
4283     case 2:
4284       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4285
4286     default:
4287       gcc_unreachable ();
4288     }
4289 }
4290   [(set_attr "type" "fmov,fmov,ssecvt")
4291    (set_attr "prefix" "orig,orig,maybe_vex")
4292    (set_attr "mode" "SF,XF,DF")])
4293
4294 (define_insn "*extendsfdf2_sse"
4295   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4296         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4297   "TARGET_SSE2 && TARGET_SSE_MATH"
4298   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4299   [(set_attr "type" "ssecvt")
4300    (set_attr "prefix" "maybe_vex")
4301    (set_attr "mode" "DF")])
4302
4303 (define_insn "*extendsfdf2_i387"
4304   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4305         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4306   "TARGET_80387"
4307   "* return output_387_reg_move (insn, operands);"
4308   [(set_attr "type" "fmov")
4309    (set_attr "mode" "SF,XF")])
4310
4311 (define_expand "extend<mode>xf2"
4312   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4313         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4314   "TARGET_80387"
4315 {
4316   /* ??? Needed for compress_float_constant since all fp constants
4317      are LEGITIMATE_CONSTANT_P.  */
4318   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4319     {
4320       if (standard_80387_constant_p (operands[1]) > 0)
4321         {
4322           operands[1] = simplify_const_unary_operation
4323             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4324           emit_move_insn_1 (operands[0], operands[1]);
4325           DONE;
4326         }
4327       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4328     }
4329 })
4330
4331 (define_insn "*extend<mode>xf2_i387"
4332   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4333         (float_extend:XF
4334           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4335   "TARGET_80387"
4336   "* return output_387_reg_move (insn, operands);"
4337   [(set_attr "type" "fmov")
4338    (set_attr "mode" "<MODE>,XF")])
4339
4340 ;; %%% This seems bad bad news.
4341 ;; This cannot output into an f-reg because there is no way to be sure
4342 ;; of truncating in that case.  Otherwise this is just like a simple move
4343 ;; insn.  So we pretend we can output to a reg in order to get better
4344 ;; register preferencing, but we really use a stack slot.
4345
4346 ;; Conversion from DFmode to SFmode.
4347
4348 (define_expand "truncdfsf2"
4349   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4350         (float_truncate:SF
4351           (match_operand:DF 1 "nonimmediate_operand" "")))]
4352   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4353 {
4354   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4355     ;
4356   else if (flag_unsafe_math_optimizations)
4357     ;
4358   else
4359     {
4360       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4361       rtx temp = assign_386_stack_local (SFmode, slot);
4362       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4363       DONE;
4364     }
4365 })
4366
4367 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4368    cvtsd2ss:
4369       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4370       cvtpd2ps xmm2,xmm1
4371    We do the conversion post reload to avoid producing of 128bit spills
4372    that might lead to ICE on 32bit target.  The sequence unlikely combine
4373    anyway.  */
4374 (define_split
4375   [(set (match_operand:SF 0 "register_operand" "")
4376         (float_truncate:SF
4377           (match_operand:DF 1 "nonimmediate_operand" "")))]
4378   "TARGET_USE_VECTOR_FP_CONVERTS
4379    && optimize_insn_for_speed_p ()
4380    && reload_completed && SSE_REG_P (operands[0])"
4381    [(set (match_dup 2)
4382          (vec_concat:V4SF
4383            (float_truncate:V2SF
4384              (match_dup 4))
4385            (match_dup 3)))]
4386 {
4387   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4388   operands[3] = CONST0_RTX (V2SFmode);
4389   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4390   /* Use movsd for loading from memory, unpcklpd for registers.
4391      Try to avoid move when unpacking can be done in source, or SSE3
4392      movddup is available.  */
4393   if (REG_P (operands[1]))
4394     {
4395       if (!TARGET_SSE3
4396           && true_regnum (operands[0]) != true_regnum (operands[1])
4397           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4398               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4399         {
4400           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4401           emit_move_insn (tmp, operands[1]);
4402           operands[1] = tmp;
4403         }
4404       else if (!TARGET_SSE3)
4405         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4406       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4407     }
4408   else
4409     emit_insn (gen_sse2_loadlpd (operands[4],
4410                                  CONST0_RTX (V2DFmode), operands[1]));
4411 })
4412
4413 (define_expand "truncdfsf2_with_temp"
4414   [(parallel [(set (match_operand:SF 0 "" "")
4415                    (float_truncate:SF (match_operand:DF 1 "" "")))
4416               (clobber (match_operand:SF 2 "" ""))])]
4417   "")
4418
4419 (define_insn "*truncdfsf_fast_mixed"
4420   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4421         (float_truncate:SF
4422           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4423   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4424 {
4425   switch (which_alternative)
4426     {
4427     case 0:
4428       return output_387_reg_move (insn, operands);
4429     case 1:
4430       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4431     default:
4432       gcc_unreachable ();
4433     }
4434 }
4435   [(set_attr "type" "fmov,ssecvt")
4436    (set_attr "prefix" "orig,maybe_vex")
4437    (set_attr "mode" "SF")])
4438
4439 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4440 ;; because nothing we do here is unsafe.
4441 (define_insn "*truncdfsf_fast_sse"
4442   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4443         (float_truncate:SF
4444           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4445   "TARGET_SSE2 && TARGET_SSE_MATH"
4446   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4447   [(set_attr "type" "ssecvt")
4448    (set_attr "prefix" "maybe_vex")
4449    (set_attr "mode" "SF")])
4450
4451 (define_insn "*truncdfsf_fast_i387"
4452   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4453         (float_truncate:SF
4454           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4455   "TARGET_80387 && flag_unsafe_math_optimizations"
4456   "* return output_387_reg_move (insn, operands);"
4457   [(set_attr "type" "fmov")
4458    (set_attr "mode" "SF")])
4459
4460 (define_insn "*truncdfsf_mixed"
4461   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4462         (float_truncate:SF
4463           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4464    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4465   "TARGET_MIX_SSE_I387"
4466 {
4467   switch (which_alternative)
4468     {
4469     case 0:
4470       return output_387_reg_move (insn, operands);
4471     case 1:
4472       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4473
4474     default:
4475       return "#";
4476     }
4477 }
4478   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4479    (set_attr "unit" "*,*,i387,i387,i387")
4480    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4481    (set_attr "mode" "SF")])
4482
4483 (define_insn "*truncdfsf_i387"
4484   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4485         (float_truncate:SF
4486           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4487    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4488   "TARGET_80387"
4489 {
4490   switch (which_alternative)
4491     {
4492     case 0:
4493       return output_387_reg_move (insn, operands);
4494
4495     default:
4496       return "#";
4497     }
4498 }
4499   [(set_attr "type" "fmov,multi,multi,multi")
4500    (set_attr "unit" "*,i387,i387,i387")
4501    (set_attr "mode" "SF")])
4502
4503 (define_insn "*truncdfsf2_i387_1"
4504   [(set (match_operand:SF 0 "memory_operand" "=m")
4505         (float_truncate:SF
4506           (match_operand:DF 1 "register_operand" "f")))]
4507   "TARGET_80387
4508    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4509    && !TARGET_MIX_SSE_I387"
4510   "* return output_387_reg_move (insn, operands);"
4511   [(set_attr "type" "fmov")
4512    (set_attr "mode" "SF")])
4513
4514 (define_split
4515   [(set (match_operand:SF 0 "register_operand" "")
4516         (float_truncate:SF
4517          (match_operand:DF 1 "fp_register_operand" "")))
4518    (clobber (match_operand 2 "" ""))]
4519   "reload_completed"
4520   [(set (match_dup 2) (match_dup 1))
4521    (set (match_dup 0) (match_dup 2))]
4522 {
4523   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4524 })
4525
4526 ;; Conversion from XFmode to {SF,DF}mode
4527
4528 (define_expand "truncxf<mode>2"
4529   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4530                    (float_truncate:MODEF
4531                      (match_operand:XF 1 "register_operand" "")))
4532               (clobber (match_dup 2))])]
4533   "TARGET_80387"
4534 {
4535   if (flag_unsafe_math_optimizations)
4536     {
4537       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4538       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4539       if (reg != operands[0])
4540         emit_move_insn (operands[0], reg);
4541       DONE;
4542     }
4543   else
4544     {
4545       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4546       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4547     }
4548 })
4549
4550 (define_insn "*truncxfsf2_mixed"
4551   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4552         (float_truncate:SF
4553           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4554    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4555   "TARGET_80387"
4556 {
4557   gcc_assert (!which_alternative);
4558   return output_387_reg_move (insn, operands);
4559 }
4560   [(set_attr "type" "fmov,multi,multi,multi")
4561    (set_attr "unit" "*,i387,i387,i387")
4562    (set_attr "mode" "SF")])
4563
4564 (define_insn "*truncxfdf2_mixed"
4565   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4566         (float_truncate:DF
4567           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4568    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4569   "TARGET_80387"
4570 {
4571   gcc_assert (!which_alternative);
4572   return output_387_reg_move (insn, operands);
4573 }
4574   [(set_attr "type" "fmov,multi,multi,multi")
4575    (set_attr "unit" "*,i387,i387,i387")
4576    (set_attr "mode" "DF")])
4577
4578 (define_insn "truncxf<mode>2_i387_noop"
4579   [(set (match_operand:MODEF 0 "register_operand" "=f")
4580         (float_truncate:MODEF
4581           (match_operand:XF 1 "register_operand" "f")))]
4582   "TARGET_80387 && flag_unsafe_math_optimizations"
4583   "* return output_387_reg_move (insn, operands);"
4584   [(set_attr "type" "fmov")
4585    (set_attr "mode" "<MODE>")])
4586
4587 (define_insn "*truncxf<mode>2_i387"
4588   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4589         (float_truncate:MODEF
4590           (match_operand:XF 1 "register_operand" "f")))]
4591   "TARGET_80387"
4592   "* return output_387_reg_move (insn, operands);"
4593   [(set_attr "type" "fmov")
4594    (set_attr "mode" "<MODE>")])
4595
4596 (define_split
4597   [(set (match_operand:MODEF 0 "register_operand" "")
4598         (float_truncate:MODEF
4599           (match_operand:XF 1 "register_operand" "")))
4600    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4601   "TARGET_80387 && reload_completed"
4602   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4603    (set (match_dup 0) (match_dup 2))]
4604   "")
4605
4606 (define_split
4607   [(set (match_operand:MODEF 0 "memory_operand" "")
4608         (float_truncate:MODEF
4609           (match_operand:XF 1 "register_operand" "")))
4610    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4611   "TARGET_80387"
4612   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4613   "")
4614 \f
4615 ;; Signed conversion to DImode.
4616
4617 (define_expand "fix_truncxfdi2"
4618   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4619                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4620               (clobber (reg:CC FLAGS_REG))])]
4621   "TARGET_80387"
4622 {
4623   if (TARGET_FISTTP)
4624    {
4625      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4626      DONE;
4627    }
4628 })
4629
4630 (define_expand "fix_trunc<mode>di2"
4631   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4632                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4633               (clobber (reg:CC FLAGS_REG))])]
4634   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4635 {
4636   if (TARGET_FISTTP
4637       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4638    {
4639      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4640      DONE;
4641    }
4642   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4643    {
4644      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4645      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4646      if (out != operands[0])
4647         emit_move_insn (operands[0], out);
4648      DONE;
4649    }
4650 })
4651
4652 ;; Signed conversion to SImode.
4653
4654 (define_expand "fix_truncxfsi2"
4655   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4656                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4657               (clobber (reg:CC FLAGS_REG))])]
4658   "TARGET_80387"
4659 {
4660   if (TARGET_FISTTP)
4661    {
4662      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4663      DONE;
4664    }
4665 })
4666
4667 (define_expand "fix_trunc<mode>si2"
4668   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4669                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4670               (clobber (reg:CC FLAGS_REG))])]
4671   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4672 {
4673   if (TARGET_FISTTP
4674       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4675    {
4676      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4677      DONE;
4678    }
4679   if (SSE_FLOAT_MODE_P (<MODE>mode))
4680    {
4681      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4682      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4683      if (out != operands[0])
4684         emit_move_insn (operands[0], out);
4685      DONE;
4686    }
4687 })
4688
4689 ;; Signed conversion to HImode.
4690
4691 (define_expand "fix_trunc<mode>hi2"
4692   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4693                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4694               (clobber (reg:CC FLAGS_REG))])]
4695   "TARGET_80387
4696    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4697 {
4698   if (TARGET_FISTTP)
4699    {
4700      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4701      DONE;
4702    }
4703 })
4704
4705 ;; Unsigned conversion to SImode.
4706
4707 (define_expand "fixuns_trunc<mode>si2"
4708   [(parallel
4709     [(set (match_operand:SI 0 "register_operand" "")
4710           (unsigned_fix:SI
4711             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4712      (use (match_dup 2))
4713      (clobber (match_scratch:<ssevecmode> 3 ""))
4714      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4715   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4716 {
4717   enum machine_mode mode = <MODE>mode;
4718   enum machine_mode vecmode = <ssevecmode>mode;
4719   REAL_VALUE_TYPE TWO31r;
4720   rtx two31;
4721
4722   if (optimize_insn_for_size_p ())
4723     FAIL;
4724
4725   real_ldexp (&TWO31r, &dconst1, 31);
4726   two31 = const_double_from_real_value (TWO31r, mode);
4727   two31 = ix86_build_const_vector (mode, true, two31);
4728   operands[2] = force_reg (vecmode, two31);
4729 })
4730
4731 (define_insn_and_split "*fixuns_trunc<mode>_1"
4732   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4733         (unsigned_fix:SI
4734           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4735    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4736    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4737    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4738   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4739    && optimize_function_for_speed_p (cfun)"
4740   "#"
4741   "&& reload_completed"
4742   [(const_int 0)]
4743 {
4744   ix86_split_convert_uns_si_sse (operands);
4745   DONE;
4746 })
4747
4748 ;; Unsigned conversion to HImode.
4749 ;; Without these patterns, we'll try the unsigned SI conversion which
4750 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4751
4752 (define_expand "fixuns_trunc<mode>hi2"
4753   [(set (match_dup 2)
4754         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4755    (set (match_operand:HI 0 "nonimmediate_operand" "")
4756         (subreg:HI (match_dup 2) 0))]
4757   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4758   "operands[2] = gen_reg_rtx (SImode);")
4759
4760 ;; When SSE is available, it is always faster to use it!
4761 (define_insn "fix_trunc<mode>di_sse"
4762   [(set (match_operand:DI 0 "register_operand" "=r,r")
4763         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4764   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4765    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4766   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4767   [(set_attr "type" "sseicvt")
4768    (set_attr "prefix" "maybe_vex")
4769    (set_attr "mode" "<MODE>")
4770    (set_attr "athlon_decode" "double,vector")
4771    (set_attr "amdfam10_decode" "double,double")])
4772
4773 (define_insn "fix_trunc<mode>si_sse"
4774   [(set (match_operand:SI 0 "register_operand" "=r,r")
4775         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4776   "SSE_FLOAT_MODE_P (<MODE>mode)
4777    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4778   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4779   [(set_attr "type" "sseicvt")
4780    (set_attr "prefix" "maybe_vex")
4781    (set_attr "mode" "<MODE>")
4782    (set_attr "athlon_decode" "double,vector")
4783    (set_attr "amdfam10_decode" "double,double")])
4784
4785 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4786 (define_peephole2
4787   [(set (match_operand:MODEF 0 "register_operand" "")
4788         (match_operand:MODEF 1 "memory_operand" ""))
4789    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4790         (fix:SSEMODEI24 (match_dup 0)))]
4791   "TARGET_SHORTEN_X87_SSE
4792    && peep2_reg_dead_p (2, operands[0])"
4793   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4794   "")
4795
4796 ;; Avoid vector decoded forms of the instruction.
4797 (define_peephole2
4798   [(match_scratch:DF 2 "Y2")
4799    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4800         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4801   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4802   [(set (match_dup 2) (match_dup 1))
4803    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4804   "")
4805
4806 (define_peephole2
4807   [(match_scratch:SF 2 "x")
4808    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4809         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4810   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4811   [(set (match_dup 2) (match_dup 1))
4812    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4813   "")
4814
4815 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4816   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4817         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4818   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4819    && TARGET_FISTTP
4820    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4821          && (TARGET_64BIT || <MODE>mode != DImode))
4822         && TARGET_SSE_MATH)
4823    && !(reload_completed || reload_in_progress)"
4824   "#"
4825   "&& 1"
4826   [(const_int 0)]
4827 {
4828   if (memory_operand (operands[0], VOIDmode))
4829     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4830   else
4831     {
4832       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4833       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4834                                                             operands[1],
4835                                                             operands[2]));
4836     }
4837   DONE;
4838 }
4839   [(set_attr "type" "fisttp")
4840    (set_attr "mode" "<MODE>")])
4841
4842 (define_insn "fix_trunc<mode>_i387_fisttp"
4843   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4844         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4845    (clobber (match_scratch:XF 2 "=&1f"))]
4846   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4847    && TARGET_FISTTP
4848    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4849          && (TARGET_64BIT || <MODE>mode != DImode))
4850         && TARGET_SSE_MATH)"
4851   "* return output_fix_trunc (insn, operands, 1);"
4852   [(set_attr "type" "fisttp")
4853    (set_attr "mode" "<MODE>")])
4854
4855 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4856   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4857         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4858    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4859    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4860   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4861    && TARGET_FISTTP
4862    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4863         && (TARGET_64BIT || <MODE>mode != DImode))
4864         && TARGET_SSE_MATH)"
4865   "#"
4866   [(set_attr "type" "fisttp")
4867    (set_attr "mode" "<MODE>")])
4868
4869 (define_split
4870   [(set (match_operand:X87MODEI 0 "register_operand" "")
4871         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4872    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4873    (clobber (match_scratch 3 ""))]
4874   "reload_completed"
4875   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4876               (clobber (match_dup 3))])
4877    (set (match_dup 0) (match_dup 2))]
4878   "")
4879
4880 (define_split
4881   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4882         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4883    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4884    (clobber (match_scratch 3 ""))]
4885   "reload_completed"
4886   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4887               (clobber (match_dup 3))])]
4888   "")
4889
4890 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4891 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4892 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4893 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4894 ;; function in i386.c.
4895 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4896   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4897         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4898    (clobber (reg:CC FLAGS_REG))]
4899   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4900    && !TARGET_FISTTP
4901    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4902          && (TARGET_64BIT || <MODE>mode != DImode))
4903    && !(reload_completed || reload_in_progress)"
4904   "#"
4905   "&& 1"
4906   [(const_int 0)]
4907 {
4908   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4909
4910   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4911   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4912   if (memory_operand (operands[0], VOIDmode))
4913     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4914                                          operands[2], operands[3]));
4915   else
4916     {
4917       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4918       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4919                                                      operands[2], operands[3],
4920                                                      operands[4]));
4921     }
4922   DONE;
4923 }
4924   [(set_attr "type" "fistp")
4925    (set_attr "i387_cw" "trunc")
4926    (set_attr "mode" "<MODE>")])
4927
4928 (define_insn "fix_truncdi_i387"
4929   [(set (match_operand:DI 0 "memory_operand" "=m")
4930         (fix:DI (match_operand 1 "register_operand" "f")))
4931    (use (match_operand:HI 2 "memory_operand" "m"))
4932    (use (match_operand:HI 3 "memory_operand" "m"))
4933    (clobber (match_scratch:XF 4 "=&1f"))]
4934   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4935    && !TARGET_FISTTP
4936    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4937   "* return output_fix_trunc (insn, operands, 0);"
4938   [(set_attr "type" "fistp")
4939    (set_attr "i387_cw" "trunc")
4940    (set_attr "mode" "DI")])
4941
4942 (define_insn "fix_truncdi_i387_with_temp"
4943   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4944         (fix:DI (match_operand 1 "register_operand" "f,f")))
4945    (use (match_operand:HI 2 "memory_operand" "m,m"))
4946    (use (match_operand:HI 3 "memory_operand" "m,m"))
4947    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4948    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4949   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4950    && !TARGET_FISTTP
4951    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4952   "#"
4953   [(set_attr "type" "fistp")
4954    (set_attr "i387_cw" "trunc")
4955    (set_attr "mode" "DI")])
4956
4957 (define_split
4958   [(set (match_operand:DI 0 "register_operand" "")
4959         (fix:DI (match_operand 1 "register_operand" "")))
4960    (use (match_operand:HI 2 "memory_operand" ""))
4961    (use (match_operand:HI 3 "memory_operand" ""))
4962    (clobber (match_operand:DI 4 "memory_operand" ""))
4963    (clobber (match_scratch 5 ""))]
4964   "reload_completed"
4965   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4966               (use (match_dup 2))
4967               (use (match_dup 3))
4968               (clobber (match_dup 5))])
4969    (set (match_dup 0) (match_dup 4))]
4970   "")
4971
4972 (define_split
4973   [(set (match_operand:DI 0 "memory_operand" "")
4974         (fix:DI (match_operand 1 "register_operand" "")))
4975    (use (match_operand:HI 2 "memory_operand" ""))
4976    (use (match_operand:HI 3 "memory_operand" ""))
4977    (clobber (match_operand:DI 4 "memory_operand" ""))
4978    (clobber (match_scratch 5 ""))]
4979   "reload_completed"
4980   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4981               (use (match_dup 2))
4982               (use (match_dup 3))
4983               (clobber (match_dup 5))])]
4984   "")
4985
4986 (define_insn "fix_trunc<mode>_i387"
4987   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4988         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4989    (use (match_operand:HI 2 "memory_operand" "m"))
4990    (use (match_operand:HI 3 "memory_operand" "m"))]
4991   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4992    && !TARGET_FISTTP
4993    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4994   "* return output_fix_trunc (insn, operands, 0);"
4995   [(set_attr "type" "fistp")
4996    (set_attr "i387_cw" "trunc")
4997    (set_attr "mode" "<MODE>")])
4998
4999 (define_insn "fix_trunc<mode>_i387_with_temp"
5000   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5001         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5002    (use (match_operand:HI 2 "memory_operand" "m,m"))
5003    (use (match_operand:HI 3 "memory_operand" "m,m"))
5004    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5005   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5006    && !TARGET_FISTTP
5007    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5008   "#"
5009   [(set_attr "type" "fistp")
5010    (set_attr "i387_cw" "trunc")
5011    (set_attr "mode" "<MODE>")])
5012
5013 (define_split
5014   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5015         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5016    (use (match_operand:HI 2 "memory_operand" ""))
5017    (use (match_operand:HI 3 "memory_operand" ""))
5018    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5019   "reload_completed"
5020   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5021               (use (match_dup 2))
5022               (use (match_dup 3))])
5023    (set (match_dup 0) (match_dup 4))]
5024   "")
5025
5026 (define_split
5027   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5028         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5029    (use (match_operand:HI 2 "memory_operand" ""))
5030    (use (match_operand:HI 3 "memory_operand" ""))
5031    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5032   "reload_completed"
5033   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5034               (use (match_dup 2))
5035               (use (match_dup 3))])]
5036   "")
5037
5038 (define_insn "x86_fnstcw_1"
5039   [(set (match_operand:HI 0 "memory_operand" "=m")
5040         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5041   "TARGET_80387"
5042   "fnstcw\t%0"
5043   [(set_attr "length" "2")
5044    (set_attr "mode" "HI")
5045    (set_attr "unit" "i387")])
5046
5047 (define_insn "x86_fldcw_1"
5048   [(set (reg:HI FPCR_REG)
5049         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5050   "TARGET_80387"
5051   "fldcw\t%0"
5052   [(set_attr "length" "2")
5053    (set_attr "mode" "HI")
5054    (set_attr "unit" "i387")
5055    (set_attr "athlon_decode" "vector")
5056    (set_attr "amdfam10_decode" "vector")])
5057 \f
5058 ;; Conversion between fixed point and floating point.
5059
5060 ;; Even though we only accept memory inputs, the backend _really_
5061 ;; wants to be able to do this between registers.
5062
5063 (define_expand "floathi<mode>2"
5064   [(set (match_operand:X87MODEF 0 "register_operand" "")
5065         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5066   "TARGET_80387
5067    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5068        || TARGET_MIX_SSE_I387)"
5069   "")
5070
5071 ;; Pre-reload splitter to add memory clobber to the pattern.
5072 (define_insn_and_split "*floathi<mode>2_1"
5073   [(set (match_operand:X87MODEF 0 "register_operand" "")
5074         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5075   "TARGET_80387
5076    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5077        || TARGET_MIX_SSE_I387)
5078    && !(reload_completed || reload_in_progress)"
5079   "#"
5080   "&& 1"
5081   [(parallel [(set (match_dup 0)
5082               (float:X87MODEF (match_dup 1)))
5083    (clobber (match_dup 2))])]
5084   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5085
5086 (define_insn "*floathi<mode>2_i387_with_temp"
5087   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5088         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5089   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5090   "TARGET_80387
5091    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5092        || TARGET_MIX_SSE_I387)"
5093   "#"
5094   [(set_attr "type" "fmov,multi")
5095    (set_attr "mode" "<MODE>")
5096    (set_attr "unit" "*,i387")
5097    (set_attr "fp_int_src" "true")])
5098
5099 (define_insn "*floathi<mode>2_i387"
5100   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5101         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5102   "TARGET_80387
5103    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5104        || TARGET_MIX_SSE_I387)"
5105   "fild%z1\t%1"
5106   [(set_attr "type" "fmov")
5107    (set_attr "mode" "<MODE>")
5108    (set_attr "fp_int_src" "true")])
5109
5110 (define_split
5111   [(set (match_operand:X87MODEF 0 "register_operand" "")
5112         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5113    (clobber (match_operand:HI 2 "memory_operand" ""))]
5114   "TARGET_80387
5115    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5116        || TARGET_MIX_SSE_I387)
5117    && reload_completed"
5118   [(set (match_dup 2) (match_dup 1))
5119    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5120   "")
5121
5122 (define_split
5123   [(set (match_operand:X87MODEF 0 "register_operand" "")
5124         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5125    (clobber (match_operand:HI 2 "memory_operand" ""))]
5126    "TARGET_80387
5127     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5128         || TARGET_MIX_SSE_I387)
5129     && reload_completed"
5130   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5131   "")
5132
5133 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5134   [(set (match_operand:X87MODEF 0 "register_operand" "")
5135         (float:X87MODEF
5136           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5137   "TARGET_80387
5138    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5139        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5140   "
5141 {
5142   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5143         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5144       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5145     {
5146       rtx reg = gen_reg_rtx (XFmode);
5147       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5148 /* Avoid references to nonexistent function in dead code in XFmode case.  */
5149 #define gen_truncxfxf2 gen_truncxfdf2
5150       emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5151 #undef gen_truncxfxf2
5152       DONE;
5153     }
5154 }")
5155
5156 ;; Pre-reload splitter to add memory clobber to the pattern.
5157 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5158   [(set (match_operand:X87MODEF 0 "register_operand" "")
5159         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5160   "((TARGET_80387
5161      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5162      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5163            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5164          || TARGET_MIX_SSE_I387))
5165     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5166         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5167         && ((<SSEMODEI24:MODE>mode == SImode
5168              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5169              && optimize_function_for_speed_p (cfun)
5170              && flag_trapping_math)
5171             || !(TARGET_INTER_UNIT_CONVERSIONS
5172                  || optimize_function_for_size_p (cfun)))))
5173    && !(reload_completed || reload_in_progress)"
5174   "#"
5175   "&& 1"
5176   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5177               (clobber (match_dup 2))])]
5178 {
5179   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5180
5181   /* Avoid store forwarding (partial memory) stall penalty
5182      by passing DImode value through XMM registers.  */
5183   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5184       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5185       && optimize_function_for_speed_p (cfun))
5186     {
5187       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5188                                                             operands[1],
5189                                                             operands[2]));
5190       DONE;
5191     }
5192 })
5193
5194 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5195   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5196         (float:MODEF
5197           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5198    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5199   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5200    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5201   "#"
5202   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5203    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5204    (set_attr "unit" "*,i387,*,*,*")
5205    (set_attr "athlon_decode" "*,*,double,direct,double")
5206    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5207    (set_attr "fp_int_src" "true")])
5208
5209 (define_insn "*floatsi<mode>2_vector_mixed"
5210   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5211         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5212   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5213    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5214   "@
5215    fild%z1\t%1
5216    #"
5217   [(set_attr "type" "fmov,sseicvt")
5218    (set_attr "mode" "<MODE>,<ssevecmode>")
5219    (set_attr "unit" "i387,*")
5220    (set_attr "athlon_decode" "*,direct")
5221    (set_attr "amdfam10_decode" "*,double")
5222    (set_attr "fp_int_src" "true")])
5223
5224 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5225   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5226         (float:MODEF
5227           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5228   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5229   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5230    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5231   "#"
5232   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5233    (set_attr "mode" "<MODEF:MODE>")
5234    (set_attr "unit" "*,i387,*,*")
5235    (set_attr "athlon_decode" "*,*,double,direct")
5236    (set_attr "amdfam10_decode" "*,*,vector,double")
5237    (set_attr "fp_int_src" "true")])
5238
5239 (define_split
5240   [(set (match_operand:MODEF 0 "register_operand" "")
5241         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5242    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5243   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5244    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5245    && TARGET_INTER_UNIT_CONVERSIONS
5246    && reload_completed
5247    && (SSE_REG_P (operands[0])
5248        || (GET_CODE (operands[0]) == SUBREG
5249            && SSE_REG_P (operands[0])))"
5250   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5251   "")
5252
5253 (define_split
5254   [(set (match_operand:MODEF 0 "register_operand" "")
5255         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5256    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5257   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5258    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5259    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5260    && reload_completed
5261    && (SSE_REG_P (operands[0])
5262        || (GET_CODE (operands[0]) == SUBREG
5263            && SSE_REG_P (operands[0])))"
5264   [(set (match_dup 2) (match_dup 1))
5265    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5266   "")
5267
5268 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5269   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5270         (float:MODEF
5271           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5272   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5273    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5274    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5275   "@
5276    fild%z1\t%1
5277    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5278    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5279   [(set_attr "type" "fmov,sseicvt,sseicvt")
5280    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5281    (set_attr "mode" "<MODEF:MODE>")
5282    (set_attr "unit" "i387,*,*")
5283    (set_attr "athlon_decode" "*,double,direct")
5284    (set_attr "amdfam10_decode" "*,vector,double")
5285    (set_attr "fp_int_src" "true")])
5286
5287 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5288   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5289         (float:MODEF
5290           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5291   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5292    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5293    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5294   "@
5295    fild%z1\t%1
5296    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5297   [(set_attr "type" "fmov,sseicvt")
5298    (set_attr "prefix" "orig,maybe_vex")
5299    (set_attr "mode" "<MODEF:MODE>")
5300    (set_attr "athlon_decode" "*,direct")
5301    (set_attr "amdfam10_decode" "*,double")
5302    (set_attr "fp_int_src" "true")])
5303
5304 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5305   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5306         (float:MODEF
5307           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5308    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5309   "TARGET_SSE2 && TARGET_SSE_MATH
5310    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5311   "#"
5312   [(set_attr "type" "sseicvt")
5313    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5314    (set_attr "athlon_decode" "double,direct,double")
5315    (set_attr "amdfam10_decode" "vector,double,double")
5316    (set_attr "fp_int_src" "true")])
5317
5318 (define_insn "*floatsi<mode>2_vector_sse"
5319   [(set (match_operand:MODEF 0 "register_operand" "=x")
5320         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5321   "TARGET_SSE2 && TARGET_SSE_MATH
5322    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5323   "#"
5324   [(set_attr "type" "sseicvt")
5325    (set_attr "mode" "<MODE>")
5326    (set_attr "athlon_decode" "direct")
5327    (set_attr "amdfam10_decode" "double")
5328    (set_attr "fp_int_src" "true")])
5329
5330 (define_split
5331   [(set (match_operand:MODEF 0 "register_operand" "")
5332         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5333    (clobber (match_operand:SI 2 "memory_operand" ""))]
5334   "TARGET_SSE2 && TARGET_SSE_MATH
5335    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5336    && reload_completed
5337    && (SSE_REG_P (operands[0])
5338        || (GET_CODE (operands[0]) == SUBREG
5339            && SSE_REG_P (operands[0])))"
5340   [(const_int 0)]
5341 {
5342   rtx op1 = operands[1];
5343
5344   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5345                                      <MODE>mode, 0);
5346   if (GET_CODE (op1) == SUBREG)
5347     op1 = SUBREG_REG (op1);
5348
5349   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5350     {
5351       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5352       emit_insn (gen_sse2_loadld (operands[4],
5353                                   CONST0_RTX (V4SImode), operands[1]));
5354     }
5355   /* We can ignore possible trapping value in the
5356      high part of SSE register for non-trapping math. */
5357   else if (SSE_REG_P (op1) && !flag_trapping_math)
5358     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5359   else
5360     {
5361       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5362       emit_move_insn (operands[2], operands[1]);
5363       emit_insn (gen_sse2_loadld (operands[4],
5364                                   CONST0_RTX (V4SImode), operands[2]));
5365     }
5366   emit_insn
5367     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5368   DONE;
5369 })
5370
5371 (define_split
5372   [(set (match_operand:MODEF 0 "register_operand" "")
5373         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5374    (clobber (match_operand:SI 2 "memory_operand" ""))]
5375   "TARGET_SSE2 && TARGET_SSE_MATH
5376    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5377    && reload_completed
5378    && (SSE_REG_P (operands[0])
5379        || (GET_CODE (operands[0]) == SUBREG
5380            && SSE_REG_P (operands[0])))"
5381   [(const_int 0)]
5382 {
5383   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5384                                      <MODE>mode, 0);
5385   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5386
5387   emit_insn (gen_sse2_loadld (operands[4],
5388                               CONST0_RTX (V4SImode), operands[1]));
5389   emit_insn
5390     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5391   DONE;
5392 })
5393
5394 (define_split
5395   [(set (match_operand:MODEF 0 "register_operand" "")
5396         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5397   "TARGET_SSE2 && TARGET_SSE_MATH
5398    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5399    && reload_completed
5400    && (SSE_REG_P (operands[0])
5401        || (GET_CODE (operands[0]) == SUBREG
5402            && SSE_REG_P (operands[0])))"
5403   [(const_int 0)]
5404 {
5405   rtx op1 = operands[1];
5406
5407   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5408                                      <MODE>mode, 0);
5409   if (GET_CODE (op1) == SUBREG)
5410     op1 = SUBREG_REG (op1);
5411
5412   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5413     {
5414       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5415       emit_insn (gen_sse2_loadld (operands[4],
5416                                   CONST0_RTX (V4SImode), operands[1]));
5417     }
5418   /* We can ignore possible trapping value in the
5419      high part of SSE register for non-trapping math. */
5420   else if (SSE_REG_P (op1) && !flag_trapping_math)
5421     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5422   else
5423     gcc_unreachable ();
5424   emit_insn
5425     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5426   DONE;
5427 })
5428
5429 (define_split
5430   [(set (match_operand:MODEF 0 "register_operand" "")
5431         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5432   "TARGET_SSE2 && TARGET_SSE_MATH
5433    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5434    && reload_completed
5435    && (SSE_REG_P (operands[0])
5436        || (GET_CODE (operands[0]) == SUBREG
5437            && SSE_REG_P (operands[0])))"
5438   [(const_int 0)]
5439 {
5440   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5441                                      <MODE>mode, 0);
5442   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5443
5444   emit_insn (gen_sse2_loadld (operands[4],
5445                               CONST0_RTX (V4SImode), operands[1]));
5446   emit_insn
5447     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5448   DONE;
5449 })
5450
5451 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5452   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5453         (float:MODEF
5454           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5455   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5456   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5457    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5458   "#"
5459   [(set_attr "type" "sseicvt")
5460    (set_attr "mode" "<MODEF:MODE>")
5461    (set_attr "athlon_decode" "double,direct")
5462    (set_attr "amdfam10_decode" "vector,double")
5463    (set_attr "fp_int_src" "true")])
5464
5465 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5466   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5467         (float:MODEF
5468           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5469   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5470    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5471    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5472   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5473   [(set_attr "type" "sseicvt")
5474    (set_attr "prefix" "maybe_vex")
5475    (set_attr "mode" "<MODEF:MODE>")
5476    (set_attr "athlon_decode" "double,direct")
5477    (set_attr "amdfam10_decode" "vector,double")
5478    (set_attr "fp_int_src" "true")])
5479
5480 (define_split
5481   [(set (match_operand:MODEF 0 "register_operand" "")
5482         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5483    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5484   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5485    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5486    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5487    && reload_completed
5488    && (SSE_REG_P (operands[0])
5489        || (GET_CODE (operands[0]) == SUBREG
5490            && SSE_REG_P (operands[0])))"
5491   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5492   "")
5493
5494 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5495   [(set (match_operand:MODEF 0 "register_operand" "=x")
5496         (float:MODEF
5497           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5498   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5499    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5500    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5501   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5502   [(set_attr "type" "sseicvt")
5503    (set_attr "prefix" "maybe_vex")
5504    (set_attr "mode" "<MODEF:MODE>")
5505    (set_attr "athlon_decode" "direct")
5506    (set_attr "amdfam10_decode" "double")
5507    (set_attr "fp_int_src" "true")])
5508
5509 (define_split
5510   [(set (match_operand:MODEF 0 "register_operand" "")
5511         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5512    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5513   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5514    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5515    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5516    && reload_completed
5517    && (SSE_REG_P (operands[0])
5518        || (GET_CODE (operands[0]) == SUBREG
5519            && SSE_REG_P (operands[0])))"
5520   [(set (match_dup 2) (match_dup 1))
5521    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5522   "")
5523
5524 (define_split
5525   [(set (match_operand:MODEF 0 "register_operand" "")
5526         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5527    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5528   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5529    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5530    && reload_completed
5531    && (SSE_REG_P (operands[0])
5532        || (GET_CODE (operands[0]) == SUBREG
5533            && SSE_REG_P (operands[0])))"
5534   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5535   "")
5536
5537 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5538   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5539         (float:X87MODEF
5540           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5541   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5542   "TARGET_80387
5543    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5544   "@
5545    fild%z1\t%1
5546    #"
5547   [(set_attr "type" "fmov,multi")
5548    (set_attr "mode" "<X87MODEF:MODE>")
5549    (set_attr "unit" "*,i387")
5550    (set_attr "fp_int_src" "true")])
5551
5552 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5553   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5554         (float:X87MODEF
5555           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5556   "TARGET_80387
5557    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
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    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5569    && reload_completed
5570    && FP_REG_P (operands[0])"
5571   [(set (match_dup 2) (match_dup 1))
5572    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5573   "")
5574
5575 (define_split
5576   [(set (match_operand:X87MODEF 0 "register_operand" "")
5577         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5578    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5579   "TARGET_80387
5580    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5581    && reload_completed
5582    && FP_REG_P (operands[0])"
5583   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5584   "")
5585
5586 ;; Avoid store forwarding (partial memory) stall penalty
5587 ;; by passing DImode value through XMM registers.  */
5588
5589 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5590   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5591         (float:X87MODEF
5592           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5593    (clobber (match_scratch:V4SI 3 "=X,x"))
5594    (clobber (match_scratch:V4SI 4 "=X,x"))
5595    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5596   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5597    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5598    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5599   "#"
5600   [(set_attr "type" "multi")
5601    (set_attr "mode" "<X87MODEF:MODE>")
5602    (set_attr "unit" "i387")
5603    (set_attr "fp_int_src" "true")])
5604
5605 (define_split
5606   [(set (match_operand:X87MODEF 0 "register_operand" "")
5607         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5608    (clobber (match_scratch:V4SI 3 ""))
5609    (clobber (match_scratch:V4SI 4 ""))
5610    (clobber (match_operand:DI 2 "memory_operand" ""))]
5611   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5612    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5613    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5614    && reload_completed
5615    && FP_REG_P (operands[0])"
5616   [(set (match_dup 2) (match_dup 3))
5617    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5618 {
5619   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5620      Assemble the 64-bit DImode value in an xmm register.  */
5621   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5622                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5623   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5624                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5625   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5626
5627   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5628 })
5629
5630 (define_split
5631   [(set (match_operand:X87MODEF 0 "register_operand" "")
5632         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5633    (clobber (match_scratch:V4SI 3 ""))
5634    (clobber (match_scratch:V4SI 4 ""))
5635    (clobber (match_operand:DI 2 "memory_operand" ""))]
5636   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5637    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5638    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5639    && reload_completed
5640    && FP_REG_P (operands[0])"
5641   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5642   "")
5643
5644 ;; Avoid store forwarding (partial memory) stall penalty by extending
5645 ;; SImode value to DImode through XMM register instead of pushing two
5646 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5647 ;; targets benefit from this optimization. Also note that fild
5648 ;; loads from memory only.
5649
5650 (define_insn "*floatunssi<mode>2_1"
5651   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5652         (unsigned_float:X87MODEF
5653           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5654    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5655    (clobber (match_scratch:SI 3 "=X,x"))]
5656   "!TARGET_64BIT
5657    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, SImode)
5658    && TARGET_SSE"
5659   "#"
5660   [(set_attr "type" "multi")
5661    (set_attr "mode" "<MODE>")])
5662
5663 (define_split
5664   [(set (match_operand:X87MODEF 0 "register_operand" "")
5665         (unsigned_float:X87MODEF
5666           (match_operand:SI 1 "register_operand" "")))
5667    (clobber (match_operand:DI 2 "memory_operand" ""))
5668    (clobber (match_scratch:SI 3 ""))]
5669   "!TARGET_64BIT
5670    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, SImode)
5671    && TARGET_SSE
5672    && reload_completed"
5673   [(set (match_dup 2) (match_dup 1))
5674    (set (match_dup 0)
5675         (float:X87MODEF (match_dup 2)))]
5676   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5677
5678 (define_split
5679   [(set (match_operand:X87MODEF 0 "register_operand" "")
5680         (unsigned_float:X87MODEF
5681           (match_operand:SI 1 "memory_operand" "")))
5682    (clobber (match_operand:DI 2 "memory_operand" ""))
5683    (clobber (match_scratch:SI 3 ""))]
5684   "!TARGET_64BIT
5685    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, SImode)
5686    && TARGET_SSE
5687    && reload_completed"
5688   [(set (match_dup 2) (match_dup 3))
5689    (set (match_dup 0)
5690         (float:X87MODEF (match_dup 2)))]
5691 {
5692   emit_move_insn (operands[3], operands[1]);
5693   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5694 })
5695
5696 (define_expand "floatunssi<mode>2"
5697   [(parallel
5698      [(set (match_operand:X87MODEF 0 "register_operand" "")
5699            (unsigned_float:X87MODEF
5700              (match_operand:SI 1 "nonimmediate_operand" "")))
5701       (clobber (match_dup 2))
5702       (clobber (match_scratch:SI 3 ""))])]
5703   "!TARGET_64BIT
5704    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, SImode)
5705         && TARGET_SSE)
5706        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5707 {
5708   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5709     {
5710       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5711       DONE;
5712     }
5713   else
5714     {
5715       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5716       operands[2] = assign_386_stack_local (DImode, slot);
5717     }
5718 })
5719
5720 (define_expand "floatunsdisf2"
5721   [(use (match_operand:SF 0 "register_operand" ""))
5722    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5723   "TARGET_64BIT && TARGET_SSE_MATH"
5724   "x86_emit_floatuns (operands); DONE;")
5725
5726 (define_expand "floatunsdidf2"
5727   [(use (match_operand:DF 0 "register_operand" ""))
5728    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5729   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5730    && TARGET_SSE2 && TARGET_SSE_MATH"
5731 {
5732   if (TARGET_64BIT)
5733     x86_emit_floatuns (operands);
5734   else
5735     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5736   DONE;
5737 })
5738 \f
5739 ;; Add instructions
5740
5741 ;; %%% splits for addditi3
5742
5743 (define_expand "addti3"
5744   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5745         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5746                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5747   "TARGET_64BIT"
5748   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5749
5750 (define_insn "*addti3_1"
5751   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5752         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5753                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5754    (clobber (reg:CC FLAGS_REG))]
5755   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5756   "#")
5757
5758 (define_split
5759   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5760         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5761                  (match_operand:TI 2 "x86_64_general_operand" "")))
5762    (clobber (reg:CC FLAGS_REG))]
5763   "TARGET_64BIT && reload_completed"
5764   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5765                                           UNSPEC_ADD_CARRY))
5766               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5767    (parallel [(set (match_dup 3)
5768                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5769                                      (match_dup 4))
5770                             (match_dup 5)))
5771               (clobber (reg:CC FLAGS_REG))])]
5772   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5773
5774 ;; %%% splits for addsidi3
5775 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5776 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5777 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5778
5779 (define_expand "adddi3"
5780   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5781         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5782                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5783   ""
5784   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5785
5786 (define_insn "*adddi3_1"
5787   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5788         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5789                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5790    (clobber (reg:CC FLAGS_REG))]
5791   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5792   "#")
5793
5794 (define_split
5795   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5796         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5797                  (match_operand:DI 2 "general_operand" "")))
5798    (clobber (reg:CC FLAGS_REG))]
5799   "!TARGET_64BIT && reload_completed"
5800   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5801                                           UNSPEC_ADD_CARRY))
5802               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5803    (parallel [(set (match_dup 3)
5804                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5805                                      (match_dup 4))
5806                             (match_dup 5)))
5807               (clobber (reg:CC FLAGS_REG))])]
5808   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5809
5810 (define_insn "adddi3_carry_rex64"
5811   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5812           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5813                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5814                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5815    (clobber (reg:CC FLAGS_REG))]
5816   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5817   "adc{q}\t{%2, %0|%0, %2}"
5818   [(set_attr "type" "alu")
5819    (set_attr "pent_pair" "pu")
5820    (set_attr "mode" "DI")])
5821
5822 (define_insn "*adddi3_cc_rex64"
5823   [(set (reg:CC FLAGS_REG)
5824         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5825                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5826                    UNSPEC_ADD_CARRY))
5827    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5828         (plus:DI (match_dup 1) (match_dup 2)))]
5829   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5830   "add{q}\t{%2, %0|%0, %2}"
5831   [(set_attr "type" "alu")
5832    (set_attr "mode" "DI")])
5833
5834 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5835   [(set (reg:CCC FLAGS_REG)
5836         (compare:CCC
5837             (plusminus:SWI
5838                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5839                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5840             (match_dup 1)))
5841    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5842         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5843   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5844   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5845   [(set_attr "type" "alu")
5846    (set_attr "mode" "<MODE>")])
5847
5848 (define_insn "*add<mode>3_cconly_overflow"
5849   [(set (reg:CCC FLAGS_REG)
5850         (compare:CCC
5851                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5852                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5853                 (match_dup 1)))
5854    (clobber (match_scratch:SWI 0 "=<r>"))]
5855   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5856   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5857   [(set_attr "type" "alu")
5858    (set_attr "mode" "<MODE>")])
5859
5860 (define_insn "*sub<mode>3_cconly_overflow"
5861   [(set (reg:CCC FLAGS_REG)
5862         (compare:CCC
5863              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5864                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5865              (match_dup 0)))]
5866   ""
5867   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5868   [(set_attr "type" "icmp")
5869    (set_attr "mode" "<MODE>")])
5870
5871 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5872   [(set (reg:CCC FLAGS_REG)
5873         (compare:CCC
5874             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5875                           (match_operand:SI 2 "general_operand" "g"))
5876             (match_dup 1)))
5877    (set (match_operand:DI 0 "register_operand" "=r")
5878         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5879   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5880   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5881   [(set_attr "type" "alu")
5882    (set_attr "mode" "SI")])
5883
5884 (define_insn "addqi3_carry"
5885   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5886           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5887                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5888                    (match_operand:QI 2 "general_operand" "qn,qm")))
5889    (clobber (reg:CC FLAGS_REG))]
5890   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5891   "adc{b}\t{%2, %0|%0, %2}"
5892   [(set_attr "type" "alu")
5893    (set_attr "pent_pair" "pu")
5894    (set_attr "mode" "QI")])
5895
5896 (define_insn "addhi3_carry"
5897   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5898           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5899                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5900                    (match_operand:HI 2 "general_operand" "rn,rm")))
5901    (clobber (reg:CC FLAGS_REG))]
5902   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5903   "adc{w}\t{%2, %0|%0, %2}"
5904   [(set_attr "type" "alu")
5905    (set_attr "pent_pair" "pu")
5906    (set_attr "mode" "HI")])
5907
5908 (define_insn "addsi3_carry"
5909   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5910           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5911                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5912                    (match_operand:SI 2 "general_operand" "ri,rm")))
5913    (clobber (reg:CC FLAGS_REG))]
5914   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5915   "adc{l}\t{%2, %0|%0, %2}"
5916   [(set_attr "type" "alu")
5917    (set_attr "pent_pair" "pu")
5918    (set_attr "mode" "SI")])
5919
5920 (define_insn "*addsi3_carry_zext"
5921   [(set (match_operand:DI 0 "register_operand" "=r")
5922           (zero_extend:DI
5923             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5924                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5925                      (match_operand:SI 2 "general_operand" "g"))))
5926    (clobber (reg:CC FLAGS_REG))]
5927   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5928   "adc{l}\t{%2, %k0|%k0, %2}"
5929   [(set_attr "type" "alu")
5930    (set_attr "pent_pair" "pu")
5931    (set_attr "mode" "SI")])
5932
5933 (define_insn "*addsi3_cc"
5934   [(set (reg:CC FLAGS_REG)
5935         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5936                     (match_operand:SI 2 "general_operand" "ri,rm")]
5937                    UNSPEC_ADD_CARRY))
5938    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5939         (plus:SI (match_dup 1) (match_dup 2)))]
5940   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5941   "add{l}\t{%2, %0|%0, %2}"
5942   [(set_attr "type" "alu")
5943    (set_attr "mode" "SI")])
5944
5945 (define_insn "addqi3_cc"
5946   [(set (reg:CC FLAGS_REG)
5947         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5948                     (match_operand:QI 2 "general_operand" "qn,qm")]
5949                    UNSPEC_ADD_CARRY))
5950    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5951         (plus:QI (match_dup 1) (match_dup 2)))]
5952   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5953   "add{b}\t{%2, %0|%0, %2}"
5954   [(set_attr "type" "alu")
5955    (set_attr "mode" "QI")])
5956
5957 (define_expand "addsi3"
5958   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5959         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5960                  (match_operand:SI 2 "general_operand" "")))]
5961   ""
5962   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5963
5964 (define_insn "*lea_1"
5965   [(set (match_operand:SI 0 "register_operand" "=r")
5966         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5967   "!TARGET_64BIT"
5968   "lea{l}\t{%a1, %0|%0, %a1}"
5969   [(set_attr "type" "lea")
5970    (set_attr "mode" "SI")])
5971
5972 (define_insn "*lea_1_rex64"
5973   [(set (match_operand:SI 0 "register_operand" "=r")
5974         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5975   "TARGET_64BIT"
5976   "lea{l}\t{%a1, %0|%0, %a1}"
5977   [(set_attr "type" "lea")
5978    (set_attr "mode" "SI")])
5979
5980 (define_insn "*lea_1_zext"
5981   [(set (match_operand:DI 0 "register_operand" "=r")
5982         (zero_extend:DI
5983          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5984   "TARGET_64BIT"
5985   "lea{l}\t{%a1, %k0|%k0, %a1}"
5986   [(set_attr "type" "lea")
5987    (set_attr "mode" "SI")])
5988
5989 (define_insn "*lea_2_rex64"
5990   [(set (match_operand:DI 0 "register_operand" "=r")
5991         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5992   "TARGET_64BIT"
5993   "lea{q}\t{%a1, %0|%0, %a1}"
5994   [(set_attr "type" "lea")
5995    (set_attr "mode" "DI")])
5996
5997 ;; The lea patterns for non-Pmodes needs to be matched by several
5998 ;; insns converted to real lea by splitters.
5999
6000 (define_insn_and_split "*lea_general_1"
6001   [(set (match_operand 0 "register_operand" "=r")
6002         (plus (plus (match_operand 1 "index_register_operand" "l")
6003                     (match_operand 2 "register_operand" "r"))
6004               (match_operand 3 "immediate_operand" "i")))]
6005   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6006     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6007    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6008    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6009    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6010    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6011        || GET_MODE (operands[3]) == VOIDmode)"
6012   "#"
6013   "&& reload_completed"
6014   [(const_int 0)]
6015 {
6016   rtx pat;
6017   operands[0] = gen_lowpart (SImode, operands[0]);
6018   operands[1] = gen_lowpart (Pmode, operands[1]);
6019   operands[2] = gen_lowpart (Pmode, operands[2]);
6020   operands[3] = gen_lowpart (Pmode, operands[3]);
6021   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6022                       operands[3]);
6023   if (Pmode != SImode)
6024     pat = gen_rtx_SUBREG (SImode, pat, 0);
6025   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6026   DONE;
6027 }
6028   [(set_attr "type" "lea")
6029    (set_attr "mode" "SI")])
6030
6031 (define_insn_and_split "*lea_general_1_zext"
6032   [(set (match_operand:DI 0 "register_operand" "=r")
6033         (zero_extend:DI
6034           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6035                             (match_operand:SI 2 "register_operand" "r"))
6036                    (match_operand:SI 3 "immediate_operand" "i"))))]
6037   "TARGET_64BIT"
6038   "#"
6039   "&& reload_completed"
6040   [(set (match_dup 0)
6041         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6042                                                      (match_dup 2))
6043                                             (match_dup 3)) 0)))]
6044 {
6045   operands[1] = gen_lowpart (Pmode, operands[1]);
6046   operands[2] = gen_lowpart (Pmode, operands[2]);
6047   operands[3] = gen_lowpart (Pmode, operands[3]);
6048 }
6049   [(set_attr "type" "lea")
6050    (set_attr "mode" "SI")])
6051
6052 (define_insn_and_split "*lea_general_2"
6053   [(set (match_operand 0 "register_operand" "=r")
6054         (plus (mult (match_operand 1 "index_register_operand" "l")
6055                     (match_operand 2 "const248_operand" "i"))
6056               (match_operand 3 "nonmemory_operand" "ri")))]
6057   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6058     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6059    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6060    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6061    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6062        || GET_MODE (operands[3]) == VOIDmode)"
6063   "#"
6064   "&& reload_completed"
6065   [(const_int 0)]
6066 {
6067   rtx pat;
6068   operands[0] = gen_lowpart (SImode, operands[0]);
6069   operands[1] = gen_lowpart (Pmode, operands[1]);
6070   operands[3] = gen_lowpart (Pmode, operands[3]);
6071   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6072                       operands[3]);
6073   if (Pmode != SImode)
6074     pat = gen_rtx_SUBREG (SImode, pat, 0);
6075   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6076   DONE;
6077 }
6078   [(set_attr "type" "lea")
6079    (set_attr "mode" "SI")])
6080
6081 (define_insn_and_split "*lea_general_2_zext"
6082   [(set (match_operand:DI 0 "register_operand" "=r")
6083         (zero_extend:DI
6084           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6085                             (match_operand:SI 2 "const248_operand" "n"))
6086                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6087   "TARGET_64BIT"
6088   "#"
6089   "&& reload_completed"
6090   [(set (match_dup 0)
6091         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6092                                                      (match_dup 2))
6093                                             (match_dup 3)) 0)))]
6094 {
6095   operands[1] = gen_lowpart (Pmode, operands[1]);
6096   operands[3] = gen_lowpart (Pmode, operands[3]);
6097 }
6098   [(set_attr "type" "lea")
6099    (set_attr "mode" "SI")])
6100
6101 (define_insn_and_split "*lea_general_3"
6102   [(set (match_operand 0 "register_operand" "=r")
6103         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6104                           (match_operand 2 "const248_operand" "i"))
6105                     (match_operand 3 "register_operand" "r"))
6106               (match_operand 4 "immediate_operand" "i")))]
6107   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6108     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6109    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6110    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6111    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6112   "#"
6113   "&& reload_completed"
6114   [(const_int 0)]
6115 {
6116   rtx pat;
6117   operands[0] = gen_lowpart (SImode, operands[0]);
6118   operands[1] = gen_lowpart (Pmode, operands[1]);
6119   operands[3] = gen_lowpart (Pmode, operands[3]);
6120   operands[4] = gen_lowpart (Pmode, operands[4]);
6121   pat = gen_rtx_PLUS (Pmode,
6122                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6123                                                          operands[2]),
6124                                     operands[3]),
6125                       operands[4]);
6126   if (Pmode != SImode)
6127     pat = gen_rtx_SUBREG (SImode, pat, 0);
6128   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6129   DONE;
6130 }
6131   [(set_attr "type" "lea")
6132    (set_attr "mode" "SI")])
6133
6134 (define_insn_and_split "*lea_general_3_zext"
6135   [(set (match_operand:DI 0 "register_operand" "=r")
6136         (zero_extend:DI
6137           (plus:SI (plus:SI (mult:SI
6138                               (match_operand:SI 1 "index_register_operand" "l")
6139                               (match_operand:SI 2 "const248_operand" "n"))
6140                             (match_operand:SI 3 "register_operand" "r"))
6141                    (match_operand:SI 4 "immediate_operand" "i"))))]
6142   "TARGET_64BIT"
6143   "#"
6144   "&& reload_completed"
6145   [(set (match_dup 0)
6146         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6147                                                               (match_dup 2))
6148                                                      (match_dup 3))
6149                                             (match_dup 4)) 0)))]
6150 {
6151   operands[1] = gen_lowpart (Pmode, operands[1]);
6152   operands[3] = gen_lowpart (Pmode, operands[3]);
6153   operands[4] = gen_lowpart (Pmode, operands[4]);
6154 }
6155   [(set_attr "type" "lea")
6156    (set_attr "mode" "SI")])
6157
6158 (define_insn "*adddi_1_rex64"
6159   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6160         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6161                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6162    (clobber (reg:CC FLAGS_REG))]
6163   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6164 {
6165   switch (get_attr_type (insn))
6166     {
6167     case TYPE_LEA:
6168       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6169       return "lea{q}\t{%a2, %0|%0, %a2}";
6170
6171     case TYPE_INCDEC:
6172       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6173       if (operands[2] == const1_rtx)
6174         return "inc{q}\t%0";
6175       else
6176         {
6177           gcc_assert (operands[2] == constm1_rtx);
6178           return "dec{q}\t%0";
6179         }
6180
6181     default:
6182       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6183
6184       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6185          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6186       if (CONST_INT_P (operands[2])
6187           /* Avoid overflows.  */
6188           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6189           && (INTVAL (operands[2]) == 128
6190               || (INTVAL (operands[2]) < 0
6191                   && INTVAL (operands[2]) != -128)))
6192         {
6193           operands[2] = GEN_INT (-INTVAL (operands[2]));
6194           return "sub{q}\t{%2, %0|%0, %2}";
6195         }
6196       return "add{q}\t{%2, %0|%0, %2}";
6197     }
6198 }
6199   [(set (attr "type")
6200      (cond [(eq_attr "alternative" "2")
6201               (const_string "lea")
6202             ; Current assemblers are broken and do not allow @GOTOFF in
6203             ; ought but a memory context.
6204             (match_operand:DI 2 "pic_symbolic_operand" "")
6205               (const_string "lea")
6206             (match_operand:DI 2 "incdec_operand" "")
6207               (const_string "incdec")
6208            ]
6209            (const_string "alu")))
6210    (set_attr "mode" "DI")])
6211
6212 ;; Convert lea to the lea pattern to avoid flags dependency.
6213 (define_split
6214   [(set (match_operand:DI 0 "register_operand" "")
6215         (plus:DI (match_operand:DI 1 "register_operand" "")
6216                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6217    (clobber (reg:CC FLAGS_REG))]
6218   "TARGET_64BIT && reload_completed
6219    && true_regnum (operands[0]) != true_regnum (operands[1])"
6220   [(set (match_dup 0)
6221         (plus:DI (match_dup 1)
6222                  (match_dup 2)))]
6223   "")
6224
6225 (define_insn "*adddi_2_rex64"
6226   [(set (reg FLAGS_REG)
6227         (compare
6228           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6229                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6230           (const_int 0)))
6231    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6232         (plus:DI (match_dup 1) (match_dup 2)))]
6233   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6234    && ix86_binary_operator_ok (PLUS, DImode, operands)
6235    /* Current assemblers are broken and do not allow @GOTOFF in
6236       ought but a memory context.  */
6237    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6238 {
6239   switch (get_attr_type (insn))
6240     {
6241     case TYPE_INCDEC:
6242       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6243       if (operands[2] == const1_rtx)
6244         return "inc{q}\t%0";
6245       else
6246         {
6247           gcc_assert (operands[2] == constm1_rtx);
6248           return "dec{q}\t%0";
6249         }
6250
6251     default:
6252       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6253       /* ???? We ought to handle there the 32bit case too
6254          - do we need new constraint?  */
6255       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6256          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6257       if (CONST_INT_P (operands[2])
6258           /* Avoid overflows.  */
6259           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6260           && (INTVAL (operands[2]) == 128
6261               || (INTVAL (operands[2]) < 0
6262                   && INTVAL (operands[2]) != -128)))
6263         {
6264           operands[2] = GEN_INT (-INTVAL (operands[2]));
6265           return "sub{q}\t{%2, %0|%0, %2}";
6266         }
6267       return "add{q}\t{%2, %0|%0, %2}";
6268     }
6269 }
6270   [(set (attr "type")
6271      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6272         (const_string "incdec")
6273         (const_string "alu")))
6274    (set_attr "mode" "DI")])
6275
6276 (define_insn "*adddi_3_rex64"
6277   [(set (reg FLAGS_REG)
6278         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6279                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6280    (clobber (match_scratch:DI 0 "=r"))]
6281   "TARGET_64BIT
6282    && ix86_match_ccmode (insn, CCZmode)
6283    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6284    /* Current assemblers are broken and do not allow @GOTOFF in
6285       ought but a memory context.  */
6286    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6287 {
6288   switch (get_attr_type (insn))
6289     {
6290     case TYPE_INCDEC:
6291       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6292       if (operands[2] == const1_rtx)
6293         return "inc{q}\t%0";
6294       else
6295         {
6296           gcc_assert (operands[2] == constm1_rtx);
6297           return "dec{q}\t%0";
6298         }
6299
6300     default:
6301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6302       /* ???? We ought to handle there the 32bit case too
6303          - do we need new constraint?  */
6304       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6305          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6306       if (CONST_INT_P (operands[2])
6307           /* Avoid overflows.  */
6308           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6309           && (INTVAL (operands[2]) == 128
6310               || (INTVAL (operands[2]) < 0
6311                   && INTVAL (operands[2]) != -128)))
6312         {
6313           operands[2] = GEN_INT (-INTVAL (operands[2]));
6314           return "sub{q}\t{%2, %0|%0, %2}";
6315         }
6316       return "add{q}\t{%2, %0|%0, %2}";
6317     }
6318 }
6319   [(set (attr "type")
6320      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6321         (const_string "incdec")
6322         (const_string "alu")))
6323    (set_attr "mode" "DI")])
6324
6325 ; For comparisons against 1, -1 and 128, we may generate better code
6326 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6327 ; is matched then.  We can't accept general immediate, because for
6328 ; case of overflows,  the result is messed up.
6329 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6330 ; when negated.
6331 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6332 ; only for comparisons not depending on it.
6333 (define_insn "*adddi_4_rex64"
6334   [(set (reg FLAGS_REG)
6335         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6336                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6337    (clobber (match_scratch:DI 0 "=rm"))]
6338   "TARGET_64BIT
6339    &&  ix86_match_ccmode (insn, CCGCmode)"
6340 {
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       if (operands[2] == constm1_rtx)
6345         return "inc{q}\t%0";
6346       else
6347         {
6348           gcc_assert (operands[2] == const1_rtx);
6349           return "dec{q}\t%0";
6350         }
6351
6352     default:
6353       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6354       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6355          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6356       if ((INTVAL (operands[2]) == -128
6357            || (INTVAL (operands[2]) > 0
6358                && INTVAL (operands[2]) != 128))
6359           /* Avoid overflows.  */
6360           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6361         return "sub{q}\t{%2, %0|%0, %2}";
6362       operands[2] = GEN_INT (-INTVAL (operands[2]));
6363       return "add{q}\t{%2, %0|%0, %2}";
6364     }
6365 }
6366   [(set (attr "type")
6367      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6368         (const_string "incdec")
6369         (const_string "alu")))
6370    (set_attr "mode" "DI")])
6371
6372 (define_insn "*adddi_5_rex64"
6373   [(set (reg FLAGS_REG)
6374         (compare
6375           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6376                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6377           (const_int 0)))
6378    (clobber (match_scratch:DI 0 "=r"))]
6379   "TARGET_64BIT
6380    && ix86_match_ccmode (insn, CCGOCmode)
6381    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6382    /* Current assemblers are broken and do not allow @GOTOFF in
6383       ought but a memory context.  */
6384    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6385 {
6386   switch (get_attr_type (insn))
6387     {
6388     case TYPE_INCDEC:
6389       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6390       if (operands[2] == const1_rtx)
6391         return "inc{q}\t%0";
6392       else
6393         {
6394           gcc_assert (operands[2] == constm1_rtx);
6395           return "dec{q}\t%0";
6396         }
6397
6398     default:
6399       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6400       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6401          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6402       if (CONST_INT_P (operands[2])
6403           /* Avoid overflows.  */
6404           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6405           && (INTVAL (operands[2]) == 128
6406               || (INTVAL (operands[2]) < 0
6407                   && INTVAL (operands[2]) != -128)))
6408         {
6409           operands[2] = GEN_INT (-INTVAL (operands[2]));
6410           return "sub{q}\t{%2, %0|%0, %2}";
6411         }
6412       return "add{q}\t{%2, %0|%0, %2}";
6413     }
6414 }
6415   [(set (attr "type")
6416      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6417         (const_string "incdec")
6418         (const_string "alu")))
6419    (set_attr "mode" "DI")])
6420
6421
6422 (define_insn "*addsi_1"
6423   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6424         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6425                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6426    (clobber (reg:CC FLAGS_REG))]
6427   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6428 {
6429   switch (get_attr_type (insn))
6430     {
6431     case TYPE_LEA:
6432       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6433       return "lea{l}\t{%a2, %0|%0, %a2}";
6434
6435     case TYPE_INCDEC:
6436       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6437       if (operands[2] == const1_rtx)
6438         return "inc{l}\t%0";
6439       else
6440         {
6441           gcc_assert (operands[2] == constm1_rtx);
6442           return "dec{l}\t%0";
6443         }
6444
6445     default:
6446       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6447
6448       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6449          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6450       if (CONST_INT_P (operands[2])
6451           && (INTVAL (operands[2]) == 128
6452               || (INTVAL (operands[2]) < 0
6453                   && INTVAL (operands[2]) != -128)))
6454         {
6455           operands[2] = GEN_INT (-INTVAL (operands[2]));
6456           return "sub{l}\t{%2, %0|%0, %2}";
6457         }
6458       return "add{l}\t{%2, %0|%0, %2}";
6459     }
6460 }
6461   [(set (attr "type")
6462      (cond [(eq_attr "alternative" "2")
6463               (const_string "lea")
6464             ; Current assemblers are broken and do not allow @GOTOFF in
6465             ; ought but a memory context.
6466             (match_operand:SI 2 "pic_symbolic_operand" "")
6467               (const_string "lea")
6468             (match_operand:SI 2 "incdec_operand" "")
6469               (const_string "incdec")
6470            ]
6471            (const_string "alu")))
6472    (set_attr "mode" "SI")])
6473
6474 ;; Convert lea to the lea pattern to avoid flags dependency.
6475 (define_split
6476   [(set (match_operand 0 "register_operand" "")
6477         (plus (match_operand 1 "register_operand" "")
6478               (match_operand 2 "nonmemory_operand" "")))
6479    (clobber (reg:CC FLAGS_REG))]
6480   "reload_completed
6481    && true_regnum (operands[0]) != true_regnum (operands[1])"
6482   [(const_int 0)]
6483 {
6484   rtx pat;
6485   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6486      may confuse gen_lowpart.  */
6487   if (GET_MODE (operands[0]) != Pmode)
6488     {
6489       operands[1] = gen_lowpart (Pmode, operands[1]);
6490       operands[2] = gen_lowpart (Pmode, operands[2]);
6491     }
6492   operands[0] = gen_lowpart (SImode, operands[0]);
6493   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6494   if (Pmode != SImode)
6495     pat = gen_rtx_SUBREG (SImode, pat, 0);
6496   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6497   DONE;
6498 })
6499
6500 ;; It may seem that nonimmediate operand is proper one for operand 1.
6501 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6502 ;; we take care in ix86_binary_operator_ok to not allow two memory
6503 ;; operands so proper swapping will be done in reload.  This allow
6504 ;; patterns constructed from addsi_1 to match.
6505 (define_insn "addsi_1_zext"
6506   [(set (match_operand:DI 0 "register_operand" "=r,r")
6507         (zero_extend:DI
6508           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6509                    (match_operand:SI 2 "general_operand" "g,li"))))
6510    (clobber (reg:CC FLAGS_REG))]
6511   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6512 {
6513   switch (get_attr_type (insn))
6514     {
6515     case TYPE_LEA:
6516       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6517       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6518
6519     case TYPE_INCDEC:
6520       if (operands[2] == const1_rtx)
6521         return "inc{l}\t%k0";
6522       else
6523         {
6524           gcc_assert (operands[2] == constm1_rtx);
6525           return "dec{l}\t%k0";
6526         }
6527
6528     default:
6529       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6530          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6531       if (CONST_INT_P (operands[2])
6532           && (INTVAL (operands[2]) == 128
6533               || (INTVAL (operands[2]) < 0
6534                   && INTVAL (operands[2]) != -128)))
6535         {
6536           operands[2] = GEN_INT (-INTVAL (operands[2]));
6537           return "sub{l}\t{%2, %k0|%k0, %2}";
6538         }
6539       return "add{l}\t{%2, %k0|%k0, %2}";
6540     }
6541 }
6542   [(set (attr "type")
6543      (cond [(eq_attr "alternative" "1")
6544               (const_string "lea")
6545             ; Current assemblers are broken and do not allow @GOTOFF in
6546             ; ought but a memory context.
6547             (match_operand:SI 2 "pic_symbolic_operand" "")
6548               (const_string "lea")
6549             (match_operand:SI 2 "incdec_operand" "")
6550               (const_string "incdec")
6551            ]
6552            (const_string "alu")))
6553    (set_attr "mode" "SI")])
6554
6555 ;; Convert lea to the lea pattern to avoid flags dependency.
6556 (define_split
6557   [(set (match_operand:DI 0 "register_operand" "")
6558         (zero_extend:DI
6559           (plus:SI (match_operand:SI 1 "register_operand" "")
6560                    (match_operand:SI 2 "nonmemory_operand" ""))))
6561    (clobber (reg:CC FLAGS_REG))]
6562   "TARGET_64BIT && reload_completed
6563    && true_regnum (operands[0]) != true_regnum (operands[1])"
6564   [(set (match_dup 0)
6565         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6566 {
6567   operands[1] = gen_lowpart (Pmode, operands[1]);
6568   operands[2] = gen_lowpart (Pmode, operands[2]);
6569 })
6570
6571 (define_insn "*addsi_2"
6572   [(set (reg FLAGS_REG)
6573         (compare
6574           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6575                    (match_operand:SI 2 "general_operand" "g,ri"))
6576           (const_int 0)))
6577    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6578         (plus:SI (match_dup 1) (match_dup 2)))]
6579   "ix86_match_ccmode (insn, CCGOCmode)
6580    && ix86_binary_operator_ok (PLUS, SImode, operands)
6581    /* Current assemblers are broken and do not allow @GOTOFF in
6582       ought but a memory context.  */
6583    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6584 {
6585   switch (get_attr_type (insn))
6586     {
6587     case TYPE_INCDEC:
6588       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6589       if (operands[2] == const1_rtx)
6590         return "inc{l}\t%0";
6591       else
6592         {
6593           gcc_assert (operands[2] == constm1_rtx);
6594           return "dec{l}\t%0";
6595         }
6596
6597     default:
6598       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6599       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6600          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6601       if (CONST_INT_P (operands[2])
6602           && (INTVAL (operands[2]) == 128
6603               || (INTVAL (operands[2]) < 0
6604                   && INTVAL (operands[2]) != -128)))
6605         {
6606           operands[2] = GEN_INT (-INTVAL (operands[2]));
6607           return "sub{l}\t{%2, %0|%0, %2}";
6608         }
6609       return "add{l}\t{%2, %0|%0, %2}";
6610     }
6611 }
6612   [(set (attr "type")
6613      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6614         (const_string "incdec")
6615         (const_string "alu")))
6616    (set_attr "mode" "SI")])
6617
6618 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6619 (define_insn "*addsi_2_zext"
6620   [(set (reg FLAGS_REG)
6621         (compare
6622           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6623                    (match_operand:SI 2 "general_operand" "g"))
6624           (const_int 0)))
6625    (set (match_operand:DI 0 "register_operand" "=r")
6626         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6627   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6628    && ix86_binary_operator_ok (PLUS, SImode, operands)
6629    /* Current assemblers are broken and do not allow @GOTOFF in
6630       ought but a memory context.  */
6631    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6632 {
6633   switch (get_attr_type (insn))
6634     {
6635     case TYPE_INCDEC:
6636       if (operands[2] == const1_rtx)
6637         return "inc{l}\t%k0";
6638       else
6639         {
6640           gcc_assert (operands[2] == constm1_rtx);
6641           return "dec{l}\t%k0";
6642         }
6643
6644     default:
6645       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6646          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6647       if (CONST_INT_P (operands[2])
6648           && (INTVAL (operands[2]) == 128
6649               || (INTVAL (operands[2]) < 0
6650                   && INTVAL (operands[2]) != -128)))
6651         {
6652           operands[2] = GEN_INT (-INTVAL (operands[2]));
6653           return "sub{l}\t{%2, %k0|%k0, %2}";
6654         }
6655       return "add{l}\t{%2, %k0|%k0, %2}";
6656     }
6657 }
6658   [(set (attr "type")
6659      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6660         (const_string "incdec")
6661         (const_string "alu")))
6662    (set_attr "mode" "SI")])
6663
6664 (define_insn "*addsi_3"
6665   [(set (reg FLAGS_REG)
6666         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6667                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6668    (clobber (match_scratch:SI 0 "=r"))]
6669   "ix86_match_ccmode (insn, CCZmode)
6670    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6671    /* Current assemblers are broken and do not allow @GOTOFF in
6672       ought but a memory context.  */
6673    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6674 {
6675   switch (get_attr_type (insn))
6676     {
6677     case TYPE_INCDEC:
6678       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6679       if (operands[2] == const1_rtx)
6680         return "inc{l}\t%0";
6681       else
6682         {
6683           gcc_assert (operands[2] == constm1_rtx);
6684           return "dec{l}\t%0";
6685         }
6686
6687     default:
6688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6689       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6690          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6691       if (CONST_INT_P (operands[2])
6692           && (INTVAL (operands[2]) == 128
6693               || (INTVAL (operands[2]) < 0
6694                   && INTVAL (operands[2]) != -128)))
6695         {
6696           operands[2] = GEN_INT (-INTVAL (operands[2]));
6697           return "sub{l}\t{%2, %0|%0, %2}";
6698         }
6699       return "add{l}\t{%2, %0|%0, %2}";
6700     }
6701 }
6702   [(set (attr "type")
6703      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6704         (const_string "incdec")
6705         (const_string "alu")))
6706    (set_attr "mode" "SI")])
6707
6708 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6709 (define_insn "*addsi_3_zext"
6710   [(set (reg FLAGS_REG)
6711         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6712                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6713    (set (match_operand:DI 0 "register_operand" "=r")
6714         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6715   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6716    && ix86_binary_operator_ok (PLUS, SImode, operands)
6717    /* Current assemblers are broken and do not allow @GOTOFF in
6718       ought but a memory context.  */
6719    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6720 {
6721   switch (get_attr_type (insn))
6722     {
6723     case TYPE_INCDEC:
6724       if (operands[2] == const1_rtx)
6725         return "inc{l}\t%k0";
6726       else
6727         {
6728           gcc_assert (operands[2] == constm1_rtx);
6729           return "dec{l}\t%k0";
6730         }
6731
6732     default:
6733       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6734          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6735       if (CONST_INT_P (operands[2])
6736           && (INTVAL (operands[2]) == 128
6737               || (INTVAL (operands[2]) < 0
6738                   && INTVAL (operands[2]) != -128)))
6739         {
6740           operands[2] = GEN_INT (-INTVAL (operands[2]));
6741           return "sub{l}\t{%2, %k0|%k0, %2}";
6742         }
6743       return "add{l}\t{%2, %k0|%k0, %2}";
6744     }
6745 }
6746   [(set (attr "type")
6747      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6748         (const_string "incdec")
6749         (const_string "alu")))
6750    (set_attr "mode" "SI")])
6751
6752 ; For comparisons against 1, -1 and 128, we may generate better code
6753 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6754 ; is matched then.  We can't accept general immediate, because for
6755 ; case of overflows,  the result is messed up.
6756 ; This pattern also don't hold of 0x80000000, since the value overflows
6757 ; when negated.
6758 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6759 ; only for comparisons not depending on it.
6760 (define_insn "*addsi_4"
6761   [(set (reg FLAGS_REG)
6762         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6763                  (match_operand:SI 2 "const_int_operand" "n")))
6764    (clobber (match_scratch:SI 0 "=rm"))]
6765   "ix86_match_ccmode (insn, CCGCmode)
6766    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6767 {
6768   switch (get_attr_type (insn))
6769     {
6770     case TYPE_INCDEC:
6771       if (operands[2] == constm1_rtx)
6772         return "inc{l}\t%0";
6773       else
6774         {
6775           gcc_assert (operands[2] == const1_rtx);
6776           return "dec{l}\t%0";
6777         }
6778
6779     default:
6780       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6781       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6782          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6783       if ((INTVAL (operands[2]) == -128
6784            || (INTVAL (operands[2]) > 0
6785                && INTVAL (operands[2]) != 128)))
6786         return "sub{l}\t{%2, %0|%0, %2}";
6787       operands[2] = GEN_INT (-INTVAL (operands[2]));
6788       return "add{l}\t{%2, %0|%0, %2}";
6789     }
6790 }
6791   [(set (attr "type")
6792      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6793         (const_string "incdec")
6794         (const_string "alu")))
6795    (set_attr "mode" "SI")])
6796
6797 (define_insn "*addsi_5"
6798   [(set (reg FLAGS_REG)
6799         (compare
6800           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6801                    (match_operand:SI 2 "general_operand" "g"))
6802           (const_int 0)))
6803    (clobber (match_scratch:SI 0 "=r"))]
6804   "ix86_match_ccmode (insn, CCGOCmode)
6805    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6806    /* Current assemblers are broken and do not allow @GOTOFF in
6807       ought but a memory context.  */
6808    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6809 {
6810   switch (get_attr_type (insn))
6811     {
6812     case TYPE_INCDEC:
6813       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6814       if (operands[2] == const1_rtx)
6815         return "inc{l}\t%0";
6816       else
6817         {
6818           gcc_assert (operands[2] == constm1_rtx);
6819           return "dec{l}\t%0";
6820         }
6821
6822     default:
6823       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6824       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6825          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6826       if (CONST_INT_P (operands[2])
6827           && (INTVAL (operands[2]) == 128
6828               || (INTVAL (operands[2]) < 0
6829                   && INTVAL (operands[2]) != -128)))
6830         {
6831           operands[2] = GEN_INT (-INTVAL (operands[2]));
6832           return "sub{l}\t{%2, %0|%0, %2}";
6833         }
6834       return "add{l}\t{%2, %0|%0, %2}";
6835     }
6836 }
6837   [(set (attr "type")
6838      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6839         (const_string "incdec")
6840         (const_string "alu")))
6841    (set_attr "mode" "SI")])
6842
6843 (define_expand "addhi3"
6844   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6845         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6846                  (match_operand:HI 2 "general_operand" "")))]
6847   "TARGET_HIMODE_MATH"
6848   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6849
6850 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6851 ;; type optimizations enabled by define-splits.  This is not important
6852 ;; for PII, and in fact harmful because of partial register stalls.
6853
6854 (define_insn "*addhi_1_lea"
6855   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6856         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6857                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6858    (clobber (reg:CC FLAGS_REG))]
6859   "!TARGET_PARTIAL_REG_STALL
6860    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6861 {
6862   switch (get_attr_type (insn))
6863     {
6864     case TYPE_LEA:
6865       return "#";
6866     case TYPE_INCDEC:
6867       if (operands[2] == const1_rtx)
6868         return "inc{w}\t%0";
6869       else
6870         {
6871           gcc_assert (operands[2] == constm1_rtx);
6872           return "dec{w}\t%0";
6873         }
6874
6875     default:
6876       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6877          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6878       if (CONST_INT_P (operands[2])
6879           && (INTVAL (operands[2]) == 128
6880               || (INTVAL (operands[2]) < 0
6881                   && INTVAL (operands[2]) != -128)))
6882         {
6883           operands[2] = GEN_INT (-INTVAL (operands[2]));
6884           return "sub{w}\t{%2, %0|%0, %2}";
6885         }
6886       return "add{w}\t{%2, %0|%0, %2}";
6887     }
6888 }
6889   [(set (attr "type")
6890      (if_then_else (eq_attr "alternative" "2")
6891         (const_string "lea")
6892         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6893            (const_string "incdec")
6894            (const_string "alu"))))
6895    (set_attr "mode" "HI,HI,SI")])
6896
6897 (define_insn "*addhi_1"
6898   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6899         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6900                  (match_operand:HI 2 "general_operand" "rn,rm")))
6901    (clobber (reg:CC FLAGS_REG))]
6902   "TARGET_PARTIAL_REG_STALL
6903    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6904 {
6905   switch (get_attr_type (insn))
6906     {
6907     case TYPE_INCDEC:
6908       if (operands[2] == const1_rtx)
6909         return "inc{w}\t%0";
6910       else
6911         {
6912           gcc_assert (operands[2] == constm1_rtx);
6913           return "dec{w}\t%0";
6914         }
6915
6916     default:
6917       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6918          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6919       if (CONST_INT_P (operands[2])
6920           && (INTVAL (operands[2]) == 128
6921               || (INTVAL (operands[2]) < 0
6922                   && INTVAL (operands[2]) != -128)))
6923         {
6924           operands[2] = GEN_INT (-INTVAL (operands[2]));
6925           return "sub{w}\t{%2, %0|%0, %2}";
6926         }
6927       return "add{w}\t{%2, %0|%0, %2}";
6928     }
6929 }
6930   [(set (attr "type")
6931      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6932         (const_string "incdec")
6933         (const_string "alu")))
6934    (set_attr "mode" "HI")])
6935
6936 (define_insn "*addhi_2"
6937   [(set (reg FLAGS_REG)
6938         (compare
6939           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6940                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6941           (const_int 0)))
6942    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6943         (plus:HI (match_dup 1) (match_dup 2)))]
6944   "ix86_match_ccmode (insn, CCGOCmode)
6945    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6946 {
6947   switch (get_attr_type (insn))
6948     {
6949     case TYPE_INCDEC:
6950       if (operands[2] == const1_rtx)
6951         return "inc{w}\t%0";
6952       else
6953         {
6954           gcc_assert (operands[2] == constm1_rtx);
6955           return "dec{w}\t%0";
6956         }
6957
6958     default:
6959       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6960          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6961       if (CONST_INT_P (operands[2])
6962           && (INTVAL (operands[2]) == 128
6963               || (INTVAL (operands[2]) < 0
6964                   && INTVAL (operands[2]) != -128)))
6965         {
6966           operands[2] = GEN_INT (-INTVAL (operands[2]));
6967           return "sub{w}\t{%2, %0|%0, %2}";
6968         }
6969       return "add{w}\t{%2, %0|%0, %2}";
6970     }
6971 }
6972   [(set (attr "type")
6973      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6974         (const_string "incdec")
6975         (const_string "alu")))
6976    (set_attr "mode" "HI")])
6977
6978 (define_insn "*addhi_3"
6979   [(set (reg FLAGS_REG)
6980         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6981                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6982    (clobber (match_scratch:HI 0 "=r"))]
6983   "ix86_match_ccmode (insn, CCZmode)
6984    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6985 {
6986   switch (get_attr_type (insn))
6987     {
6988     case TYPE_INCDEC:
6989       if (operands[2] == const1_rtx)
6990         return "inc{w}\t%0";
6991       else
6992         {
6993           gcc_assert (operands[2] == constm1_rtx);
6994           return "dec{w}\t%0";
6995         }
6996
6997     default:
6998       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6999          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7000       if (CONST_INT_P (operands[2])
7001           && (INTVAL (operands[2]) == 128
7002               || (INTVAL (operands[2]) < 0
7003                   && INTVAL (operands[2]) != -128)))
7004         {
7005           operands[2] = GEN_INT (-INTVAL (operands[2]));
7006           return "sub{w}\t{%2, %0|%0, %2}";
7007         }
7008       return "add{w}\t{%2, %0|%0, %2}";
7009     }
7010 }
7011   [(set (attr "type")
7012      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7013         (const_string "incdec")
7014         (const_string "alu")))
7015    (set_attr "mode" "HI")])
7016
7017 ; See comments above addsi_4 for details.
7018 (define_insn "*addhi_4"
7019   [(set (reg FLAGS_REG)
7020         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7021                  (match_operand:HI 2 "const_int_operand" "n")))
7022    (clobber (match_scratch:HI 0 "=rm"))]
7023   "ix86_match_ccmode (insn, CCGCmode)
7024    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7025 {
7026   switch (get_attr_type (insn))
7027     {
7028     case TYPE_INCDEC:
7029       if (operands[2] == constm1_rtx)
7030         return "inc{w}\t%0";
7031       else
7032         {
7033           gcc_assert (operands[2] == const1_rtx);
7034           return "dec{w}\t%0";
7035         }
7036
7037     default:
7038       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7039       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7040          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7041       if ((INTVAL (operands[2]) == -128
7042            || (INTVAL (operands[2]) > 0
7043                && INTVAL (operands[2]) != 128)))
7044         return "sub{w}\t{%2, %0|%0, %2}";
7045       operands[2] = GEN_INT (-INTVAL (operands[2]));
7046       return "add{w}\t{%2, %0|%0, %2}";
7047     }
7048 }
7049   [(set (attr "type")
7050      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7051         (const_string "incdec")
7052         (const_string "alu")))
7053    (set_attr "mode" "SI")])
7054
7055
7056 (define_insn "*addhi_5"
7057   [(set (reg FLAGS_REG)
7058         (compare
7059           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7060                    (match_operand:HI 2 "general_operand" "rmn"))
7061           (const_int 0)))
7062    (clobber (match_scratch:HI 0 "=r"))]
7063   "ix86_match_ccmode (insn, CCGOCmode)
7064    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7065 {
7066   switch (get_attr_type (insn))
7067     {
7068     case TYPE_INCDEC:
7069       if (operands[2] == const1_rtx)
7070         return "inc{w}\t%0";
7071       else
7072         {
7073           gcc_assert (operands[2] == constm1_rtx);
7074           return "dec{w}\t%0";
7075         }
7076
7077     default:
7078       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7079          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7080       if (CONST_INT_P (operands[2])
7081           && (INTVAL (operands[2]) == 128
7082               || (INTVAL (operands[2]) < 0
7083                   && INTVAL (operands[2]) != -128)))
7084         {
7085           operands[2] = GEN_INT (-INTVAL (operands[2]));
7086           return "sub{w}\t{%2, %0|%0, %2}";
7087         }
7088       return "add{w}\t{%2, %0|%0, %2}";
7089     }
7090 }
7091   [(set (attr "type")
7092      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7093         (const_string "incdec")
7094         (const_string "alu")))
7095    (set_attr "mode" "HI")])
7096
7097 (define_expand "addqi3"
7098   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7099         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7100                  (match_operand:QI 2 "general_operand" "")))]
7101   "TARGET_QIMODE_MATH"
7102   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7103
7104 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7105 (define_insn "*addqi_1_lea"
7106   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7107         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7108                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7109    (clobber (reg:CC FLAGS_REG))]
7110   "!TARGET_PARTIAL_REG_STALL
7111    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7112 {
7113   int widen = (which_alternative == 2);
7114   switch (get_attr_type (insn))
7115     {
7116     case TYPE_LEA:
7117       return "#";
7118     case TYPE_INCDEC:
7119       if (operands[2] == const1_rtx)
7120         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7121       else
7122         {
7123           gcc_assert (operands[2] == constm1_rtx);
7124           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7125         }
7126
7127     default:
7128       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7129          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7130       if (CONST_INT_P (operands[2])
7131           && (INTVAL (operands[2]) == 128
7132               || (INTVAL (operands[2]) < 0
7133                   && INTVAL (operands[2]) != -128)))
7134         {
7135           operands[2] = GEN_INT (-INTVAL (operands[2]));
7136           if (widen)
7137             return "sub{l}\t{%2, %k0|%k0, %2}";
7138           else
7139             return "sub{b}\t{%2, %0|%0, %2}";
7140         }
7141       if (widen)
7142         return "add{l}\t{%k2, %k0|%k0, %k2}";
7143       else
7144         return "add{b}\t{%2, %0|%0, %2}";
7145     }
7146 }
7147   [(set (attr "type")
7148      (if_then_else (eq_attr "alternative" "3")
7149         (const_string "lea")
7150         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7151            (const_string "incdec")
7152            (const_string "alu"))))
7153    (set_attr "mode" "QI,QI,SI,SI")])
7154
7155 (define_insn "*addqi_1"
7156   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7157         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7158                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7159    (clobber (reg:CC FLAGS_REG))]
7160   "TARGET_PARTIAL_REG_STALL
7161    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7162 {
7163   int widen = (which_alternative == 2);
7164   switch (get_attr_type (insn))
7165     {
7166     case TYPE_INCDEC:
7167       if (operands[2] == const1_rtx)
7168         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7169       else
7170         {
7171           gcc_assert (operands[2] == constm1_rtx);
7172           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7173         }
7174
7175     default:
7176       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7177          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7178       if (CONST_INT_P (operands[2])
7179           && (INTVAL (operands[2]) == 128
7180               || (INTVAL (operands[2]) < 0
7181                   && INTVAL (operands[2]) != -128)))
7182         {
7183           operands[2] = GEN_INT (-INTVAL (operands[2]));
7184           if (widen)
7185             return "sub{l}\t{%2, %k0|%k0, %2}";
7186           else
7187             return "sub{b}\t{%2, %0|%0, %2}";
7188         }
7189       if (widen)
7190         return "add{l}\t{%k2, %k0|%k0, %k2}";
7191       else
7192         return "add{b}\t{%2, %0|%0, %2}";
7193     }
7194 }
7195   [(set (attr "type")
7196      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7197         (const_string "incdec")
7198         (const_string "alu")))
7199    (set_attr "mode" "QI,QI,SI")])
7200
7201 (define_insn "*addqi_1_slp"
7202   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7203         (plus:QI (match_dup 0)
7204                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7205    (clobber (reg:CC FLAGS_REG))]
7206   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7207    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7208 {
7209   switch (get_attr_type (insn))
7210     {
7211     case TYPE_INCDEC:
7212       if (operands[1] == const1_rtx)
7213         return "inc{b}\t%0";
7214       else
7215         {
7216           gcc_assert (operands[1] == constm1_rtx);
7217           return "dec{b}\t%0";
7218         }
7219
7220     default:
7221       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7222       if (CONST_INT_P (operands[1])
7223           && INTVAL (operands[1]) < 0)
7224         {
7225           operands[1] = GEN_INT (-INTVAL (operands[1]));
7226           return "sub{b}\t{%1, %0|%0, %1}";
7227         }
7228       return "add{b}\t{%1, %0|%0, %1}";
7229     }
7230 }
7231   [(set (attr "type")
7232      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7233         (const_string "incdec")
7234         (const_string "alu1")))
7235    (set (attr "memory")
7236      (if_then_else (match_operand 1 "memory_operand" "")
7237         (const_string "load")
7238         (const_string "none")))
7239    (set_attr "mode" "QI")])
7240
7241 (define_insn "*addqi_2"
7242   [(set (reg FLAGS_REG)
7243         (compare
7244           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7245                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7246           (const_int 0)))
7247    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7248         (plus:QI (match_dup 1) (match_dup 2)))]
7249   "ix86_match_ccmode (insn, CCGOCmode)
7250    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7251 {
7252   switch (get_attr_type (insn))
7253     {
7254     case TYPE_INCDEC:
7255       if (operands[2] == const1_rtx)
7256         return "inc{b}\t%0";
7257       else
7258         {
7259           gcc_assert (operands[2] == constm1_rtx
7260                       || (CONST_INT_P (operands[2])
7261                           && INTVAL (operands[2]) == 255));
7262           return "dec{b}\t%0";
7263         }
7264
7265     default:
7266       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7267       if (CONST_INT_P (operands[2])
7268           && INTVAL (operands[2]) < 0)
7269         {
7270           operands[2] = GEN_INT (-INTVAL (operands[2]));
7271           return "sub{b}\t{%2, %0|%0, %2}";
7272         }
7273       return "add{b}\t{%2, %0|%0, %2}";
7274     }
7275 }
7276   [(set (attr "type")
7277      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7278         (const_string "incdec")
7279         (const_string "alu")))
7280    (set_attr "mode" "QI")])
7281
7282 (define_insn "*addqi_3"
7283   [(set (reg FLAGS_REG)
7284         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7285                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7286    (clobber (match_scratch:QI 0 "=q"))]
7287   "ix86_match_ccmode (insn, CCZmode)
7288    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7289 {
7290   switch (get_attr_type (insn))
7291     {
7292     case TYPE_INCDEC:
7293       if (operands[2] == const1_rtx)
7294         return "inc{b}\t%0";
7295       else
7296         {
7297           gcc_assert (operands[2] == constm1_rtx
7298                       || (CONST_INT_P (operands[2])
7299                           && INTVAL (operands[2]) == 255));
7300           return "dec{b}\t%0";
7301         }
7302
7303     default:
7304       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7305       if (CONST_INT_P (operands[2])
7306           && INTVAL (operands[2]) < 0)
7307         {
7308           operands[2] = GEN_INT (-INTVAL (operands[2]));
7309           return "sub{b}\t{%2, %0|%0, %2}";
7310         }
7311       return "add{b}\t{%2, %0|%0, %2}";
7312     }
7313 }
7314   [(set (attr "type")
7315      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7316         (const_string "incdec")
7317         (const_string "alu")))
7318    (set_attr "mode" "QI")])
7319
7320 ; See comments above addsi_4 for details.
7321 (define_insn "*addqi_4"
7322   [(set (reg FLAGS_REG)
7323         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7324                  (match_operand:QI 2 "const_int_operand" "n")))
7325    (clobber (match_scratch:QI 0 "=qm"))]
7326   "ix86_match_ccmode (insn, CCGCmode)
7327    && (INTVAL (operands[2]) & 0xff) != 0x80"
7328 {
7329   switch (get_attr_type (insn))
7330     {
7331     case TYPE_INCDEC:
7332       if (operands[2] == constm1_rtx
7333           || (CONST_INT_P (operands[2])
7334               && INTVAL (operands[2]) == 255))
7335         return "inc{b}\t%0";
7336       else
7337         {
7338           gcc_assert (operands[2] == const1_rtx);
7339           return "dec{b}\t%0";
7340         }
7341
7342     default:
7343       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7344       if (INTVAL (operands[2]) < 0)
7345         {
7346           operands[2] = GEN_INT (-INTVAL (operands[2]));
7347           return "add{b}\t{%2, %0|%0, %2}";
7348         }
7349       return "sub{b}\t{%2, %0|%0, %2}";
7350     }
7351 }
7352   [(set (attr "type")
7353      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7354         (const_string "incdec")
7355         (const_string "alu")))
7356    (set_attr "mode" "QI")])
7357
7358
7359 (define_insn "*addqi_5"
7360   [(set (reg FLAGS_REG)
7361         (compare
7362           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7363                    (match_operand:QI 2 "general_operand" "qmn"))
7364           (const_int 0)))
7365    (clobber (match_scratch:QI 0 "=q"))]
7366   "ix86_match_ccmode (insn, CCGOCmode)
7367    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7368 {
7369   switch (get_attr_type (insn))
7370     {
7371     case TYPE_INCDEC:
7372       if (operands[2] == const1_rtx)
7373         return "inc{b}\t%0";
7374       else
7375         {
7376           gcc_assert (operands[2] == constm1_rtx
7377                       || (CONST_INT_P (operands[2])
7378                           && INTVAL (operands[2]) == 255));
7379           return "dec{b}\t%0";
7380         }
7381
7382     default:
7383       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7384       if (CONST_INT_P (operands[2])
7385           && INTVAL (operands[2]) < 0)
7386         {
7387           operands[2] = GEN_INT (-INTVAL (operands[2]));
7388           return "sub{b}\t{%2, %0|%0, %2}";
7389         }
7390       return "add{b}\t{%2, %0|%0, %2}";
7391     }
7392 }
7393   [(set (attr "type")
7394      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7395         (const_string "incdec")
7396         (const_string "alu")))
7397    (set_attr "mode" "QI")])
7398
7399
7400 (define_insn "addqi_ext_1"
7401   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7402                          (const_int 8)
7403                          (const_int 8))
7404         (plus:SI
7405           (zero_extract:SI
7406             (match_operand 1 "ext_register_operand" "0")
7407             (const_int 8)
7408             (const_int 8))
7409           (match_operand:QI 2 "general_operand" "Qmn")))
7410    (clobber (reg:CC FLAGS_REG))]
7411   "!TARGET_64BIT"
7412 {
7413   switch (get_attr_type (insn))
7414     {
7415     case TYPE_INCDEC:
7416       if (operands[2] == const1_rtx)
7417         return "inc{b}\t%h0";
7418       else
7419         {
7420           gcc_assert (operands[2] == constm1_rtx
7421                       || (CONST_INT_P (operands[2])
7422                           && INTVAL (operands[2]) == 255));
7423           return "dec{b}\t%h0";
7424         }
7425
7426     default:
7427       return "add{b}\t{%2, %h0|%h0, %2}";
7428     }
7429 }
7430   [(set (attr "type")
7431      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7432         (const_string "incdec")
7433         (const_string "alu")))
7434    (set_attr "mode" "QI")])
7435
7436 (define_insn "*addqi_ext_1_rex64"
7437   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7438                          (const_int 8)
7439                          (const_int 8))
7440         (plus:SI
7441           (zero_extract:SI
7442             (match_operand 1 "ext_register_operand" "0")
7443             (const_int 8)
7444             (const_int 8))
7445           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7446    (clobber (reg:CC FLAGS_REG))]
7447   "TARGET_64BIT"
7448 {
7449   switch (get_attr_type (insn))
7450     {
7451     case TYPE_INCDEC:
7452       if (operands[2] == const1_rtx)
7453         return "inc{b}\t%h0";
7454       else
7455         {
7456           gcc_assert (operands[2] == constm1_rtx
7457                       || (CONST_INT_P (operands[2])
7458                           && INTVAL (operands[2]) == 255));
7459           return "dec{b}\t%h0";
7460         }
7461
7462     default:
7463       return "add{b}\t{%2, %h0|%h0, %2}";
7464     }
7465 }
7466   [(set (attr "type")
7467      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7468         (const_string "incdec")
7469         (const_string "alu")))
7470    (set_attr "mode" "QI")])
7471
7472 (define_insn "*addqi_ext_2"
7473   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7474                          (const_int 8)
7475                          (const_int 8))
7476         (plus:SI
7477           (zero_extract:SI
7478             (match_operand 1 "ext_register_operand" "%0")
7479             (const_int 8)
7480             (const_int 8))
7481           (zero_extract:SI
7482             (match_operand 2 "ext_register_operand" "Q")
7483             (const_int 8)
7484             (const_int 8))))
7485    (clobber (reg:CC FLAGS_REG))]
7486   ""
7487   "add{b}\t{%h2, %h0|%h0, %h2}"
7488   [(set_attr "type" "alu")
7489    (set_attr "mode" "QI")])
7490
7491 ;; The patterns that match these are at the end of this file.
7492
7493 (define_expand "addxf3"
7494   [(set (match_operand:XF 0 "register_operand" "")
7495         (plus:XF (match_operand:XF 1 "register_operand" "")
7496                  (match_operand:XF 2 "register_operand" "")))]
7497   "TARGET_80387"
7498   "")
7499
7500 (define_expand "add<mode>3"
7501   [(set (match_operand:MODEF 0 "register_operand" "")
7502         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7503                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7504   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7505     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7506   "")
7507 \f
7508 ;; Subtract instructions
7509
7510 ;; %%% splits for subditi3
7511
7512 (define_expand "subti3"
7513   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7514         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7515                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7516   "TARGET_64BIT"
7517   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7518
7519 (define_insn "*subti3_1"
7520   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7521         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7522                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7523    (clobber (reg:CC FLAGS_REG))]
7524   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7525   "#")
7526
7527 (define_split
7528   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7529         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7530                   (match_operand:TI 2 "x86_64_general_operand" "")))
7531    (clobber (reg:CC FLAGS_REG))]
7532   "TARGET_64BIT && reload_completed"
7533   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7534               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7535    (parallel [(set (match_dup 3)
7536                    (minus:DI (match_dup 4)
7537                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7538                                       (match_dup 5))))
7539               (clobber (reg:CC FLAGS_REG))])]
7540   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7541
7542 ;; %%% splits for subsidi3
7543
7544 (define_expand "subdi3"
7545   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7546         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7547                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7548   ""
7549   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7550
7551 (define_insn "*subdi3_1"
7552   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7553         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7554                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7555    (clobber (reg:CC FLAGS_REG))]
7556   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7557   "#")
7558
7559 (define_split
7560   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7561         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7562                   (match_operand:DI 2 "general_operand" "")))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "!TARGET_64BIT && reload_completed"
7565   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7566               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7567    (parallel [(set (match_dup 3)
7568                    (minus:SI (match_dup 4)
7569                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7570                                       (match_dup 5))))
7571               (clobber (reg:CC FLAGS_REG))])]
7572   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7573
7574 (define_insn "subdi3_carry_rex64"
7575   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7576           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7577             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7578                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7579    (clobber (reg:CC FLAGS_REG))]
7580   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7581   "sbb{q}\t{%2, %0|%0, %2}"
7582   [(set_attr "type" "alu")
7583    (set_attr "pent_pair" "pu")
7584    (set_attr "mode" "DI")])
7585
7586 (define_insn "*subdi_1_rex64"
7587   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7588         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7589                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7590    (clobber (reg:CC FLAGS_REG))]
7591   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7592   "sub{q}\t{%2, %0|%0, %2}"
7593   [(set_attr "type" "alu")
7594    (set_attr "mode" "DI")])
7595
7596 (define_insn "*subdi_2_rex64"
7597   [(set (reg FLAGS_REG)
7598         (compare
7599           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7600                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7601           (const_int 0)))
7602    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7603         (minus:DI (match_dup 1) (match_dup 2)))]
7604   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7605    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7606   "sub{q}\t{%2, %0|%0, %2}"
7607   [(set_attr "type" "alu")
7608    (set_attr "mode" "DI")])
7609
7610 (define_insn "*subdi_3_rex63"
7611   [(set (reg FLAGS_REG)
7612         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7613                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7614    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7615         (minus:DI (match_dup 1) (match_dup 2)))]
7616   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7617    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7618   "sub{q}\t{%2, %0|%0, %2}"
7619   [(set_attr "type" "alu")
7620    (set_attr "mode" "DI")])
7621
7622 (define_insn "subqi3_carry"
7623   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7624           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7625             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7626                (match_operand:QI 2 "general_operand" "qn,qm"))))
7627    (clobber (reg:CC FLAGS_REG))]
7628   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7629   "sbb{b}\t{%2, %0|%0, %2}"
7630   [(set_attr "type" "alu")
7631    (set_attr "pent_pair" "pu")
7632    (set_attr "mode" "QI")])
7633
7634 (define_insn "subhi3_carry"
7635   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7636           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7637             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7638                (match_operand:HI 2 "general_operand" "rn,rm"))))
7639    (clobber (reg:CC FLAGS_REG))]
7640   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7641   "sbb{w}\t{%2, %0|%0, %2}"
7642   [(set_attr "type" "alu")
7643    (set_attr "pent_pair" "pu")
7644    (set_attr "mode" "HI")])
7645
7646 (define_insn "subsi3_carry"
7647   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7648           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7649             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7650                (match_operand:SI 2 "general_operand" "ri,rm"))))
7651    (clobber (reg:CC FLAGS_REG))]
7652   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7653   "sbb{l}\t{%2, %0|%0, %2}"
7654   [(set_attr "type" "alu")
7655    (set_attr "pent_pair" "pu")
7656    (set_attr "mode" "SI")])
7657
7658 (define_insn "subsi3_carry_zext"
7659   [(set (match_operand:DI 0 "register_operand" "=r")
7660           (zero_extend:DI
7661             (minus:SI (match_operand:SI 1 "register_operand" "0")
7662               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7663                  (match_operand:SI 2 "general_operand" "g")))))
7664    (clobber (reg:CC FLAGS_REG))]
7665   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7666   "sbb{l}\t{%2, %k0|%k0, %2}"
7667   [(set_attr "type" "alu")
7668    (set_attr "pent_pair" "pu")
7669    (set_attr "mode" "SI")])
7670
7671 (define_expand "subsi3"
7672   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7673         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7674                   (match_operand:SI 2 "general_operand" "")))]
7675   ""
7676   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7677
7678 (define_insn "*subsi_1"
7679   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7680         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7681                   (match_operand:SI 2 "general_operand" "ri,rm")))
7682    (clobber (reg:CC FLAGS_REG))]
7683   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7684   "sub{l}\t{%2, %0|%0, %2}"
7685   [(set_attr "type" "alu")
7686    (set_attr "mode" "SI")])
7687
7688 (define_insn "*subsi_1_zext"
7689   [(set (match_operand:DI 0 "register_operand" "=r")
7690         (zero_extend:DI
7691           (minus:SI (match_operand:SI 1 "register_operand" "0")
7692                     (match_operand:SI 2 "general_operand" "g"))))
7693    (clobber (reg:CC FLAGS_REG))]
7694   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7695   "sub{l}\t{%2, %k0|%k0, %2}"
7696   [(set_attr "type" "alu")
7697    (set_attr "mode" "SI")])
7698
7699 (define_insn "*subsi_2"
7700   [(set (reg FLAGS_REG)
7701         (compare
7702           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7703                     (match_operand:SI 2 "general_operand" "ri,rm"))
7704           (const_int 0)))
7705    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7706         (minus:SI (match_dup 1) (match_dup 2)))]
7707   "ix86_match_ccmode (insn, CCGOCmode)
7708    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7709   "sub{l}\t{%2, %0|%0, %2}"
7710   [(set_attr "type" "alu")
7711    (set_attr "mode" "SI")])
7712
7713 (define_insn "*subsi_2_zext"
7714   [(set (reg FLAGS_REG)
7715         (compare
7716           (minus:SI (match_operand:SI 1 "register_operand" "0")
7717                     (match_operand:SI 2 "general_operand" "g"))
7718           (const_int 0)))
7719    (set (match_operand:DI 0 "register_operand" "=r")
7720         (zero_extend:DI
7721           (minus:SI (match_dup 1)
7722                     (match_dup 2))))]
7723   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7724    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7725   "sub{l}\t{%2, %k0|%k0, %2}"
7726   [(set_attr "type" "alu")
7727    (set_attr "mode" "SI")])
7728
7729 (define_insn "*subsi_3"
7730   [(set (reg FLAGS_REG)
7731         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7732                  (match_operand:SI 2 "general_operand" "ri,rm")))
7733    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7734         (minus:SI (match_dup 1) (match_dup 2)))]
7735   "ix86_match_ccmode (insn, CCmode)
7736    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7737   "sub{l}\t{%2, %0|%0, %2}"
7738   [(set_attr "type" "alu")
7739    (set_attr "mode" "SI")])
7740
7741 (define_insn "*subsi_3_zext"
7742   [(set (reg FLAGS_REG)
7743         (compare (match_operand:SI 1 "register_operand" "0")
7744                  (match_operand:SI 2 "general_operand" "g")))
7745    (set (match_operand:DI 0 "register_operand" "=r")
7746         (zero_extend:DI
7747           (minus:SI (match_dup 1)
7748                     (match_dup 2))))]
7749   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7750    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7751   "sub{l}\t{%2, %1|%1, %2}"
7752   [(set_attr "type" "alu")
7753    (set_attr "mode" "DI")])
7754
7755 (define_expand "subhi3"
7756   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7757         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7758                   (match_operand:HI 2 "general_operand" "")))]
7759   "TARGET_HIMODE_MATH"
7760   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7761
7762 (define_insn "*subhi_1"
7763   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7764         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7765                   (match_operand:HI 2 "general_operand" "rn,rm")))
7766    (clobber (reg:CC FLAGS_REG))]
7767   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7768   "sub{w}\t{%2, %0|%0, %2}"
7769   [(set_attr "type" "alu")
7770    (set_attr "mode" "HI")])
7771
7772 (define_insn "*subhi_2"
7773   [(set (reg FLAGS_REG)
7774         (compare
7775           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7776                     (match_operand:HI 2 "general_operand" "rn,rm"))
7777           (const_int 0)))
7778    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7779         (minus:HI (match_dup 1) (match_dup 2)))]
7780   "ix86_match_ccmode (insn, CCGOCmode)
7781    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7782   "sub{w}\t{%2, %0|%0, %2}"
7783   [(set_attr "type" "alu")
7784    (set_attr "mode" "HI")])
7785
7786 (define_insn "*subhi_3"
7787   [(set (reg FLAGS_REG)
7788         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7789                  (match_operand:HI 2 "general_operand" "rn,rm")))
7790    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7791         (minus:HI (match_dup 1) (match_dup 2)))]
7792   "ix86_match_ccmode (insn, CCmode)
7793    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7794   "sub{w}\t{%2, %0|%0, %2}"
7795   [(set_attr "type" "alu")
7796    (set_attr "mode" "HI")])
7797
7798 (define_expand "subqi3"
7799   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7800         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7801                   (match_operand:QI 2 "general_operand" "")))]
7802   "TARGET_QIMODE_MATH"
7803   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7804
7805 (define_insn "*subqi_1"
7806   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7807         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7808                   (match_operand:QI 2 "general_operand" "qn,qm")))
7809    (clobber (reg:CC FLAGS_REG))]
7810   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7811   "sub{b}\t{%2, %0|%0, %2}"
7812   [(set_attr "type" "alu")
7813    (set_attr "mode" "QI")])
7814
7815 (define_insn "*subqi_1_slp"
7816   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7817         (minus:QI (match_dup 0)
7818                   (match_operand:QI 1 "general_operand" "qn,qm")))
7819    (clobber (reg:CC FLAGS_REG))]
7820   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7821    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7822   "sub{b}\t{%1, %0|%0, %1}"
7823   [(set_attr "type" "alu1")
7824    (set_attr "mode" "QI")])
7825
7826 (define_insn "*subqi_2"
7827   [(set (reg FLAGS_REG)
7828         (compare
7829           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7830                     (match_operand:QI 2 "general_operand" "qn,qm"))
7831           (const_int 0)))
7832    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7833         (minus:QI (match_dup 1) (match_dup 2)))]
7834   "ix86_match_ccmode (insn, CCGOCmode)
7835    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7836   "sub{b}\t{%2, %0|%0, %2}"
7837   [(set_attr "type" "alu")
7838    (set_attr "mode" "QI")])
7839
7840 (define_insn "*subqi_3"
7841   [(set (reg FLAGS_REG)
7842         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7843                  (match_operand:QI 2 "general_operand" "qn,qm")))
7844    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7845         (minus:QI (match_dup 1) (match_dup 2)))]
7846   "ix86_match_ccmode (insn, CCmode)
7847    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7848   "sub{b}\t{%2, %0|%0, %2}"
7849   [(set_attr "type" "alu")
7850    (set_attr "mode" "QI")])
7851
7852 ;; The patterns that match these are at the end of this file.
7853
7854 (define_expand "subxf3"
7855   [(set (match_operand:XF 0 "register_operand" "")
7856         (minus:XF (match_operand:XF 1 "register_operand" "")
7857                   (match_operand:XF 2 "register_operand" "")))]
7858   "TARGET_80387"
7859   "")
7860
7861 (define_expand "sub<mode>3"
7862   [(set (match_operand:MODEF 0 "register_operand" "")
7863         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7864                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7865   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7866     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7867   "")
7868 \f
7869 ;; Multiply instructions
7870
7871 (define_expand "muldi3"
7872   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7873                    (mult:DI (match_operand:DI 1 "register_operand" "")
7874                             (match_operand:DI 2 "x86_64_general_operand" "")))
7875               (clobber (reg:CC FLAGS_REG))])]
7876   "TARGET_64BIT"
7877   "")
7878
7879 ;; On AMDFAM10
7880 ;; IMUL reg64, reg64, imm8      Direct
7881 ;; IMUL reg64, mem64, imm8      VectorPath
7882 ;; IMUL reg64, reg64, imm32     Direct
7883 ;; IMUL reg64, mem64, imm32     VectorPath
7884 ;; IMUL reg64, reg64            Direct
7885 ;; IMUL reg64, mem64            Direct
7886
7887 (define_insn "*muldi3_1_rex64"
7888   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7889         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7890                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7891    (clobber (reg:CC FLAGS_REG))]
7892   "TARGET_64BIT
7893    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7894   "@
7895    imul{q}\t{%2, %1, %0|%0, %1, %2}
7896    imul{q}\t{%2, %1, %0|%0, %1, %2}
7897    imul{q}\t{%2, %0|%0, %2}"
7898   [(set_attr "type" "imul")
7899    (set_attr "prefix_0f" "0,0,1")
7900    (set (attr "athlon_decode")
7901         (cond [(eq_attr "cpu" "athlon")
7902                   (const_string "vector")
7903                (eq_attr "alternative" "1")
7904                   (const_string "vector")
7905                (and (eq_attr "alternative" "2")
7906                     (match_operand 1 "memory_operand" ""))
7907                   (const_string "vector")]
7908               (const_string "direct")))
7909    (set (attr "amdfam10_decode")
7910         (cond [(and (eq_attr "alternative" "0,1")
7911                     (match_operand 1 "memory_operand" ""))
7912                   (const_string "vector")]
7913               (const_string "direct")))
7914    (set_attr "mode" "DI")])
7915
7916 (define_expand "mulsi3"
7917   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7918                    (mult:SI (match_operand:SI 1 "register_operand" "")
7919                             (match_operand:SI 2 "general_operand" "")))
7920               (clobber (reg:CC FLAGS_REG))])]
7921   ""
7922   "")
7923
7924 ;; On AMDFAM10
7925 ;; IMUL reg32, reg32, imm8      Direct
7926 ;; IMUL reg32, mem32, imm8      VectorPath
7927 ;; IMUL reg32, reg32, imm32     Direct
7928 ;; IMUL reg32, mem32, imm32     VectorPath
7929 ;; IMUL reg32, reg32            Direct
7930 ;; IMUL reg32, mem32            Direct
7931
7932 (define_insn "*mulsi3_1"
7933   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7934         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7935                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7936    (clobber (reg:CC FLAGS_REG))]
7937   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7938   "@
7939    imul{l}\t{%2, %1, %0|%0, %1, %2}
7940    imul{l}\t{%2, %1, %0|%0, %1, %2}
7941    imul{l}\t{%2, %0|%0, %2}"
7942   [(set_attr "type" "imul")
7943    (set_attr "prefix_0f" "0,0,1")
7944    (set (attr "athlon_decode")
7945         (cond [(eq_attr "cpu" "athlon")
7946                   (const_string "vector")
7947                (eq_attr "alternative" "1")
7948                   (const_string "vector")
7949                (and (eq_attr "alternative" "2")
7950                     (match_operand 1 "memory_operand" ""))
7951                   (const_string "vector")]
7952               (const_string "direct")))
7953    (set (attr "amdfam10_decode")
7954         (cond [(and (eq_attr "alternative" "0,1")
7955                     (match_operand 1 "memory_operand" ""))
7956                   (const_string "vector")]
7957               (const_string "direct")))
7958    (set_attr "mode" "SI")])
7959
7960 (define_insn "*mulsi3_1_zext"
7961   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7962         (zero_extend:DI
7963           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7964                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7965    (clobber (reg:CC FLAGS_REG))]
7966   "TARGET_64BIT
7967    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7968   "@
7969    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7970    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7971    imul{l}\t{%2, %k0|%k0, %2}"
7972   [(set_attr "type" "imul")
7973    (set_attr "prefix_0f" "0,0,1")
7974    (set (attr "athlon_decode")
7975         (cond [(eq_attr "cpu" "athlon")
7976                   (const_string "vector")
7977                (eq_attr "alternative" "1")
7978                   (const_string "vector")
7979                (and (eq_attr "alternative" "2")
7980                     (match_operand 1 "memory_operand" ""))
7981                   (const_string "vector")]
7982               (const_string "direct")))
7983    (set (attr "amdfam10_decode")
7984         (cond [(and (eq_attr "alternative" "0,1")
7985                     (match_operand 1 "memory_operand" ""))
7986                   (const_string "vector")]
7987               (const_string "direct")))
7988    (set_attr "mode" "SI")])
7989
7990 (define_expand "mulhi3"
7991   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7992                    (mult:HI (match_operand:HI 1 "register_operand" "")
7993                             (match_operand:HI 2 "general_operand" "")))
7994               (clobber (reg:CC FLAGS_REG))])]
7995   "TARGET_HIMODE_MATH"
7996   "")
7997
7998 ;; On AMDFAM10
7999 ;; IMUL reg16, reg16, imm8      VectorPath
8000 ;; IMUL reg16, mem16, imm8      VectorPath
8001 ;; IMUL reg16, reg16, imm16     VectorPath
8002 ;; IMUL reg16, mem16, imm16     VectorPath
8003 ;; IMUL reg16, reg16            Direct
8004 ;; IMUL reg16, mem16            Direct
8005 (define_insn "*mulhi3_1"
8006   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8007         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8008                  (match_operand:HI 2 "general_operand" "K,n,mr")))
8009    (clobber (reg:CC FLAGS_REG))]
8010   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8011   "@
8012    imul{w}\t{%2, %1, %0|%0, %1, %2}
8013    imul{w}\t{%2, %1, %0|%0, %1, %2}
8014    imul{w}\t{%2, %0|%0, %2}"
8015   [(set_attr "type" "imul")
8016    (set_attr "prefix_0f" "0,0,1")
8017    (set (attr "athlon_decode")
8018         (cond [(eq_attr "cpu" "athlon")
8019                   (const_string "vector")
8020                (eq_attr "alternative" "1,2")
8021                   (const_string "vector")]
8022               (const_string "direct")))
8023    (set (attr "amdfam10_decode")
8024         (cond [(eq_attr "alternative" "0,1")
8025                   (const_string "vector")]
8026               (const_string "direct")))
8027    (set_attr "mode" "HI")])
8028
8029 (define_expand "mulqi3"
8030   [(parallel [(set (match_operand:QI 0 "register_operand" "")
8031                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8032                             (match_operand:QI 2 "register_operand" "")))
8033               (clobber (reg:CC FLAGS_REG))])]
8034   "TARGET_QIMODE_MATH"
8035   "")
8036
8037 ;;On AMDFAM10
8038 ;; MUL reg8     Direct
8039 ;; MUL mem8     Direct
8040
8041 (define_insn "*mulqi3_1"
8042   [(set (match_operand:QI 0 "register_operand" "=a")
8043         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8044                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8045    (clobber (reg:CC FLAGS_REG))]
8046   "TARGET_QIMODE_MATH
8047    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8048   "mul{b}\t%2"
8049   [(set_attr "type" "imul")
8050    (set_attr "length_immediate" "0")
8051    (set (attr "athlon_decode")
8052      (if_then_else (eq_attr "cpu" "athlon")
8053         (const_string "vector")
8054         (const_string "direct")))
8055    (set_attr "amdfam10_decode" "direct")
8056    (set_attr "mode" "QI")])
8057
8058 (define_expand "umulqihi3"
8059   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8060                    (mult:HI (zero_extend:HI
8061                               (match_operand:QI 1 "nonimmediate_operand" ""))
8062                             (zero_extend:HI
8063                               (match_operand:QI 2 "register_operand" ""))))
8064               (clobber (reg:CC FLAGS_REG))])]
8065   "TARGET_QIMODE_MATH"
8066   "")
8067
8068 (define_insn "*umulqihi3_1"
8069   [(set (match_operand:HI 0 "register_operand" "=a")
8070         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8071                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8072    (clobber (reg:CC FLAGS_REG))]
8073   "TARGET_QIMODE_MATH
8074    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8075   "mul{b}\t%2"
8076   [(set_attr "type" "imul")
8077    (set_attr "length_immediate" "0")
8078    (set (attr "athlon_decode")
8079      (if_then_else (eq_attr "cpu" "athlon")
8080         (const_string "vector")
8081         (const_string "direct")))
8082    (set_attr "amdfam10_decode" "direct")
8083    (set_attr "mode" "QI")])
8084
8085 (define_expand "mulqihi3"
8086   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8087                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8088                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8089               (clobber (reg:CC FLAGS_REG))])]
8090   "TARGET_QIMODE_MATH"
8091   "")
8092
8093 (define_insn "*mulqihi3_insn"
8094   [(set (match_operand:HI 0 "register_operand" "=a")
8095         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8096                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8097    (clobber (reg:CC FLAGS_REG))]
8098   "TARGET_QIMODE_MATH
8099    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8100   "imul{b}\t%2"
8101   [(set_attr "type" "imul")
8102    (set_attr "length_immediate" "0")
8103    (set (attr "athlon_decode")
8104      (if_then_else (eq_attr "cpu" "athlon")
8105         (const_string "vector")
8106         (const_string "direct")))
8107    (set_attr "amdfam10_decode" "direct")
8108    (set_attr "mode" "QI")])
8109
8110 (define_expand "umulditi3"
8111   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8112                    (mult:TI (zero_extend:TI
8113                               (match_operand:DI 1 "nonimmediate_operand" ""))
8114                             (zero_extend:TI
8115                               (match_operand:DI 2 "register_operand" ""))))
8116               (clobber (reg:CC FLAGS_REG))])]
8117   "TARGET_64BIT"
8118   "")
8119
8120 (define_insn "*umulditi3_insn"
8121   [(set (match_operand:TI 0 "register_operand" "=A")
8122         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8123                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8124    (clobber (reg:CC FLAGS_REG))]
8125   "TARGET_64BIT
8126    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8127   "mul{q}\t%2"
8128   [(set_attr "type" "imul")
8129    (set_attr "length_immediate" "0")
8130    (set (attr "athlon_decode")
8131      (if_then_else (eq_attr "cpu" "athlon")
8132         (const_string "vector")
8133         (const_string "double")))
8134    (set_attr "amdfam10_decode" "double")
8135    (set_attr "mode" "DI")])
8136
8137 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8138 (define_expand "umulsidi3"
8139   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8140                    (mult:DI (zero_extend:DI
8141                               (match_operand:SI 1 "nonimmediate_operand" ""))
8142                             (zero_extend:DI
8143                               (match_operand:SI 2 "register_operand" ""))))
8144               (clobber (reg:CC FLAGS_REG))])]
8145   "!TARGET_64BIT"
8146   "")
8147
8148 (define_insn "*umulsidi3_insn"
8149   [(set (match_operand:DI 0 "register_operand" "=A")
8150         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8151                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8152    (clobber (reg:CC FLAGS_REG))]
8153   "!TARGET_64BIT
8154    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8155   "mul{l}\t%2"
8156   [(set_attr "type" "imul")
8157    (set_attr "length_immediate" "0")
8158    (set (attr "athlon_decode")
8159      (if_then_else (eq_attr "cpu" "athlon")
8160         (const_string "vector")
8161         (const_string "double")))
8162    (set_attr "amdfam10_decode" "double")
8163    (set_attr "mode" "SI")])
8164
8165 (define_expand "mulditi3"
8166   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8167                    (mult:TI (sign_extend:TI
8168                               (match_operand:DI 1 "nonimmediate_operand" ""))
8169                             (sign_extend:TI
8170                               (match_operand:DI 2 "register_operand" ""))))
8171               (clobber (reg:CC FLAGS_REG))])]
8172   "TARGET_64BIT"
8173   "")
8174
8175 (define_insn "*mulditi3_insn"
8176   [(set (match_operand:TI 0 "register_operand" "=A")
8177         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8178                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8179    (clobber (reg:CC FLAGS_REG))]
8180   "TARGET_64BIT
8181    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8182   "imul{q}\t%2"
8183   [(set_attr "type" "imul")
8184    (set_attr "length_immediate" "0")
8185    (set (attr "athlon_decode")
8186      (if_then_else (eq_attr "cpu" "athlon")
8187         (const_string "vector")
8188         (const_string "double")))
8189    (set_attr "amdfam10_decode" "double")
8190    (set_attr "mode" "DI")])
8191
8192 (define_expand "mulsidi3"
8193   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8194                    (mult:DI (sign_extend:DI
8195                               (match_operand:SI 1 "nonimmediate_operand" ""))
8196                             (sign_extend:DI
8197                               (match_operand:SI 2 "register_operand" ""))))
8198               (clobber (reg:CC FLAGS_REG))])]
8199   "!TARGET_64BIT"
8200   "")
8201
8202 (define_insn "*mulsidi3_insn"
8203   [(set (match_operand:DI 0 "register_operand" "=A")
8204         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8205                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8206    (clobber (reg:CC FLAGS_REG))]
8207   "!TARGET_64BIT
8208    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8209   "imul{l}\t%2"
8210   [(set_attr "type" "imul")
8211    (set_attr "length_immediate" "0")
8212    (set (attr "athlon_decode")
8213      (if_then_else (eq_attr "cpu" "athlon")
8214         (const_string "vector")
8215         (const_string "double")))
8216    (set_attr "amdfam10_decode" "double")
8217    (set_attr "mode" "SI")])
8218
8219 (define_expand "umuldi3_highpart"
8220   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8221                    (truncate:DI
8222                      (lshiftrt:TI
8223                        (mult:TI (zero_extend:TI
8224                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8225                                 (zero_extend:TI
8226                                   (match_operand:DI 2 "register_operand" "")))
8227                        (const_int 64))))
8228               (clobber (match_scratch:DI 3 ""))
8229               (clobber (reg:CC FLAGS_REG))])]
8230   "TARGET_64BIT"
8231   "")
8232
8233 (define_insn "*umuldi3_highpart_rex64"
8234   [(set (match_operand:DI 0 "register_operand" "=d")
8235         (truncate:DI
8236           (lshiftrt:TI
8237             (mult:TI (zero_extend:TI
8238                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8239                      (zero_extend:TI
8240                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8241             (const_int 64))))
8242    (clobber (match_scratch:DI 3 "=1"))
8243    (clobber (reg:CC FLAGS_REG))]
8244   "TARGET_64BIT
8245    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8246   "mul{q}\t%2"
8247   [(set_attr "type" "imul")
8248    (set_attr "length_immediate" "0")
8249    (set (attr "athlon_decode")
8250      (if_then_else (eq_attr "cpu" "athlon")
8251         (const_string "vector")
8252         (const_string "double")))
8253    (set_attr "amdfam10_decode" "double")
8254    (set_attr "mode" "DI")])
8255
8256 (define_expand "umulsi3_highpart"
8257   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8258                    (truncate:SI
8259                      (lshiftrt:DI
8260                        (mult:DI (zero_extend:DI
8261                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8262                                 (zero_extend:DI
8263                                   (match_operand:SI 2 "register_operand" "")))
8264                        (const_int 32))))
8265               (clobber (match_scratch:SI 3 ""))
8266               (clobber (reg:CC FLAGS_REG))])]
8267   ""
8268   "")
8269
8270 (define_insn "*umulsi3_highpart_insn"
8271   [(set (match_operand:SI 0 "register_operand" "=d")
8272         (truncate:SI
8273           (lshiftrt:DI
8274             (mult:DI (zero_extend:DI
8275                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8276                      (zero_extend:DI
8277                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8278             (const_int 32))))
8279    (clobber (match_scratch:SI 3 "=1"))
8280    (clobber (reg:CC FLAGS_REG))]
8281   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8282   "mul{l}\t%2"
8283   [(set_attr "type" "imul")
8284    (set_attr "length_immediate" "0")
8285    (set (attr "athlon_decode")
8286      (if_then_else (eq_attr "cpu" "athlon")
8287         (const_string "vector")
8288         (const_string "double")))
8289    (set_attr "amdfam10_decode" "double")
8290    (set_attr "mode" "SI")])
8291
8292 (define_insn "*umulsi3_highpart_zext"
8293   [(set (match_operand:DI 0 "register_operand" "=d")
8294         (zero_extend:DI (truncate:SI
8295           (lshiftrt:DI
8296             (mult:DI (zero_extend:DI
8297                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8298                      (zero_extend:DI
8299                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8300             (const_int 32)))))
8301    (clobber (match_scratch:SI 3 "=1"))
8302    (clobber (reg:CC FLAGS_REG))]
8303   "TARGET_64BIT
8304    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8305   "mul{l}\t%2"
8306   [(set_attr "type" "imul")
8307    (set_attr "length_immediate" "0")
8308    (set (attr "athlon_decode")
8309      (if_then_else (eq_attr "cpu" "athlon")
8310         (const_string "vector")
8311         (const_string "double")))
8312    (set_attr "amdfam10_decode" "double")
8313    (set_attr "mode" "SI")])
8314
8315 (define_expand "smuldi3_highpart"
8316   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8317                    (truncate:DI
8318                      (lshiftrt:TI
8319                        (mult:TI (sign_extend:TI
8320                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8321                                 (sign_extend:TI
8322                                   (match_operand:DI 2 "register_operand" "")))
8323                        (const_int 64))))
8324               (clobber (match_scratch:DI 3 ""))
8325               (clobber (reg:CC FLAGS_REG))])]
8326   "TARGET_64BIT"
8327   "")
8328
8329 (define_insn "*smuldi3_highpart_rex64"
8330   [(set (match_operand:DI 0 "register_operand" "=d")
8331         (truncate:DI
8332           (lshiftrt:TI
8333             (mult:TI (sign_extend:TI
8334                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8335                      (sign_extend:TI
8336                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8337             (const_int 64))))
8338    (clobber (match_scratch:DI 3 "=1"))
8339    (clobber (reg:CC FLAGS_REG))]
8340   "TARGET_64BIT
8341    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8342   "imul{q}\t%2"
8343   [(set_attr "type" "imul")
8344    (set (attr "athlon_decode")
8345      (if_then_else (eq_attr "cpu" "athlon")
8346         (const_string "vector")
8347         (const_string "double")))
8348    (set_attr "amdfam10_decode" "double")
8349    (set_attr "mode" "DI")])
8350
8351 (define_expand "smulsi3_highpart"
8352   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8353                    (truncate:SI
8354                      (lshiftrt:DI
8355                        (mult:DI (sign_extend:DI
8356                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8357                                 (sign_extend:DI
8358                                   (match_operand:SI 2 "register_operand" "")))
8359                        (const_int 32))))
8360               (clobber (match_scratch:SI 3 ""))
8361               (clobber (reg:CC FLAGS_REG))])]
8362   ""
8363   "")
8364
8365 (define_insn "*smulsi3_highpart_insn"
8366   [(set (match_operand:SI 0 "register_operand" "=d")
8367         (truncate:SI
8368           (lshiftrt:DI
8369             (mult:DI (sign_extend:DI
8370                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8371                      (sign_extend:DI
8372                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8373             (const_int 32))))
8374    (clobber (match_scratch:SI 3 "=1"))
8375    (clobber (reg:CC FLAGS_REG))]
8376   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8377   "imul{l}\t%2"
8378   [(set_attr "type" "imul")
8379    (set (attr "athlon_decode")
8380      (if_then_else (eq_attr "cpu" "athlon")
8381         (const_string "vector")
8382         (const_string "double")))
8383    (set_attr "amdfam10_decode" "double")
8384    (set_attr "mode" "SI")])
8385
8386 (define_insn "*smulsi3_highpart_zext"
8387   [(set (match_operand:DI 0 "register_operand" "=d")
8388         (zero_extend:DI (truncate:SI
8389           (lshiftrt:DI
8390             (mult:DI (sign_extend:DI
8391                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8392                      (sign_extend:DI
8393                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8394             (const_int 32)))))
8395    (clobber (match_scratch:SI 3 "=1"))
8396    (clobber (reg:CC FLAGS_REG))]
8397   "TARGET_64BIT
8398    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8399   "imul{l}\t%2"
8400   [(set_attr "type" "imul")
8401    (set (attr "athlon_decode")
8402      (if_then_else (eq_attr "cpu" "athlon")
8403         (const_string "vector")
8404         (const_string "double")))
8405    (set_attr "amdfam10_decode" "double")
8406    (set_attr "mode" "SI")])
8407
8408 ;; The patterns that match these are at the end of this file.
8409
8410 (define_expand "mulxf3"
8411   [(set (match_operand:XF 0 "register_operand" "")
8412         (mult:XF (match_operand:XF 1 "register_operand" "")
8413                  (match_operand:XF 2 "register_operand" "")))]
8414   "TARGET_80387"
8415   "")
8416
8417 (define_expand "mul<mode>3"
8418   [(set (match_operand:MODEF 0 "register_operand" "")
8419         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8420                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8421   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8422     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8423   "")
8424
8425 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8426
8427 \f
8428 ;; Divide instructions
8429
8430 (define_insn "divqi3"
8431   [(set (match_operand:QI 0 "register_operand" "=a")
8432         (div:QI (match_operand:HI 1 "register_operand" "0")
8433                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8434    (clobber (reg:CC FLAGS_REG))]
8435   "TARGET_QIMODE_MATH"
8436   "idiv{b}\t%2"
8437   [(set_attr "type" "idiv")
8438    (set_attr "mode" "QI")])
8439
8440 (define_insn "udivqi3"
8441   [(set (match_operand:QI 0 "register_operand" "=a")
8442         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8443                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8444    (clobber (reg:CC FLAGS_REG))]
8445   "TARGET_QIMODE_MATH"
8446   "div{b}\t%2"
8447   [(set_attr "type" "idiv")
8448    (set_attr "mode" "QI")])
8449
8450 ;; The patterns that match these are at the end of this file.
8451
8452 (define_expand "divxf3"
8453   [(set (match_operand:XF 0 "register_operand" "")
8454         (div:XF (match_operand:XF 1 "register_operand" "")
8455                 (match_operand:XF 2 "register_operand" "")))]
8456   "TARGET_80387"
8457   "")
8458
8459 (define_expand "divdf3"
8460   [(set (match_operand:DF 0 "register_operand" "")
8461         (div:DF (match_operand:DF 1 "register_operand" "")
8462                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8463    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8464     || (TARGET_SSE2 && TARGET_SSE_MATH)"
8465    "")
8466
8467 (define_expand "divsf3"
8468   [(set (match_operand:SF 0 "register_operand" "")
8469         (div:SF (match_operand:SF 1 "register_operand" "")
8470                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8471   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8472     || TARGET_SSE_MATH"
8473 {
8474   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8475       && flag_finite_math_only && !flag_trapping_math
8476       && flag_unsafe_math_optimizations)
8477     {
8478       ix86_emit_swdivsf (operands[0], operands[1],
8479                          operands[2], SFmode);
8480       DONE;
8481     }
8482 })
8483 \f
8484 ;; Remainder instructions.
8485
8486 (define_expand "divmoddi4"
8487   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8488                    (div:DI (match_operand:DI 1 "register_operand" "")
8489                            (match_operand:DI 2 "nonimmediate_operand" "")))
8490               (set (match_operand:DI 3 "register_operand" "")
8491                    (mod:DI (match_dup 1) (match_dup 2)))
8492               (clobber (reg:CC FLAGS_REG))])]
8493   "TARGET_64BIT"
8494   "")
8495
8496 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8497 ;; Penalize eax case slightly because it results in worse scheduling
8498 ;; of code.
8499 (define_insn "*divmoddi4_nocltd_rex64"
8500   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8501         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8502                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8503    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8504         (mod:DI (match_dup 2) (match_dup 3)))
8505    (clobber (reg:CC FLAGS_REG))]
8506   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8507   "#"
8508   [(set_attr "type" "multi")])
8509
8510 (define_insn "*divmoddi4_cltd_rex64"
8511   [(set (match_operand:DI 0 "register_operand" "=a")
8512         (div:DI (match_operand:DI 2 "register_operand" "a")
8513                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8514    (set (match_operand:DI 1 "register_operand" "=&d")
8515         (mod:DI (match_dup 2) (match_dup 3)))
8516    (clobber (reg:CC FLAGS_REG))]
8517   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8518   "#"
8519   [(set_attr "type" "multi")])
8520
8521 (define_insn "*divmoddi_noext_rex64"
8522   [(set (match_operand:DI 0 "register_operand" "=a")
8523         (div:DI (match_operand:DI 1 "register_operand" "0")
8524                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8525    (set (match_operand:DI 3 "register_operand" "=d")
8526         (mod:DI (match_dup 1) (match_dup 2)))
8527    (use (match_operand:DI 4 "register_operand" "3"))
8528    (clobber (reg:CC FLAGS_REG))]
8529   "TARGET_64BIT"
8530   "idiv{q}\t%2"
8531   [(set_attr "type" "idiv")
8532    (set_attr "mode" "DI")])
8533
8534 (define_split
8535   [(set (match_operand:DI 0 "register_operand" "")
8536         (div:DI (match_operand:DI 1 "register_operand" "")
8537                 (match_operand:DI 2 "nonimmediate_operand" "")))
8538    (set (match_operand:DI 3 "register_operand" "")
8539         (mod:DI (match_dup 1) (match_dup 2)))
8540    (clobber (reg:CC FLAGS_REG))]
8541   "TARGET_64BIT && reload_completed"
8542   [(parallel [(set (match_dup 3)
8543                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8544               (clobber (reg:CC FLAGS_REG))])
8545    (parallel [(set (match_dup 0)
8546                    (div:DI (reg:DI 0) (match_dup 2)))
8547               (set (match_dup 3)
8548                    (mod:DI (reg:DI 0) (match_dup 2)))
8549               (use (match_dup 3))
8550               (clobber (reg:CC FLAGS_REG))])]
8551 {
8552   /* Avoid use of cltd in favor of a mov+shift.  */
8553   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8554     {
8555       if (true_regnum (operands[1]))
8556         emit_move_insn (operands[0], operands[1]);
8557       else
8558         emit_move_insn (operands[3], operands[1]);
8559       operands[4] = operands[3];
8560     }
8561   else
8562     {
8563       gcc_assert (!true_regnum (operands[1]));
8564       operands[4] = operands[1];
8565     }
8566 })
8567
8568
8569 (define_expand "divmodsi4"
8570   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8571                    (div:SI (match_operand:SI 1 "register_operand" "")
8572                            (match_operand:SI 2 "nonimmediate_operand" "")))
8573               (set (match_operand:SI 3 "register_operand" "")
8574                    (mod:SI (match_dup 1) (match_dup 2)))
8575               (clobber (reg:CC FLAGS_REG))])]
8576   ""
8577   "")
8578
8579 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8580 ;; Penalize eax case slightly because it results in worse scheduling
8581 ;; of code.
8582 (define_insn "*divmodsi4_nocltd"
8583   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8584         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8585                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8586    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8587         (mod:SI (match_dup 2) (match_dup 3)))
8588    (clobber (reg:CC FLAGS_REG))]
8589   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8590   "#"
8591   [(set_attr "type" "multi")])
8592
8593 (define_insn "*divmodsi4_cltd"
8594   [(set (match_operand:SI 0 "register_operand" "=a")
8595         (div:SI (match_operand:SI 2 "register_operand" "a")
8596                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8597    (set (match_operand:SI 1 "register_operand" "=&d")
8598         (mod:SI (match_dup 2) (match_dup 3)))
8599    (clobber (reg:CC FLAGS_REG))]
8600   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8601   "#"
8602   [(set_attr "type" "multi")])
8603
8604 (define_insn "*divmodsi_noext"
8605   [(set (match_operand:SI 0 "register_operand" "=a")
8606         (div:SI (match_operand:SI 1 "register_operand" "0")
8607                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8608    (set (match_operand:SI 3 "register_operand" "=d")
8609         (mod:SI (match_dup 1) (match_dup 2)))
8610    (use (match_operand:SI 4 "register_operand" "3"))
8611    (clobber (reg:CC FLAGS_REG))]
8612   ""
8613   "idiv{l}\t%2"
8614   [(set_attr "type" "idiv")
8615    (set_attr "mode" "SI")])
8616
8617 (define_split
8618   [(set (match_operand:SI 0 "register_operand" "")
8619         (div:SI (match_operand:SI 1 "register_operand" "")
8620                 (match_operand:SI 2 "nonimmediate_operand" "")))
8621    (set (match_operand:SI 3 "register_operand" "")
8622         (mod:SI (match_dup 1) (match_dup 2)))
8623    (clobber (reg:CC FLAGS_REG))]
8624   "reload_completed"
8625   [(parallel [(set (match_dup 3)
8626                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8627               (clobber (reg:CC FLAGS_REG))])
8628    (parallel [(set (match_dup 0)
8629                    (div:SI (reg:SI 0) (match_dup 2)))
8630               (set (match_dup 3)
8631                    (mod:SI (reg:SI 0) (match_dup 2)))
8632               (use (match_dup 3))
8633               (clobber (reg:CC FLAGS_REG))])]
8634 {
8635   /* Avoid use of cltd in favor of a mov+shift.  */
8636   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8637     {
8638       if (true_regnum (operands[1]))
8639         emit_move_insn (operands[0], operands[1]);
8640       else
8641         emit_move_insn (operands[3], operands[1]);
8642       operands[4] = operands[3];
8643     }
8644   else
8645     {
8646       gcc_assert (!true_regnum (operands[1]));
8647       operands[4] = operands[1];
8648     }
8649 })
8650 ;; %%% Split me.
8651 (define_insn "divmodhi4"
8652   [(set (match_operand:HI 0 "register_operand" "=a")
8653         (div:HI (match_operand:HI 1 "register_operand" "0")
8654                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8655    (set (match_operand:HI 3 "register_operand" "=&d")
8656         (mod:HI (match_dup 1) (match_dup 2)))
8657    (clobber (reg:CC FLAGS_REG))]
8658   "TARGET_HIMODE_MATH"
8659   "cwtd\;idiv{w}\t%2"
8660   [(set_attr "type" "multi")
8661    (set_attr "length_immediate" "0")
8662    (set_attr "mode" "SI")])
8663
8664 (define_insn "udivmoddi4"
8665   [(set (match_operand:DI 0 "register_operand" "=a")
8666         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8667                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8668    (set (match_operand:DI 3 "register_operand" "=&d")
8669         (umod:DI (match_dup 1) (match_dup 2)))
8670    (clobber (reg:CC FLAGS_REG))]
8671   "TARGET_64BIT"
8672   "xor{q}\t%3, %3\;div{q}\t%2"
8673   [(set_attr "type" "multi")
8674    (set_attr "length_immediate" "0")
8675    (set_attr "mode" "DI")])
8676
8677 (define_insn "*udivmoddi4_noext"
8678   [(set (match_operand:DI 0 "register_operand" "=a")
8679         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8680                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8681    (set (match_operand:DI 3 "register_operand" "=d")
8682         (umod:DI (match_dup 1) (match_dup 2)))
8683    (use (match_dup 3))
8684    (clobber (reg:CC FLAGS_REG))]
8685   "TARGET_64BIT"
8686   "div{q}\t%2"
8687   [(set_attr "type" "idiv")
8688    (set_attr "mode" "DI")])
8689
8690 (define_split
8691   [(set (match_operand:DI 0 "register_operand" "")
8692         (udiv:DI (match_operand:DI 1 "register_operand" "")
8693                  (match_operand:DI 2 "nonimmediate_operand" "")))
8694    (set (match_operand:DI 3 "register_operand" "")
8695         (umod:DI (match_dup 1) (match_dup 2)))
8696    (clobber (reg:CC FLAGS_REG))]
8697   "TARGET_64BIT && reload_completed"
8698   [(set (match_dup 3) (const_int 0))
8699    (parallel [(set (match_dup 0)
8700                    (udiv:DI (match_dup 1) (match_dup 2)))
8701               (set (match_dup 3)
8702                    (umod:DI (match_dup 1) (match_dup 2)))
8703               (use (match_dup 3))
8704               (clobber (reg:CC FLAGS_REG))])]
8705   "")
8706
8707 (define_insn "udivmodsi4"
8708   [(set (match_operand:SI 0 "register_operand" "=a")
8709         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8710                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8711    (set (match_operand:SI 3 "register_operand" "=&d")
8712         (umod:SI (match_dup 1) (match_dup 2)))
8713    (clobber (reg:CC FLAGS_REG))]
8714   ""
8715   "xor{l}\t%3, %3\;div{l}\t%2"
8716   [(set_attr "type" "multi")
8717    (set_attr "length_immediate" "0")
8718    (set_attr "mode" "SI")])
8719
8720 (define_insn "*udivmodsi4_noext"
8721   [(set (match_operand:SI 0 "register_operand" "=a")
8722         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8723                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8724    (set (match_operand:SI 3 "register_operand" "=d")
8725         (umod:SI (match_dup 1) (match_dup 2)))
8726    (use (match_dup 3))
8727    (clobber (reg:CC FLAGS_REG))]
8728   ""
8729   "div{l}\t%2"
8730   [(set_attr "type" "idiv")
8731    (set_attr "mode" "SI")])
8732
8733 (define_split
8734   [(set (match_operand:SI 0 "register_operand" "")
8735         (udiv:SI (match_operand:SI 1 "register_operand" "")
8736                  (match_operand:SI 2 "nonimmediate_operand" "")))
8737    (set (match_operand:SI 3 "register_operand" "")
8738         (umod:SI (match_dup 1) (match_dup 2)))
8739    (clobber (reg:CC FLAGS_REG))]
8740   "reload_completed"
8741   [(set (match_dup 3) (const_int 0))
8742    (parallel [(set (match_dup 0)
8743                    (udiv:SI (match_dup 1) (match_dup 2)))
8744               (set (match_dup 3)
8745                    (umod:SI (match_dup 1) (match_dup 2)))
8746               (use (match_dup 3))
8747               (clobber (reg:CC FLAGS_REG))])]
8748   "")
8749
8750 (define_expand "udivmodhi4"
8751   [(set (match_dup 4) (const_int 0))
8752    (parallel [(set (match_operand:HI 0 "register_operand" "")
8753                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8754                             (match_operand:HI 2 "nonimmediate_operand" "")))
8755               (set (match_operand:HI 3 "register_operand" "")
8756                    (umod:HI (match_dup 1) (match_dup 2)))
8757               (use (match_dup 4))
8758               (clobber (reg:CC FLAGS_REG))])]
8759   "TARGET_HIMODE_MATH"
8760   "operands[4] = gen_reg_rtx (HImode);")
8761
8762 (define_insn "*udivmodhi_noext"
8763   [(set (match_operand:HI 0 "register_operand" "=a")
8764         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8765                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8766    (set (match_operand:HI 3 "register_operand" "=d")
8767         (umod:HI (match_dup 1) (match_dup 2)))
8768    (use (match_operand:HI 4 "register_operand" "3"))
8769    (clobber (reg:CC FLAGS_REG))]
8770   ""
8771   "div{w}\t%2"
8772   [(set_attr "type" "idiv")
8773    (set_attr "mode" "HI")])
8774
8775 ;; We cannot use div/idiv for double division, because it causes
8776 ;; "division by zero" on the overflow and that's not what we expect
8777 ;; from truncate.  Because true (non truncating) double division is
8778 ;; never generated, we can't create this insn anyway.
8779 ;
8780 ;(define_insn ""
8781 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8782 ;       (truncate:SI
8783 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8784 ;                  (zero_extend:DI
8785 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8786 ;   (set (match_operand:SI 3 "register_operand" "=d")
8787 ;       (truncate:SI
8788 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8789 ;   (clobber (reg:CC FLAGS_REG))]
8790 ;  ""
8791 ;  "div{l}\t{%2, %0|%0, %2}"
8792 ;  [(set_attr "type" "idiv")])
8793 \f
8794 ;;- Logical AND instructions
8795
8796 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8797 ;; Note that this excludes ah.
8798
8799 (define_insn "*testdi_1_rex64"
8800   [(set (reg FLAGS_REG)
8801         (compare
8802           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8803                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8804           (const_int 0)))]
8805   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8806    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8807   "@
8808    test{l}\t{%k1, %k0|%k0, %k1}
8809    test{l}\t{%k1, %k0|%k0, %k1}
8810    test{q}\t{%1, %0|%0, %1}
8811    test{q}\t{%1, %0|%0, %1}
8812    test{q}\t{%1, %0|%0, %1}"
8813   [(set_attr "type" "test")
8814    (set_attr "modrm" "0,1,0,1,1")
8815    (set_attr "mode" "SI,SI,DI,DI,DI")
8816    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8817
8818 (define_insn "testsi_1"
8819   [(set (reg FLAGS_REG)
8820         (compare
8821           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8822                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8823           (const_int 0)))]
8824   "ix86_match_ccmode (insn, CCNOmode)
8825    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8826   "test{l}\t{%1, %0|%0, %1}"
8827   [(set_attr "type" "test")
8828    (set_attr "modrm" "0,1,1")
8829    (set_attr "mode" "SI")
8830    (set_attr "pent_pair" "uv,np,uv")])
8831
8832 (define_expand "testsi_ccno_1"
8833   [(set (reg:CCNO FLAGS_REG)
8834         (compare:CCNO
8835           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8836                   (match_operand:SI 1 "nonmemory_operand" ""))
8837           (const_int 0)))]
8838   ""
8839   "")
8840
8841 (define_insn "*testhi_1"
8842   [(set (reg FLAGS_REG)
8843         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8844                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8845                  (const_int 0)))]
8846   "ix86_match_ccmode (insn, CCNOmode)
8847    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8848   "test{w}\t{%1, %0|%0, %1}"
8849   [(set_attr "type" "test")
8850    (set_attr "modrm" "0,1,1")
8851    (set_attr "mode" "HI")
8852    (set_attr "pent_pair" "uv,np,uv")])
8853
8854 (define_expand "testqi_ccz_1"
8855   [(set (reg:CCZ FLAGS_REG)
8856         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8857                              (match_operand:QI 1 "nonmemory_operand" ""))
8858                  (const_int 0)))]
8859   ""
8860   "")
8861
8862 (define_insn "*testqi_1_maybe_si"
8863   [(set (reg FLAGS_REG)
8864         (compare
8865           (and:QI
8866             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8867             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8868           (const_int 0)))]
8869    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8870     && ix86_match_ccmode (insn,
8871                          CONST_INT_P (operands[1])
8872                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8873 {
8874   if (which_alternative == 3)
8875     {
8876       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8877         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8878       return "test{l}\t{%1, %k0|%k0, %1}";
8879     }
8880   return "test{b}\t{%1, %0|%0, %1}";
8881 }
8882   [(set_attr "type" "test")
8883    (set_attr "modrm" "0,1,1,1")
8884    (set_attr "mode" "QI,QI,QI,SI")
8885    (set_attr "pent_pair" "uv,np,uv,np")])
8886
8887 (define_insn "*testqi_1"
8888   [(set (reg FLAGS_REG)
8889         (compare
8890           (and:QI
8891             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8892             (match_operand:QI 1 "general_operand" "n,n,qn"))
8893           (const_int 0)))]
8894   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8895    && ix86_match_ccmode (insn, CCNOmode)"
8896   "test{b}\t{%1, %0|%0, %1}"
8897   [(set_attr "type" "test")
8898    (set_attr "modrm" "0,1,1")
8899    (set_attr "mode" "QI")
8900    (set_attr "pent_pair" "uv,np,uv")])
8901
8902 (define_expand "testqi_ext_ccno_0"
8903   [(set (reg:CCNO FLAGS_REG)
8904         (compare:CCNO
8905           (and:SI
8906             (zero_extract:SI
8907               (match_operand 0 "ext_register_operand" "")
8908               (const_int 8)
8909               (const_int 8))
8910             (match_operand 1 "const_int_operand" ""))
8911           (const_int 0)))]
8912   ""
8913   "")
8914
8915 (define_insn "*testqi_ext_0"
8916   [(set (reg FLAGS_REG)
8917         (compare
8918           (and:SI
8919             (zero_extract:SI
8920               (match_operand 0 "ext_register_operand" "Q")
8921               (const_int 8)
8922               (const_int 8))
8923             (match_operand 1 "const_int_operand" "n"))
8924           (const_int 0)))]
8925   "ix86_match_ccmode (insn, CCNOmode)"
8926   "test{b}\t{%1, %h0|%h0, %1}"
8927   [(set_attr "type" "test")
8928    (set_attr "mode" "QI")
8929    (set_attr "length_immediate" "1")
8930    (set_attr "pent_pair" "np")])
8931
8932 (define_insn "*testqi_ext_1"
8933   [(set (reg FLAGS_REG)
8934         (compare
8935           (and:SI
8936             (zero_extract:SI
8937               (match_operand 0 "ext_register_operand" "Q")
8938               (const_int 8)
8939               (const_int 8))
8940             (zero_extend:SI
8941               (match_operand:QI 1 "general_operand" "Qm")))
8942           (const_int 0)))]
8943   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8944    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8945   "test{b}\t{%1, %h0|%h0, %1}"
8946   [(set_attr "type" "test")
8947    (set_attr "mode" "QI")])
8948
8949 (define_insn "*testqi_ext_1_rex64"
8950   [(set (reg FLAGS_REG)
8951         (compare
8952           (and:SI
8953             (zero_extract:SI
8954               (match_operand 0 "ext_register_operand" "Q")
8955               (const_int 8)
8956               (const_int 8))
8957             (zero_extend:SI
8958               (match_operand:QI 1 "register_operand" "Q")))
8959           (const_int 0)))]
8960   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8961   "test{b}\t{%1, %h0|%h0, %1}"
8962   [(set_attr "type" "test")
8963    (set_attr "mode" "QI")])
8964
8965 (define_insn "*testqi_ext_2"
8966   [(set (reg FLAGS_REG)
8967         (compare
8968           (and:SI
8969             (zero_extract:SI
8970               (match_operand 0 "ext_register_operand" "Q")
8971               (const_int 8)
8972               (const_int 8))
8973             (zero_extract:SI
8974               (match_operand 1 "ext_register_operand" "Q")
8975               (const_int 8)
8976               (const_int 8)))
8977           (const_int 0)))]
8978   "ix86_match_ccmode (insn, CCNOmode)"
8979   "test{b}\t{%h1, %h0|%h0, %h1}"
8980   [(set_attr "type" "test")
8981    (set_attr "mode" "QI")])
8982
8983 ;; Combine likes to form bit extractions for some tests.  Humor it.
8984 (define_insn "*testqi_ext_3"
8985   [(set (reg FLAGS_REG)
8986         (compare (zero_extract:SI
8987                    (match_operand 0 "nonimmediate_operand" "rm")
8988                    (match_operand:SI 1 "const_int_operand" "")
8989                    (match_operand:SI 2 "const_int_operand" ""))
8990                  (const_int 0)))]
8991   "ix86_match_ccmode (insn, CCNOmode)
8992    && INTVAL (operands[1]) > 0
8993    && INTVAL (operands[2]) >= 0
8994    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8995    && (GET_MODE (operands[0]) == SImode
8996        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8997        || GET_MODE (operands[0]) == HImode
8998        || GET_MODE (operands[0]) == QImode)"
8999   "#")
9000
9001 (define_insn "*testqi_ext_3_rex64"
9002   [(set (reg FLAGS_REG)
9003         (compare (zero_extract:DI
9004                    (match_operand 0 "nonimmediate_operand" "rm")
9005                    (match_operand:DI 1 "const_int_operand" "")
9006                    (match_operand:DI 2 "const_int_operand" ""))
9007                  (const_int 0)))]
9008   "TARGET_64BIT
9009    && ix86_match_ccmode (insn, CCNOmode)
9010    && INTVAL (operands[1]) > 0
9011    && INTVAL (operands[2]) >= 0
9012    /* Ensure that resulting mask is zero or sign extended operand.  */
9013    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9014        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9015            && INTVAL (operands[1]) > 32))
9016    && (GET_MODE (operands[0]) == SImode
9017        || GET_MODE (operands[0]) == DImode
9018        || GET_MODE (operands[0]) == HImode
9019        || GET_MODE (operands[0]) == QImode)"
9020   "#")
9021
9022 (define_split
9023   [(set (match_operand 0 "flags_reg_operand" "")
9024         (match_operator 1 "compare_operator"
9025           [(zero_extract
9026              (match_operand 2 "nonimmediate_operand" "")
9027              (match_operand 3 "const_int_operand" "")
9028              (match_operand 4 "const_int_operand" ""))
9029            (const_int 0)]))]
9030   "ix86_match_ccmode (insn, CCNOmode)"
9031   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9032 {
9033   rtx val = operands[2];
9034   HOST_WIDE_INT len = INTVAL (operands[3]);
9035   HOST_WIDE_INT pos = INTVAL (operands[4]);
9036   HOST_WIDE_INT mask;
9037   enum machine_mode mode, submode;
9038
9039   mode = GET_MODE (val);
9040   if (MEM_P (val))
9041     {
9042       /* ??? Combine likes to put non-volatile mem extractions in QImode
9043          no matter the size of the test.  So find a mode that works.  */
9044       if (! MEM_VOLATILE_P (val))
9045         {
9046           mode = smallest_mode_for_size (pos + len, MODE_INT);
9047           val = adjust_address (val, mode, 0);
9048         }
9049     }
9050   else if (GET_CODE (val) == SUBREG
9051            && (submode = GET_MODE (SUBREG_REG (val)),
9052                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9053            && pos + len <= GET_MODE_BITSIZE (submode))
9054     {
9055       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9056       mode = submode;
9057       val = SUBREG_REG (val);
9058     }
9059   else if (mode == HImode && pos + len <= 8)
9060     {
9061       /* Small HImode tests can be converted to QImode.  */
9062       mode = QImode;
9063       val = gen_lowpart (QImode, val);
9064     }
9065
9066   if (len == HOST_BITS_PER_WIDE_INT)
9067     mask = -1;
9068   else
9069     mask = ((HOST_WIDE_INT)1 << len) - 1;
9070   mask <<= pos;
9071
9072   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9073 })
9074
9075 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9076 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9077 ;; this is relatively important trick.
9078 ;; Do the conversion only post-reload to avoid limiting of the register class
9079 ;; to QI regs.
9080 (define_split
9081   [(set (match_operand 0 "flags_reg_operand" "")
9082         (match_operator 1 "compare_operator"
9083           [(and (match_operand 2 "register_operand" "")
9084                 (match_operand 3 "const_int_operand" ""))
9085            (const_int 0)]))]
9086    "reload_completed
9087     && QI_REG_P (operands[2])
9088     && GET_MODE (operands[2]) != QImode
9089     && ((ix86_match_ccmode (insn, CCZmode)
9090          && !(INTVAL (operands[3]) & ~(255 << 8)))
9091         || (ix86_match_ccmode (insn, CCNOmode)
9092             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9093   [(set (match_dup 0)
9094         (match_op_dup 1
9095           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9096                    (match_dup 3))
9097            (const_int 0)]))]
9098   "operands[2] = gen_lowpart (SImode, operands[2]);
9099    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9100
9101 (define_split
9102   [(set (match_operand 0 "flags_reg_operand" "")
9103         (match_operator 1 "compare_operator"
9104           [(and (match_operand 2 "nonimmediate_operand" "")
9105                 (match_operand 3 "const_int_operand" ""))
9106            (const_int 0)]))]
9107    "reload_completed
9108     && GET_MODE (operands[2]) != QImode
9109     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9110     && ((ix86_match_ccmode (insn, CCZmode)
9111          && !(INTVAL (operands[3]) & ~255))
9112         || (ix86_match_ccmode (insn, CCNOmode)
9113             && !(INTVAL (operands[3]) & ~127)))"
9114   [(set (match_dup 0)
9115         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9116                          (const_int 0)]))]
9117   "operands[2] = gen_lowpart (QImode, operands[2]);
9118    operands[3] = gen_lowpart (QImode, operands[3]);")
9119
9120
9121 ;; %%% This used to optimize known byte-wide and operations to memory,
9122 ;; and sometimes to QImode registers.  If this is considered useful,
9123 ;; it should be done with splitters.
9124
9125 (define_expand "anddi3"
9126   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9127         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9128                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9129   "TARGET_64BIT"
9130   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9131
9132 (define_insn "*anddi_1_rex64"
9133   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9134         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9135                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9138 {
9139   switch (get_attr_type (insn))
9140     {
9141     case TYPE_IMOVX:
9142       {
9143         enum machine_mode mode;
9144
9145         gcc_assert (CONST_INT_P (operands[2]));
9146         if (INTVAL (operands[2]) == 0xff)
9147           mode = QImode;
9148         else
9149           {
9150             gcc_assert (INTVAL (operands[2]) == 0xffff);
9151             mode = HImode;
9152           }
9153
9154         operands[1] = gen_lowpart (mode, operands[1]);
9155         if (mode == QImode)
9156           return "movz{bq|x}\t{%1,%0|%0, %1}";
9157         else
9158           return "movz{wq|x}\t{%1,%0|%0, %1}";
9159       }
9160
9161     default:
9162       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9163       if (get_attr_mode (insn) == MODE_SI)
9164         return "and{l}\t{%k2, %k0|%k0, %k2}";
9165       else
9166         return "and{q}\t{%2, %0|%0, %2}";
9167     }
9168 }
9169   [(set_attr "type" "alu,alu,alu,imovx")
9170    (set_attr "length_immediate" "*,*,*,0")
9171    (set_attr "mode" "SI,DI,DI,DI")])
9172
9173 (define_insn "*anddi_2"
9174   [(set (reg FLAGS_REG)
9175         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9176                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9177                  (const_int 0)))
9178    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9179         (and:DI (match_dup 1) (match_dup 2)))]
9180   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9181    && ix86_binary_operator_ok (AND, DImode, operands)"
9182   "@
9183    and{l}\t{%k2, %k0|%k0, %k2}
9184    and{q}\t{%2, %0|%0, %2}
9185    and{q}\t{%2, %0|%0, %2}"
9186   [(set_attr "type" "alu")
9187    (set_attr "mode" "SI,DI,DI")])
9188
9189 (define_expand "andsi3"
9190   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9191         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9192                 (match_operand:SI 2 "general_operand" "")))]
9193   ""
9194   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9195
9196 (define_insn "*andsi_1"
9197   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9198         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9199                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9200    (clobber (reg:CC FLAGS_REG))]
9201   "ix86_binary_operator_ok (AND, SImode, operands)"
9202 {
9203   switch (get_attr_type (insn))
9204     {
9205     case TYPE_IMOVX:
9206       {
9207         enum machine_mode mode;
9208
9209         gcc_assert (CONST_INT_P (operands[2]));
9210         if (INTVAL (operands[2]) == 0xff)
9211           mode = QImode;
9212         else
9213           {
9214             gcc_assert (INTVAL (operands[2]) == 0xffff);
9215             mode = HImode;
9216           }
9217
9218         operands[1] = gen_lowpart (mode, operands[1]);
9219         if (mode == QImode)
9220           return "movz{bl|x}\t{%1,%0|%0, %1}";
9221         else
9222           return "movz{wl|x}\t{%1,%0|%0, %1}";
9223       }
9224
9225     default:
9226       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9227       return "and{l}\t{%2, %0|%0, %2}";
9228     }
9229 }
9230   [(set_attr "type" "alu,alu,imovx")
9231    (set_attr "length_immediate" "*,*,0")
9232    (set_attr "mode" "SI")])
9233
9234 (define_split
9235   [(set (match_operand 0 "register_operand" "")
9236         (and (match_dup 0)
9237              (const_int -65536)))
9238    (clobber (reg:CC FLAGS_REG))]
9239   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9240   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9241   "operands[1] = gen_lowpart (HImode, operands[0]);")
9242
9243 (define_split
9244   [(set (match_operand 0 "ext_register_operand" "")
9245         (and (match_dup 0)
9246              (const_int -256)))
9247    (clobber (reg:CC FLAGS_REG))]
9248   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9249   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9250   "operands[1] = gen_lowpart (QImode, operands[0]);")
9251
9252 (define_split
9253   [(set (match_operand 0 "ext_register_operand" "")
9254         (and (match_dup 0)
9255              (const_int -65281)))
9256    (clobber (reg:CC FLAGS_REG))]
9257   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9258   [(parallel [(set (zero_extract:SI (match_dup 0)
9259                                     (const_int 8)
9260                                     (const_int 8))
9261                    (xor:SI
9262                      (zero_extract:SI (match_dup 0)
9263                                       (const_int 8)
9264                                       (const_int 8))
9265                      (zero_extract:SI (match_dup 0)
9266                                       (const_int 8)
9267                                       (const_int 8))))
9268               (clobber (reg:CC FLAGS_REG))])]
9269   "operands[0] = gen_lowpart (SImode, operands[0]);")
9270
9271 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9272 (define_insn "*andsi_1_zext"
9273   [(set (match_operand:DI 0 "register_operand" "=r")
9274         (zero_extend:DI
9275           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9276                   (match_operand:SI 2 "general_operand" "g"))))
9277    (clobber (reg:CC FLAGS_REG))]
9278   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9279   "and{l}\t{%2, %k0|%k0, %2}"
9280   [(set_attr "type" "alu")
9281    (set_attr "mode" "SI")])
9282
9283 (define_insn "*andsi_2"
9284   [(set (reg FLAGS_REG)
9285         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9286                          (match_operand:SI 2 "general_operand" "g,ri"))
9287                  (const_int 0)))
9288    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9289         (and:SI (match_dup 1) (match_dup 2)))]
9290   "ix86_match_ccmode (insn, CCNOmode)
9291    && ix86_binary_operator_ok (AND, SImode, operands)"
9292   "and{l}\t{%2, %0|%0, %2}"
9293   [(set_attr "type" "alu")
9294    (set_attr "mode" "SI")])
9295
9296 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9297 (define_insn "*andsi_2_zext"
9298   [(set (reg FLAGS_REG)
9299         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9300                          (match_operand:SI 2 "general_operand" "g"))
9301                  (const_int 0)))
9302    (set (match_operand:DI 0 "register_operand" "=r")
9303         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9304   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9305    && ix86_binary_operator_ok (AND, SImode, operands)"
9306   "and{l}\t{%2, %k0|%k0, %2}"
9307   [(set_attr "type" "alu")
9308    (set_attr "mode" "SI")])
9309
9310 (define_expand "andhi3"
9311   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9312         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9313                 (match_operand:HI 2 "general_operand" "")))]
9314   "TARGET_HIMODE_MATH"
9315   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9316
9317 (define_insn "*andhi_1"
9318   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9319         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9320                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9321    (clobber (reg:CC FLAGS_REG))]
9322   "ix86_binary_operator_ok (AND, HImode, operands)"
9323 {
9324   switch (get_attr_type (insn))
9325     {
9326     case TYPE_IMOVX:
9327       gcc_assert (CONST_INT_P (operands[2]));
9328       gcc_assert (INTVAL (operands[2]) == 0xff);
9329       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9330
9331     default:
9332       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9333
9334       return "and{w}\t{%2, %0|%0, %2}";
9335     }
9336 }
9337   [(set_attr "type" "alu,alu,imovx")
9338    (set_attr "length_immediate" "*,*,0")
9339    (set_attr "mode" "HI,HI,SI")])
9340
9341 (define_insn "*andhi_2"
9342   [(set (reg FLAGS_REG)
9343         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9344                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9345                  (const_int 0)))
9346    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9347         (and:HI (match_dup 1) (match_dup 2)))]
9348   "ix86_match_ccmode (insn, CCNOmode)
9349    && ix86_binary_operator_ok (AND, HImode, operands)"
9350   "and{w}\t{%2, %0|%0, %2}"
9351   [(set_attr "type" "alu")
9352    (set_attr "mode" "HI")])
9353
9354 (define_expand "andqi3"
9355   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9356         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9357                 (match_operand:QI 2 "general_operand" "")))]
9358   "TARGET_QIMODE_MATH"
9359   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9360
9361 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9362 (define_insn "*andqi_1"
9363   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9364         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9365                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9366    (clobber (reg:CC FLAGS_REG))]
9367   "ix86_binary_operator_ok (AND, QImode, operands)"
9368   "@
9369    and{b}\t{%2, %0|%0, %2}
9370    and{b}\t{%2, %0|%0, %2}
9371    and{l}\t{%k2, %k0|%k0, %k2}"
9372   [(set_attr "type" "alu")
9373    (set_attr "mode" "QI,QI,SI")])
9374
9375 (define_insn "*andqi_1_slp"
9376   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9377         (and:QI (match_dup 0)
9378                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9379    (clobber (reg:CC FLAGS_REG))]
9380   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9381    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9382   "and{b}\t{%1, %0|%0, %1}"
9383   [(set_attr "type" "alu1")
9384    (set_attr "mode" "QI")])
9385
9386 (define_insn "*andqi_2_maybe_si"
9387   [(set (reg FLAGS_REG)
9388         (compare (and:QI
9389                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9390                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9391                  (const_int 0)))
9392    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9393         (and:QI (match_dup 1) (match_dup 2)))]
9394   "ix86_binary_operator_ok (AND, QImode, operands)
9395    && ix86_match_ccmode (insn,
9396                          CONST_INT_P (operands[2])
9397                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9398 {
9399   if (which_alternative == 2)
9400     {
9401       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9402         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9403       return "and{l}\t{%2, %k0|%k0, %2}";
9404     }
9405   return "and{b}\t{%2, %0|%0, %2}";
9406 }
9407   [(set_attr "type" "alu")
9408    (set_attr "mode" "QI,QI,SI")])
9409
9410 (define_insn "*andqi_2"
9411   [(set (reg FLAGS_REG)
9412         (compare (and:QI
9413                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9414                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9415                  (const_int 0)))
9416    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9417         (and:QI (match_dup 1) (match_dup 2)))]
9418   "ix86_match_ccmode (insn, CCNOmode)
9419    && ix86_binary_operator_ok (AND, QImode, operands)"
9420   "and{b}\t{%2, %0|%0, %2}"
9421   [(set_attr "type" "alu")
9422    (set_attr "mode" "QI")])
9423
9424 (define_insn "*andqi_2_slp"
9425   [(set (reg FLAGS_REG)
9426         (compare (and:QI
9427                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9428                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9429                  (const_int 0)))
9430    (set (strict_low_part (match_dup 0))
9431         (and:QI (match_dup 0) (match_dup 1)))]
9432   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9433    && ix86_match_ccmode (insn, CCNOmode)
9434    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9435   "and{b}\t{%1, %0|%0, %1}"
9436   [(set_attr "type" "alu1")
9437    (set_attr "mode" "QI")])
9438
9439 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9440 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9441 ;; for a QImode operand, which of course failed.
9442
9443 (define_insn "andqi_ext_0"
9444   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9445                          (const_int 8)
9446                          (const_int 8))
9447         (and:SI
9448           (zero_extract:SI
9449             (match_operand 1 "ext_register_operand" "0")
9450             (const_int 8)
9451             (const_int 8))
9452           (match_operand 2 "const_int_operand" "n")))
9453    (clobber (reg:CC FLAGS_REG))]
9454   ""
9455   "and{b}\t{%2, %h0|%h0, %2}"
9456   [(set_attr "type" "alu")
9457    (set_attr "length_immediate" "1")
9458    (set_attr "mode" "QI")])
9459
9460 ;; Generated by peephole translating test to and.  This shows up
9461 ;; often in fp comparisons.
9462
9463 (define_insn "*andqi_ext_0_cc"
9464   [(set (reg FLAGS_REG)
9465         (compare
9466           (and:SI
9467             (zero_extract:SI
9468               (match_operand 1 "ext_register_operand" "0")
9469               (const_int 8)
9470               (const_int 8))
9471             (match_operand 2 "const_int_operand" "n"))
9472           (const_int 0)))
9473    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9474                          (const_int 8)
9475                          (const_int 8))
9476         (and:SI
9477           (zero_extract:SI
9478             (match_dup 1)
9479             (const_int 8)
9480             (const_int 8))
9481           (match_dup 2)))]
9482   "ix86_match_ccmode (insn, CCNOmode)"
9483   "and{b}\t{%2, %h0|%h0, %2}"
9484   [(set_attr "type" "alu")
9485    (set_attr "length_immediate" "1")
9486    (set_attr "mode" "QI")])
9487
9488 (define_insn "*andqi_ext_1"
9489   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9490                          (const_int 8)
9491                          (const_int 8))
9492         (and:SI
9493           (zero_extract:SI
9494             (match_operand 1 "ext_register_operand" "0")
9495             (const_int 8)
9496             (const_int 8))
9497           (zero_extend:SI
9498             (match_operand:QI 2 "general_operand" "Qm"))))
9499    (clobber (reg:CC FLAGS_REG))]
9500   "!TARGET_64BIT"
9501   "and{b}\t{%2, %h0|%h0, %2}"
9502   [(set_attr "type" "alu")
9503    (set_attr "length_immediate" "0")
9504    (set_attr "mode" "QI")])
9505
9506 (define_insn "*andqi_ext_1_rex64"
9507   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9508                          (const_int 8)
9509                          (const_int 8))
9510         (and:SI
9511           (zero_extract:SI
9512             (match_operand 1 "ext_register_operand" "0")
9513             (const_int 8)
9514             (const_int 8))
9515           (zero_extend:SI
9516             (match_operand 2 "ext_register_operand" "Q"))))
9517    (clobber (reg:CC FLAGS_REG))]
9518   "TARGET_64BIT"
9519   "and{b}\t{%2, %h0|%h0, %2}"
9520   [(set_attr "type" "alu")
9521    (set_attr "length_immediate" "0")
9522    (set_attr "mode" "QI")])
9523
9524 (define_insn "*andqi_ext_2"
9525   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9526                          (const_int 8)
9527                          (const_int 8))
9528         (and:SI
9529           (zero_extract:SI
9530             (match_operand 1 "ext_register_operand" "%0")
9531             (const_int 8)
9532             (const_int 8))
9533           (zero_extract:SI
9534             (match_operand 2 "ext_register_operand" "Q")
9535             (const_int 8)
9536             (const_int 8))))
9537    (clobber (reg:CC FLAGS_REG))]
9538   ""
9539   "and{b}\t{%h2, %h0|%h0, %h2}"
9540   [(set_attr "type" "alu")
9541    (set_attr "length_immediate" "0")
9542    (set_attr "mode" "QI")])
9543
9544 ;; Convert wide AND instructions with immediate operand to shorter QImode
9545 ;; equivalents when possible.
9546 ;; Don't do the splitting with memory operands, since it introduces risk
9547 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9548 ;; for size, but that can (should?) be handled by generic code instead.
9549 (define_split
9550   [(set (match_operand 0 "register_operand" "")
9551         (and (match_operand 1 "register_operand" "")
9552              (match_operand 2 "const_int_operand" "")))
9553    (clobber (reg:CC FLAGS_REG))]
9554    "reload_completed
9555     && QI_REG_P (operands[0])
9556     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9557     && !(~INTVAL (operands[2]) & ~(255 << 8))
9558     && GET_MODE (operands[0]) != QImode"
9559   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9560                    (and:SI (zero_extract:SI (match_dup 1)
9561                                             (const_int 8) (const_int 8))
9562                            (match_dup 2)))
9563               (clobber (reg:CC FLAGS_REG))])]
9564   "operands[0] = gen_lowpart (SImode, operands[0]);
9565    operands[1] = gen_lowpart (SImode, operands[1]);
9566    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9567
9568 ;; Since AND can be encoded with sign extended immediate, this is only
9569 ;; profitable when 7th bit is not set.
9570 (define_split
9571   [(set (match_operand 0 "register_operand" "")
9572         (and (match_operand 1 "general_operand" "")
9573              (match_operand 2 "const_int_operand" "")))
9574    (clobber (reg:CC FLAGS_REG))]
9575    "reload_completed
9576     && ANY_QI_REG_P (operands[0])
9577     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9578     && !(~INTVAL (operands[2]) & ~255)
9579     && !(INTVAL (operands[2]) & 128)
9580     && GET_MODE (operands[0]) != QImode"
9581   [(parallel [(set (strict_low_part (match_dup 0))
9582                    (and:QI (match_dup 1)
9583                            (match_dup 2)))
9584               (clobber (reg:CC FLAGS_REG))])]
9585   "operands[0] = gen_lowpart (QImode, operands[0]);
9586    operands[1] = gen_lowpart (QImode, operands[1]);
9587    operands[2] = gen_lowpart (QImode, operands[2]);")
9588 \f
9589 ;; Logical inclusive OR instructions
9590
9591 ;; %%% This used to optimize known byte-wide and operations to memory.
9592 ;; If this is considered useful, it should be done with splitters.
9593
9594 (define_expand "iordi3"
9595   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9596         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9597                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9598   "TARGET_64BIT"
9599   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9600
9601 (define_insn "*iordi_1_rex64"
9602   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9603         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9604                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "TARGET_64BIT
9607    && ix86_binary_operator_ok (IOR, DImode, operands)"
9608   "or{q}\t{%2, %0|%0, %2}"
9609   [(set_attr "type" "alu")
9610    (set_attr "mode" "DI")])
9611
9612 (define_insn "*iordi_2_rex64"
9613   [(set (reg FLAGS_REG)
9614         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9615                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9616                  (const_int 0)))
9617    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9618         (ior:DI (match_dup 1) (match_dup 2)))]
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 (define_insn "*iordi_3_rex64"
9627   [(set (reg FLAGS_REG)
9628         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9629                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9630                  (const_int 0)))
9631    (clobber (match_scratch:DI 0 "=r"))]
9632   "TARGET_64BIT
9633    && ix86_match_ccmode (insn, CCNOmode)
9634    && ix86_binary_operator_ok (IOR, DImode, operands)"
9635   "or{q}\t{%2, %0|%0, %2}"
9636   [(set_attr "type" "alu")
9637    (set_attr "mode" "DI")])
9638
9639
9640 (define_expand "iorsi3"
9641   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9642         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9643                 (match_operand:SI 2 "general_operand" "")))]
9644   ""
9645   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9646
9647 (define_insn "*iorsi_1"
9648   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9649         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9650                 (match_operand:SI 2 "general_operand" "ri,g")))
9651    (clobber (reg:CC FLAGS_REG))]
9652   "ix86_binary_operator_ok (IOR, SImode, operands)"
9653   "or{l}\t{%2, %0|%0, %2}"
9654   [(set_attr "type" "alu")
9655    (set_attr "mode" "SI")])
9656
9657 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9658 (define_insn "*iorsi_1_zext"
9659   [(set (match_operand:DI 0 "register_operand" "=r")
9660         (zero_extend:DI
9661           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9662                   (match_operand:SI 2 "general_operand" "g"))))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9665   "or{l}\t{%2, %k0|%k0, %2}"
9666   [(set_attr "type" "alu")
9667    (set_attr "mode" "SI")])
9668
9669 (define_insn "*iorsi_1_zext_imm"
9670   [(set (match_operand:DI 0 "register_operand" "=r")
9671         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9672                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9673    (clobber (reg:CC FLAGS_REG))]
9674   "TARGET_64BIT"
9675   "or{l}\t{%2, %k0|%k0, %2}"
9676   [(set_attr "type" "alu")
9677    (set_attr "mode" "SI")])
9678
9679 (define_insn "*iorsi_2"
9680   [(set (reg FLAGS_REG)
9681         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9682                          (match_operand:SI 2 "general_operand" "g,ri"))
9683                  (const_int 0)))
9684    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9685         (ior:SI (match_dup 1) (match_dup 2)))]
9686   "ix86_match_ccmode (insn, CCNOmode)
9687    && ix86_binary_operator_ok (IOR, SImode, operands)"
9688   "or{l}\t{%2, %0|%0, %2}"
9689   [(set_attr "type" "alu")
9690    (set_attr "mode" "SI")])
9691
9692 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9693 ;; ??? Special case for immediate operand is missing - it is tricky.
9694 (define_insn "*iorsi_2_zext"
9695   [(set (reg FLAGS_REG)
9696         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9697                          (match_operand:SI 2 "general_operand" "g"))
9698                  (const_int 0)))
9699    (set (match_operand:DI 0 "register_operand" "=r")
9700         (zero_extend:DI (ior:SI (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_2_zext_imm"
9708   [(set (reg FLAGS_REG)
9709         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9710                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9711                  (const_int 0)))
9712    (set (match_operand:DI 0 "register_operand" "=r")
9713         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9714   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9715    && ix86_binary_operator_ok (IOR, SImode, operands)"
9716   "or{l}\t{%2, %k0|%k0, %2}"
9717   [(set_attr "type" "alu")
9718    (set_attr "mode" "SI")])
9719
9720 (define_insn "*iorsi_3"
9721   [(set (reg FLAGS_REG)
9722         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9723                          (match_operand:SI 2 "general_operand" "g"))
9724                  (const_int 0)))
9725    (clobber (match_scratch:SI 0 "=r"))]
9726   "ix86_match_ccmode (insn, CCNOmode)
9727    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9728   "or{l}\t{%2, %0|%0, %2}"
9729   [(set_attr "type" "alu")
9730    (set_attr "mode" "SI")])
9731
9732 (define_expand "iorhi3"
9733   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9734         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9735                 (match_operand:HI 2 "general_operand" "")))]
9736   "TARGET_HIMODE_MATH"
9737   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9738
9739 (define_insn "*iorhi_1"
9740   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9741         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9742                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9743    (clobber (reg:CC FLAGS_REG))]
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_2"
9750   [(set (reg FLAGS_REG)
9751         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9752                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9753                  (const_int 0)))
9754    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9755         (ior:HI (match_dup 1) (match_dup 2)))]
9756   "ix86_match_ccmode (insn, CCNOmode)
9757    && ix86_binary_operator_ok (IOR, HImode, operands)"
9758   "or{w}\t{%2, %0|%0, %2}"
9759   [(set_attr "type" "alu")
9760    (set_attr "mode" "HI")])
9761
9762 (define_insn "*iorhi_3"
9763   [(set (reg FLAGS_REG)
9764         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9765                          (match_operand:HI 2 "general_operand" "rmn"))
9766                  (const_int 0)))
9767    (clobber (match_scratch:HI 0 "=r"))]
9768   "ix86_match_ccmode (insn, CCNOmode)
9769    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9770   "or{w}\t{%2, %0|%0, %2}"
9771   [(set_attr "type" "alu")
9772    (set_attr "mode" "HI")])
9773
9774 (define_expand "iorqi3"
9775   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9776         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9777                 (match_operand:QI 2 "general_operand" "")))]
9778   "TARGET_QIMODE_MATH"
9779   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9780
9781 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9782 (define_insn "*iorqi_1"
9783   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9784         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9785                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9786    (clobber (reg:CC FLAGS_REG))]
9787   "ix86_binary_operator_ok (IOR, QImode, operands)"
9788   "@
9789    or{b}\t{%2, %0|%0, %2}
9790    or{b}\t{%2, %0|%0, %2}
9791    or{l}\t{%k2, %k0|%k0, %k2}"
9792   [(set_attr "type" "alu")
9793    (set_attr "mode" "QI,QI,SI")])
9794
9795 (define_insn "*iorqi_1_slp"
9796   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9797         (ior:QI (match_dup 0)
9798                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9799    (clobber (reg:CC FLAGS_REG))]
9800   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9801    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9802   "or{b}\t{%1, %0|%0, %1}"
9803   [(set_attr "type" "alu1")
9804    (set_attr "mode" "QI")])
9805
9806 (define_insn "*iorqi_2"
9807   [(set (reg FLAGS_REG)
9808         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9809                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9810                  (const_int 0)))
9811    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9812         (ior:QI (match_dup 1) (match_dup 2)))]
9813   "ix86_match_ccmode (insn, CCNOmode)
9814    && ix86_binary_operator_ok (IOR, QImode, operands)"
9815   "or{b}\t{%2, %0|%0, %2}"
9816   [(set_attr "type" "alu")
9817    (set_attr "mode" "QI")])
9818
9819 (define_insn "*iorqi_2_slp"
9820   [(set (reg FLAGS_REG)
9821         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9822                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9823                  (const_int 0)))
9824    (set (strict_low_part (match_dup 0))
9825         (ior:QI (match_dup 0) (match_dup 1)))]
9826   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9827    && ix86_match_ccmode (insn, CCNOmode)
9828    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9829   "or{b}\t{%1, %0|%0, %1}"
9830   [(set_attr "type" "alu1")
9831    (set_attr "mode" "QI")])
9832
9833 (define_insn "*iorqi_3"
9834   [(set (reg FLAGS_REG)
9835         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9836                          (match_operand:QI 2 "general_operand" "qmn"))
9837                  (const_int 0)))
9838    (clobber (match_scratch:QI 0 "=q"))]
9839   "ix86_match_ccmode (insn, CCNOmode)
9840    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9841   "or{b}\t{%2, %0|%0, %2}"
9842   [(set_attr "type" "alu")
9843    (set_attr "mode" "QI")])
9844
9845 (define_insn "*iorqi_ext_0"
9846   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9847                          (const_int 8)
9848                          (const_int 8))
9849         (ior:SI
9850           (zero_extract:SI
9851             (match_operand 1 "ext_register_operand" "0")
9852             (const_int 8)
9853             (const_int 8))
9854           (match_operand 2 "const_int_operand" "n")))
9855    (clobber (reg:CC FLAGS_REG))]
9856   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9857   "or{b}\t{%2, %h0|%h0, %2}"
9858   [(set_attr "type" "alu")
9859    (set_attr "length_immediate" "1")
9860    (set_attr "mode" "QI")])
9861
9862 (define_insn "*iorqi_ext_1"
9863   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9864                          (const_int 8)
9865                          (const_int 8))
9866         (ior:SI
9867           (zero_extract:SI
9868             (match_operand 1 "ext_register_operand" "0")
9869             (const_int 8)
9870             (const_int 8))
9871           (zero_extend:SI
9872             (match_operand:QI 2 "general_operand" "Qm"))))
9873    (clobber (reg:CC FLAGS_REG))]
9874   "!TARGET_64BIT
9875    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9876   "or{b}\t{%2, %h0|%h0, %2}"
9877   [(set_attr "type" "alu")
9878    (set_attr "length_immediate" "0")
9879    (set_attr "mode" "QI")])
9880
9881 (define_insn "*iorqi_ext_1_rex64"
9882   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9883                          (const_int 8)
9884                          (const_int 8))
9885         (ior:SI
9886           (zero_extract:SI
9887             (match_operand 1 "ext_register_operand" "0")
9888             (const_int 8)
9889             (const_int 8))
9890           (zero_extend:SI
9891             (match_operand 2 "ext_register_operand" "Q"))))
9892    (clobber (reg:CC FLAGS_REG))]
9893   "TARGET_64BIT
9894    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9895   "or{b}\t{%2, %h0|%h0, %2}"
9896   [(set_attr "type" "alu")
9897    (set_attr "length_immediate" "0")
9898    (set_attr "mode" "QI")])
9899
9900 (define_insn "*iorqi_ext_2"
9901   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9902                          (const_int 8)
9903                          (const_int 8))
9904         (ior:SI
9905           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9906                            (const_int 8)
9907                            (const_int 8))
9908           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9909                            (const_int 8)
9910                            (const_int 8))))
9911    (clobber (reg:CC FLAGS_REG))]
9912   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9913   "ior{b}\t{%h2, %h0|%h0, %h2}"
9914   [(set_attr "type" "alu")
9915    (set_attr "length_immediate" "0")
9916    (set_attr "mode" "QI")])
9917
9918 (define_split
9919   [(set (match_operand 0 "register_operand" "")
9920         (ior (match_operand 1 "register_operand" "")
9921              (match_operand 2 "const_int_operand" "")))
9922    (clobber (reg:CC FLAGS_REG))]
9923    "reload_completed
9924     && QI_REG_P (operands[0])
9925     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9926     && !(INTVAL (operands[2]) & ~(255 << 8))
9927     && GET_MODE (operands[0]) != QImode"
9928   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9929                    (ior:SI (zero_extract:SI (match_dup 1)
9930                                             (const_int 8) (const_int 8))
9931                            (match_dup 2)))
9932               (clobber (reg:CC FLAGS_REG))])]
9933   "operands[0] = gen_lowpart (SImode, operands[0]);
9934    operands[1] = gen_lowpart (SImode, operands[1]);
9935    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9936
9937 ;; Since OR can be encoded with sign extended immediate, this is only
9938 ;; profitable when 7th bit is set.
9939 (define_split
9940   [(set (match_operand 0 "register_operand" "")
9941         (ior (match_operand 1 "general_operand" "")
9942              (match_operand 2 "const_int_operand" "")))
9943    (clobber (reg:CC FLAGS_REG))]
9944    "reload_completed
9945     && ANY_QI_REG_P (operands[0])
9946     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9947     && !(INTVAL (operands[2]) & ~255)
9948     && (INTVAL (operands[2]) & 128)
9949     && GET_MODE (operands[0]) != QImode"
9950   [(parallel [(set (strict_low_part (match_dup 0))
9951                    (ior:QI (match_dup 1)
9952                            (match_dup 2)))
9953               (clobber (reg:CC FLAGS_REG))])]
9954   "operands[0] = gen_lowpart (QImode, operands[0]);
9955    operands[1] = gen_lowpart (QImode, operands[1]);
9956    operands[2] = gen_lowpart (QImode, operands[2]);")
9957 \f
9958 ;; Logical XOR instructions
9959
9960 ;; %%% This used to optimize known byte-wide and operations to memory.
9961 ;; If this is considered useful, it should be done with splitters.
9962
9963 (define_expand "xordi3"
9964   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9965         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9966                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9967   "TARGET_64BIT"
9968   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9969
9970 (define_insn "*xordi_1_rex64"
9971   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9972         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9973                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9974    (clobber (reg:CC FLAGS_REG))]
9975   "TARGET_64BIT
9976    && ix86_binary_operator_ok (XOR, DImode, operands)"
9977   "xor{q}\t{%2, %0|%0, %2}"
9978   [(set_attr "type" "alu")
9979    (set_attr "mode" "DI")])
9980
9981 (define_insn "*xordi_2_rex64"
9982   [(set (reg FLAGS_REG)
9983         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9984                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9985                  (const_int 0)))
9986    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9987         (xor:DI (match_dup 1) (match_dup 2)))]
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_insn "*xordi_3_rex64"
9996   [(set (reg FLAGS_REG)
9997         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9998                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9999                  (const_int 0)))
10000    (clobber (match_scratch:DI 0 "=r"))]
10001   "TARGET_64BIT
10002    && ix86_match_ccmode (insn, CCNOmode)
10003    && ix86_binary_operator_ok (XOR, DImode, operands)"
10004   "xor{q}\t{%2, %0|%0, %2}"
10005   [(set_attr "type" "alu")
10006    (set_attr "mode" "DI")])
10007
10008 (define_expand "xorsi3"
10009   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10010         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10011                 (match_operand:SI 2 "general_operand" "")))]
10012   ""
10013   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10014
10015 (define_insn "*xorsi_1"
10016   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10017         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10018                 (match_operand:SI 2 "general_operand" "ri,rm")))
10019    (clobber (reg:CC FLAGS_REG))]
10020   "ix86_binary_operator_ok (XOR, SImode, operands)"
10021   "xor{l}\t{%2, %0|%0, %2}"
10022   [(set_attr "type" "alu")
10023    (set_attr "mode" "SI")])
10024
10025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10026 ;; Add speccase for immediates
10027 (define_insn "*xorsi_1_zext"
10028   [(set (match_operand:DI 0 "register_operand" "=r")
10029         (zero_extend:DI
10030           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10031                   (match_operand:SI 2 "general_operand" "g"))))
10032    (clobber (reg:CC FLAGS_REG))]
10033   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10034   "xor{l}\t{%2, %k0|%k0, %2}"
10035   [(set_attr "type" "alu")
10036    (set_attr "mode" "SI")])
10037
10038 (define_insn "*xorsi_1_zext_imm"
10039   [(set (match_operand:DI 0 "register_operand" "=r")
10040         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10041                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10042    (clobber (reg:CC FLAGS_REG))]
10043   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10044   "xor{l}\t{%2, %k0|%k0, %2}"
10045   [(set_attr "type" "alu")
10046    (set_attr "mode" "SI")])
10047
10048 (define_insn "*xorsi_2"
10049   [(set (reg FLAGS_REG)
10050         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10051                          (match_operand:SI 2 "general_operand" "g,ri"))
10052                  (const_int 0)))
10053    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10054         (xor:SI (match_dup 1) (match_dup 2)))]
10055   "ix86_match_ccmode (insn, CCNOmode)
10056    && ix86_binary_operator_ok (XOR, SImode, operands)"
10057   "xor{l}\t{%2, %0|%0, %2}"
10058   [(set_attr "type" "alu")
10059    (set_attr "mode" "SI")])
10060
10061 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10062 ;; ??? Special case for immediate operand is missing - it is tricky.
10063 (define_insn "*xorsi_2_zext"
10064   [(set (reg FLAGS_REG)
10065         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10066                          (match_operand:SI 2 "general_operand" "g"))
10067                  (const_int 0)))
10068    (set (match_operand:DI 0 "register_operand" "=r")
10069         (zero_extend:DI (xor:SI (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_2_zext_imm"
10077   [(set (reg FLAGS_REG)
10078         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10079                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10080                  (const_int 0)))
10081    (set (match_operand:DI 0 "register_operand" "=r")
10082         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10083   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10084    && ix86_binary_operator_ok (XOR, SImode, operands)"
10085   "xor{l}\t{%2, %k0|%k0, %2}"
10086   [(set_attr "type" "alu")
10087    (set_attr "mode" "SI")])
10088
10089 (define_insn "*xorsi_3"
10090   [(set (reg FLAGS_REG)
10091         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10092                          (match_operand:SI 2 "general_operand" "g"))
10093                  (const_int 0)))
10094    (clobber (match_scratch:SI 0 "=r"))]
10095   "ix86_match_ccmode (insn, CCNOmode)
10096    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10097   "xor{l}\t{%2, %0|%0, %2}"
10098   [(set_attr "type" "alu")
10099    (set_attr "mode" "SI")])
10100
10101 (define_expand "xorhi3"
10102   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10103         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10104                 (match_operand:HI 2 "general_operand" "")))]
10105   "TARGET_HIMODE_MATH"
10106   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10107
10108 (define_insn "*xorhi_1"
10109   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10110         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10111                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10112    (clobber (reg:CC FLAGS_REG))]
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_2"
10119   [(set (reg FLAGS_REG)
10120         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10121                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10122                  (const_int 0)))
10123    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10124         (xor:HI (match_dup 1) (match_dup 2)))]
10125   "ix86_match_ccmode (insn, CCNOmode)
10126    && ix86_binary_operator_ok (XOR, HImode, operands)"
10127   "xor{w}\t{%2, %0|%0, %2}"
10128   [(set_attr "type" "alu")
10129    (set_attr "mode" "HI")])
10130
10131 (define_insn "*xorhi_3"
10132   [(set (reg FLAGS_REG)
10133         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10134                          (match_operand:HI 2 "general_operand" "rmn"))
10135                  (const_int 0)))
10136    (clobber (match_scratch:HI 0 "=r"))]
10137   "ix86_match_ccmode (insn, CCNOmode)
10138    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10139   "xor{w}\t{%2, %0|%0, %2}"
10140   [(set_attr "type" "alu")
10141    (set_attr "mode" "HI")])
10142
10143 (define_expand "xorqi3"
10144   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10145         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10146                 (match_operand:QI 2 "general_operand" "")))]
10147   "TARGET_QIMODE_MATH"
10148   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10149
10150 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10151 (define_insn "*xorqi_1"
10152   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10153         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10154                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10155    (clobber (reg:CC FLAGS_REG))]
10156   "ix86_binary_operator_ok (XOR, QImode, operands)"
10157   "@
10158    xor{b}\t{%2, %0|%0, %2}
10159    xor{b}\t{%2, %0|%0, %2}
10160    xor{l}\t{%k2, %k0|%k0, %k2}"
10161   [(set_attr "type" "alu")
10162    (set_attr "mode" "QI,QI,SI")])
10163
10164 (define_insn "*xorqi_1_slp"
10165   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10166         (xor:QI (match_dup 0)
10167                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10168    (clobber (reg:CC FLAGS_REG))]
10169   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10170    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10171   "xor{b}\t{%1, %0|%0, %1}"
10172   [(set_attr "type" "alu1")
10173    (set_attr "mode" "QI")])
10174
10175 (define_insn "*xorqi_ext_0"
10176   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10177                          (const_int 8)
10178                          (const_int 8))
10179         (xor:SI
10180           (zero_extract:SI
10181             (match_operand 1 "ext_register_operand" "0")
10182             (const_int 8)
10183             (const_int 8))
10184           (match_operand 2 "const_int_operand" "n")))
10185    (clobber (reg:CC FLAGS_REG))]
10186   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10187   "xor{b}\t{%2, %h0|%h0, %2}"
10188   [(set_attr "type" "alu")
10189    (set_attr "length_immediate" "1")
10190    (set_attr "mode" "QI")])
10191
10192 (define_insn "*xorqi_ext_1"
10193   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10194                          (const_int 8)
10195                          (const_int 8))
10196         (xor:SI
10197           (zero_extract:SI
10198             (match_operand 1 "ext_register_operand" "0")
10199             (const_int 8)
10200             (const_int 8))
10201           (zero_extend:SI
10202             (match_operand:QI 2 "general_operand" "Qm"))))
10203    (clobber (reg:CC FLAGS_REG))]
10204   "!TARGET_64BIT
10205    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10206   "xor{b}\t{%2, %h0|%h0, %2}"
10207   [(set_attr "type" "alu")
10208    (set_attr "length_immediate" "0")
10209    (set_attr "mode" "QI")])
10210
10211 (define_insn "*xorqi_ext_1_rex64"
10212   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10213                          (const_int 8)
10214                          (const_int 8))
10215         (xor:SI
10216           (zero_extract:SI
10217             (match_operand 1 "ext_register_operand" "0")
10218             (const_int 8)
10219             (const_int 8))
10220           (zero_extend:SI
10221             (match_operand 2 "ext_register_operand" "Q"))))
10222    (clobber (reg:CC FLAGS_REG))]
10223   "TARGET_64BIT
10224    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10225   "xor{b}\t{%2, %h0|%h0, %2}"
10226   [(set_attr "type" "alu")
10227    (set_attr "length_immediate" "0")
10228    (set_attr "mode" "QI")])
10229
10230 (define_insn "*xorqi_ext_2"
10231   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10232                          (const_int 8)
10233                          (const_int 8))
10234         (xor:SI
10235           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10236                            (const_int 8)
10237                            (const_int 8))
10238           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10239                            (const_int 8)
10240                            (const_int 8))))
10241    (clobber (reg:CC FLAGS_REG))]
10242   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10243   "xor{b}\t{%h2, %h0|%h0, %h2}"
10244   [(set_attr "type" "alu")
10245    (set_attr "length_immediate" "0")
10246    (set_attr "mode" "QI")])
10247
10248 (define_insn "*xorqi_cc_1"
10249   [(set (reg FLAGS_REG)
10250         (compare
10251           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10252                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10253           (const_int 0)))
10254    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10255         (xor:QI (match_dup 1) (match_dup 2)))]
10256   "ix86_match_ccmode (insn, CCNOmode)
10257    && ix86_binary_operator_ok (XOR, QImode, operands)"
10258   "xor{b}\t{%2, %0|%0, %2}"
10259   [(set_attr "type" "alu")
10260    (set_attr "mode" "QI")])
10261
10262 (define_insn "*xorqi_2_slp"
10263   [(set (reg FLAGS_REG)
10264         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10265                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10266                  (const_int 0)))
10267    (set (strict_low_part (match_dup 0))
10268         (xor:QI (match_dup 0) (match_dup 1)))]
10269   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10270    && ix86_match_ccmode (insn, CCNOmode)
10271    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10272   "xor{b}\t{%1, %0|%0, %1}"
10273   [(set_attr "type" "alu1")
10274    (set_attr "mode" "QI")])
10275
10276 (define_insn "*xorqi_cc_2"
10277   [(set (reg FLAGS_REG)
10278         (compare
10279           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10280                   (match_operand:QI 2 "general_operand" "qmn"))
10281           (const_int 0)))
10282    (clobber (match_scratch:QI 0 "=q"))]
10283   "ix86_match_ccmode (insn, CCNOmode)
10284    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10285   "xor{b}\t{%2, %0|%0, %2}"
10286   [(set_attr "type" "alu")
10287    (set_attr "mode" "QI")])
10288
10289 (define_insn "*xorqi_cc_ext_1"
10290   [(set (reg FLAGS_REG)
10291         (compare
10292           (xor:SI
10293             (zero_extract:SI
10294               (match_operand 1 "ext_register_operand" "0")
10295               (const_int 8)
10296               (const_int 8))
10297             (match_operand:QI 2 "general_operand" "qmn"))
10298           (const_int 0)))
10299    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10300                          (const_int 8)
10301                          (const_int 8))
10302         (xor:SI
10303           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10304           (match_dup 2)))]
10305   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10306   "xor{b}\t{%2, %h0|%h0, %2}"
10307   [(set_attr "type" "alu")
10308    (set_attr "mode" "QI")])
10309
10310 (define_insn "*xorqi_cc_ext_1_rex64"
10311   [(set (reg FLAGS_REG)
10312         (compare
10313           (xor:SI
10314             (zero_extract:SI
10315               (match_operand 1 "ext_register_operand" "0")
10316               (const_int 8)
10317               (const_int 8))
10318             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10319           (const_int 0)))
10320    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10321                          (const_int 8)
10322                          (const_int 8))
10323         (xor:SI
10324           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10325           (match_dup 2)))]
10326   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10327   "xor{b}\t{%2, %h0|%h0, %2}"
10328   [(set_attr "type" "alu")
10329    (set_attr "mode" "QI")])
10330
10331 (define_expand "xorqi_cc_ext_1"
10332   [(parallel [
10333      (set (reg:CCNO FLAGS_REG)
10334           (compare:CCNO
10335             (xor:SI
10336               (zero_extract:SI
10337                 (match_operand 1 "ext_register_operand" "")
10338                 (const_int 8)
10339                 (const_int 8))
10340               (match_operand:QI 2 "general_operand" ""))
10341             (const_int 0)))
10342      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10343                            (const_int 8)
10344                            (const_int 8))
10345           (xor:SI
10346             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10347             (match_dup 2)))])]
10348   ""
10349   "")
10350
10351 (define_split
10352   [(set (match_operand 0 "register_operand" "")
10353         (xor (match_operand 1 "register_operand" "")
10354              (match_operand 2 "const_int_operand" "")))
10355    (clobber (reg:CC FLAGS_REG))]
10356    "reload_completed
10357     && QI_REG_P (operands[0])
10358     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10359     && !(INTVAL (operands[2]) & ~(255 << 8))
10360     && GET_MODE (operands[0]) != QImode"
10361   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10362                    (xor:SI (zero_extract:SI (match_dup 1)
10363                                             (const_int 8) (const_int 8))
10364                            (match_dup 2)))
10365               (clobber (reg:CC FLAGS_REG))])]
10366   "operands[0] = gen_lowpart (SImode, operands[0]);
10367    operands[1] = gen_lowpart (SImode, operands[1]);
10368    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10369
10370 ;; Since XOR can be encoded with sign extended immediate, this is only
10371 ;; profitable when 7th bit is set.
10372 (define_split
10373   [(set (match_operand 0 "register_operand" "")
10374         (xor (match_operand 1 "general_operand" "")
10375              (match_operand 2 "const_int_operand" "")))
10376    (clobber (reg:CC FLAGS_REG))]
10377    "reload_completed
10378     && ANY_QI_REG_P (operands[0])
10379     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10380     && !(INTVAL (operands[2]) & ~255)
10381     && (INTVAL (operands[2]) & 128)
10382     && GET_MODE (operands[0]) != QImode"
10383   [(parallel [(set (strict_low_part (match_dup 0))
10384                    (xor:QI (match_dup 1)
10385                            (match_dup 2)))
10386               (clobber (reg:CC FLAGS_REG))])]
10387   "operands[0] = gen_lowpart (QImode, operands[0]);
10388    operands[1] = gen_lowpart (QImode, operands[1]);
10389    operands[2] = gen_lowpart (QImode, operands[2]);")
10390 \f
10391 ;; Negation instructions
10392
10393 (define_expand "negti2"
10394   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10395         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10396   "TARGET_64BIT"
10397   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10398
10399 (define_insn "*negti2_1"
10400   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10401         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10402    (clobber (reg:CC FLAGS_REG))]
10403   "TARGET_64BIT
10404    && ix86_unary_operator_ok (NEG, TImode, operands)"
10405   "#")
10406
10407 (define_split
10408   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10409         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10410    (clobber (reg:CC FLAGS_REG))]
10411   "TARGET_64BIT && reload_completed"
10412   [(parallel
10413     [(set (reg:CCZ FLAGS_REG)
10414           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10415      (set (match_dup 0) (neg:DI (match_dup 1)))])
10416    (parallel
10417     [(set (match_dup 2)
10418           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10419                             (match_dup 3))
10420                    (const_int 0)))
10421      (clobber (reg:CC FLAGS_REG))])
10422    (parallel
10423     [(set (match_dup 2)
10424           (neg:DI (match_dup 2)))
10425      (clobber (reg:CC FLAGS_REG))])]
10426   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10427
10428 (define_expand "negdi2"
10429   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10430         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10431   ""
10432   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10433
10434 (define_insn "*negdi2_1"
10435   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10436         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10437    (clobber (reg:CC FLAGS_REG))]
10438   "!TARGET_64BIT
10439    && ix86_unary_operator_ok (NEG, DImode, operands)"
10440   "#")
10441
10442 (define_split
10443   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10444         (neg:DI (match_operand:DI 1 "general_operand" "")))
10445    (clobber (reg:CC FLAGS_REG))]
10446   "!TARGET_64BIT && reload_completed"
10447   [(parallel
10448     [(set (reg:CCZ FLAGS_REG)
10449           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10450      (set (match_dup 0) (neg:SI (match_dup 1)))])
10451    (parallel
10452     [(set (match_dup 2)
10453           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10454                             (match_dup 3))
10455                    (const_int 0)))
10456      (clobber (reg:CC FLAGS_REG))])
10457    (parallel
10458     [(set (match_dup 2)
10459           (neg:SI (match_dup 2)))
10460      (clobber (reg:CC FLAGS_REG))])]
10461   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10462
10463 (define_insn "*negdi2_1_rex64"
10464   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10465         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10466    (clobber (reg:CC FLAGS_REG))]
10467   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10468   "neg{q}\t%0"
10469   [(set_attr "type" "negnot")
10470    (set_attr "mode" "DI")])
10471
10472 ;; The problem with neg is that it does not perform (compare x 0),
10473 ;; it really performs (compare 0 x), which leaves us with the zero
10474 ;; flag being the only useful item.
10475
10476 (define_insn "*negdi2_cmpz_rex64"
10477   [(set (reg:CCZ FLAGS_REG)
10478         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10479                      (const_int 0)))
10480    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10481         (neg:DI (match_dup 1)))]
10482   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10483   "neg{q}\t%0"
10484   [(set_attr "type" "negnot")
10485    (set_attr "mode" "DI")])
10486
10487
10488 (define_expand "negsi2"
10489   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10490         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10491   ""
10492   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10493
10494 (define_insn "*negsi2_1"
10495   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10496         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10497    (clobber (reg:CC FLAGS_REG))]
10498   "ix86_unary_operator_ok (NEG, SImode, operands)"
10499   "neg{l}\t%0"
10500   [(set_attr "type" "negnot")
10501    (set_attr "mode" "SI")])
10502
10503 ;; Combine is quite creative about this pattern.
10504 (define_insn "*negsi2_1_zext"
10505   [(set (match_operand:DI 0 "register_operand" "=r")
10506         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10507                                         (const_int 32)))
10508                      (const_int 32)))
10509    (clobber (reg:CC FLAGS_REG))]
10510   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10511   "neg{l}\t%k0"
10512   [(set_attr "type" "negnot")
10513    (set_attr "mode" "SI")])
10514
10515 ;; The problem with neg is that it does not perform (compare x 0),
10516 ;; it really performs (compare 0 x), which leaves us with the zero
10517 ;; flag being the only useful item.
10518
10519 (define_insn "*negsi2_cmpz"
10520   [(set (reg:CCZ FLAGS_REG)
10521         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10522                      (const_int 0)))
10523    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10524         (neg:SI (match_dup 1)))]
10525   "ix86_unary_operator_ok (NEG, SImode, operands)"
10526   "neg{l}\t%0"
10527   [(set_attr "type" "negnot")
10528    (set_attr "mode" "SI")])
10529
10530 (define_insn "*negsi2_cmpz_zext"
10531   [(set (reg:CCZ FLAGS_REG)
10532         (compare:CCZ (lshiftrt:DI
10533                        (neg:DI (ashift:DI
10534                                  (match_operand:DI 1 "register_operand" "0")
10535                                  (const_int 32)))
10536                        (const_int 32))
10537                      (const_int 0)))
10538    (set (match_operand:DI 0 "register_operand" "=r")
10539         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10540                                         (const_int 32)))
10541                      (const_int 32)))]
10542   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10543   "neg{l}\t%k0"
10544   [(set_attr "type" "negnot")
10545    (set_attr "mode" "SI")])
10546
10547 (define_expand "neghi2"
10548   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10549         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10550   "TARGET_HIMODE_MATH"
10551   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10552
10553 (define_insn "*neghi2_1"
10554   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10555         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10556    (clobber (reg:CC FLAGS_REG))]
10557   "ix86_unary_operator_ok (NEG, HImode, operands)"
10558   "neg{w}\t%0"
10559   [(set_attr "type" "negnot")
10560    (set_attr "mode" "HI")])
10561
10562 (define_insn "*neghi2_cmpz"
10563   [(set (reg:CCZ FLAGS_REG)
10564         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10565                      (const_int 0)))
10566    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10567         (neg:HI (match_dup 1)))]
10568   "ix86_unary_operator_ok (NEG, HImode, operands)"
10569   "neg{w}\t%0"
10570   [(set_attr "type" "negnot")
10571    (set_attr "mode" "HI")])
10572
10573 (define_expand "negqi2"
10574   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10575         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10576   "TARGET_QIMODE_MATH"
10577   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10578
10579 (define_insn "*negqi2_1"
10580   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10581         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10582    (clobber (reg:CC FLAGS_REG))]
10583   "ix86_unary_operator_ok (NEG, QImode, operands)"
10584   "neg{b}\t%0"
10585   [(set_attr "type" "negnot")
10586    (set_attr "mode" "QI")])
10587
10588 (define_insn "*negqi2_cmpz"
10589   [(set (reg:CCZ FLAGS_REG)
10590         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10591                      (const_int 0)))
10592    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10593         (neg:QI (match_dup 1)))]
10594   "ix86_unary_operator_ok (NEG, QImode, operands)"
10595   "neg{b}\t%0"
10596   [(set_attr "type" "negnot")
10597    (set_attr "mode" "QI")])
10598
10599 ;; Changing of sign for FP values is doable using integer unit too.
10600
10601 (define_expand "<code><mode>2"
10602   [(set (match_operand:X87MODEF 0 "register_operand" "")
10603         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10604   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10605   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10606
10607 (define_insn "*absneg<mode>2_mixed"
10608   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10609         (match_operator:MODEF 3 "absneg_operator"
10610           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10611    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10612    (clobber (reg:CC FLAGS_REG))]
10613   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10614   "#")
10615
10616 (define_insn "*absneg<mode>2_sse"
10617   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10618         (match_operator:MODEF 3 "absneg_operator"
10619           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10620    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10621    (clobber (reg:CC FLAGS_REG))]
10622   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10623   "#")
10624
10625 (define_insn "*absneg<mode>2_i387"
10626   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10627         (match_operator:X87MODEF 3 "absneg_operator"
10628           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10629    (use (match_operand 2 "" ""))
10630    (clobber (reg:CC FLAGS_REG))]
10631   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10632   "#")
10633
10634 (define_expand "<code>tf2"
10635   [(set (match_operand:TF 0 "register_operand" "")
10636         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10637   "TARGET_SSE2"
10638   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10639
10640 (define_insn "*absnegtf2_sse"
10641   [(set (match_operand:TF 0 "register_operand" "=x,x")
10642         (match_operator:TF 3 "absneg_operator"
10643           [(match_operand:TF 1 "register_operand" "0,x")]))
10644    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10645    (clobber (reg:CC FLAGS_REG))]
10646   "TARGET_SSE2"
10647   "#")
10648
10649 ;; Splitters for fp abs and neg.
10650
10651 (define_split
10652   [(set (match_operand 0 "fp_register_operand" "")
10653         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10654    (use (match_operand 2 "" ""))
10655    (clobber (reg:CC FLAGS_REG))]
10656   "reload_completed"
10657   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10658
10659 (define_split
10660   [(set (match_operand 0 "register_operand" "")
10661         (match_operator 3 "absneg_operator"
10662           [(match_operand 1 "register_operand" "")]))
10663    (use (match_operand 2 "nonimmediate_operand" ""))
10664    (clobber (reg:CC FLAGS_REG))]
10665   "reload_completed && SSE_REG_P (operands[0])"
10666   [(set (match_dup 0) (match_dup 3))]
10667 {
10668   enum machine_mode mode = GET_MODE (operands[0]);
10669   enum machine_mode vmode = GET_MODE (operands[2]);
10670   rtx tmp;
10671
10672   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10673   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10674   if (operands_match_p (operands[0], operands[2]))
10675     {
10676       tmp = operands[1];
10677       operands[1] = operands[2];
10678       operands[2] = tmp;
10679     }
10680   if (GET_CODE (operands[3]) == ABS)
10681     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10682   else
10683     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10684   operands[3] = tmp;
10685 })
10686
10687 (define_split
10688   [(set (match_operand:SF 0 "register_operand" "")
10689         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10690    (use (match_operand:V4SF 2 "" ""))
10691    (clobber (reg:CC FLAGS_REG))]
10692   "reload_completed"
10693   [(parallel [(set (match_dup 0) (match_dup 1))
10694               (clobber (reg:CC FLAGS_REG))])]
10695 {
10696   rtx tmp;
10697   operands[0] = gen_lowpart (SImode, operands[0]);
10698   if (GET_CODE (operands[1]) == ABS)
10699     {
10700       tmp = gen_int_mode (0x7fffffff, SImode);
10701       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10702     }
10703   else
10704     {
10705       tmp = gen_int_mode (0x80000000, SImode);
10706       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10707     }
10708   operands[1] = tmp;
10709 })
10710
10711 (define_split
10712   [(set (match_operand:DF 0 "register_operand" "")
10713         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10714    (use (match_operand 2 "" ""))
10715    (clobber (reg:CC FLAGS_REG))]
10716   "reload_completed"
10717   [(parallel [(set (match_dup 0) (match_dup 1))
10718               (clobber (reg:CC FLAGS_REG))])]
10719 {
10720   rtx tmp;
10721   if (TARGET_64BIT)
10722     {
10723       tmp = gen_lowpart (DImode, operands[0]);
10724       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10725       operands[0] = tmp;
10726
10727       if (GET_CODE (operands[1]) == ABS)
10728         tmp = const0_rtx;
10729       else
10730         tmp = gen_rtx_NOT (DImode, tmp);
10731     }
10732   else
10733     {
10734       operands[0] = gen_highpart (SImode, operands[0]);
10735       if (GET_CODE (operands[1]) == ABS)
10736         {
10737           tmp = gen_int_mode (0x7fffffff, SImode);
10738           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10739         }
10740       else
10741         {
10742           tmp = gen_int_mode (0x80000000, SImode);
10743           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10744         }
10745     }
10746   operands[1] = tmp;
10747 })
10748
10749 (define_split
10750   [(set (match_operand:XF 0 "register_operand" "")
10751         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10752    (use (match_operand 2 "" ""))
10753    (clobber (reg:CC FLAGS_REG))]
10754   "reload_completed"
10755   [(parallel [(set (match_dup 0) (match_dup 1))
10756               (clobber (reg:CC FLAGS_REG))])]
10757 {
10758   rtx tmp;
10759   operands[0] = gen_rtx_REG (SImode,
10760                              true_regnum (operands[0])
10761                              + (TARGET_64BIT ? 1 : 2));
10762   if (GET_CODE (operands[1]) == ABS)
10763     {
10764       tmp = GEN_INT (0x7fff);
10765       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10766     }
10767   else
10768     {
10769       tmp = GEN_INT (0x8000);
10770       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10771     }
10772   operands[1] = tmp;
10773 })
10774
10775 ;; Conditionalize these after reload. If they match before reload, we
10776 ;; lose the clobber and ability to use integer instructions.
10777
10778 (define_insn "*<code><mode>2_1"
10779   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10780         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10781   "TARGET_80387
10782    && (reload_completed
10783        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10784   "f<absnegprefix>"
10785   [(set_attr "type" "fsgn")
10786    (set_attr "mode" "<MODE>")])
10787
10788 (define_insn "*<code>extendsfdf2"
10789   [(set (match_operand:DF 0 "register_operand" "=f")
10790         (absneg:DF (float_extend:DF
10791                      (match_operand:SF 1 "register_operand" "0"))))]
10792   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10793   "f<absnegprefix>"
10794   [(set_attr "type" "fsgn")
10795    (set_attr "mode" "DF")])
10796
10797 (define_insn "*<code>extendsfxf2"
10798   [(set (match_operand:XF 0 "register_operand" "=f")
10799         (absneg:XF (float_extend:XF
10800                      (match_operand:SF 1 "register_operand" "0"))))]
10801   "TARGET_80387"
10802   "f<absnegprefix>"
10803   [(set_attr "type" "fsgn")
10804    (set_attr "mode" "XF")])
10805
10806 (define_insn "*<code>extenddfxf2"
10807   [(set (match_operand:XF 0 "register_operand" "=f")
10808         (absneg:XF (float_extend:XF
10809                       (match_operand:DF 1 "register_operand" "0"))))]
10810   "TARGET_80387"
10811   "f<absnegprefix>"
10812   [(set_attr "type" "fsgn")
10813    (set_attr "mode" "XF")])
10814
10815 ;; Copysign instructions
10816
10817 (define_mode_iterator CSGNMODE [SF DF TF])
10818 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10819
10820 (define_expand "copysign<mode>3"
10821   [(match_operand:CSGNMODE 0 "register_operand" "")
10822    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10823    (match_operand:CSGNMODE 2 "register_operand" "")]
10824   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10825    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10826 {
10827   ix86_expand_copysign (operands);
10828   DONE;
10829 })
10830
10831 (define_insn_and_split "copysign<mode>3_const"
10832   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10833         (unspec:CSGNMODE
10834           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10835            (match_operand:CSGNMODE 2 "register_operand" "0")
10836            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10837           UNSPEC_COPYSIGN))]
10838   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10839    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10840   "#"
10841   "&& reload_completed"
10842   [(const_int 0)]
10843 {
10844   ix86_split_copysign_const (operands);
10845   DONE;
10846 })
10847
10848 (define_insn "copysign<mode>3_var"
10849   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10850         (unspec:CSGNMODE
10851           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10852            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10853            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10854            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10855           UNSPEC_COPYSIGN))
10856    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10857   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10858    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10859   "#")
10860
10861 (define_split
10862   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10863         (unspec:CSGNMODE
10864           [(match_operand:CSGNMODE 2 "register_operand" "")
10865            (match_operand:CSGNMODE 3 "register_operand" "")
10866            (match_operand:<CSGNVMODE> 4 "" "")
10867            (match_operand:<CSGNVMODE> 5 "" "")]
10868           UNSPEC_COPYSIGN))
10869    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10870   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10871     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10872    && reload_completed"
10873   [(const_int 0)]
10874 {
10875   ix86_split_copysign_var (operands);
10876   DONE;
10877 })
10878 \f
10879 ;; One complement instructions
10880
10881 (define_expand "one_cmpldi2"
10882   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10883         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10884   "TARGET_64BIT"
10885   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10886
10887 (define_insn "*one_cmpldi2_1_rex64"
10888   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10889         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10890   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10891   "not{q}\t%0"
10892   [(set_attr "type" "negnot")
10893    (set_attr "mode" "DI")])
10894
10895 (define_insn "*one_cmpldi2_2_rex64"
10896   [(set (reg FLAGS_REG)
10897         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10898                  (const_int 0)))
10899    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10900         (not:DI (match_dup 1)))]
10901   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10902    && ix86_unary_operator_ok (NOT, DImode, operands)"
10903   "#"
10904   [(set_attr "type" "alu1")
10905    (set_attr "mode" "DI")])
10906
10907 (define_split
10908   [(set (match_operand 0 "flags_reg_operand" "")
10909         (match_operator 2 "compare_operator"
10910           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10911            (const_int 0)]))
10912    (set (match_operand:DI 1 "nonimmediate_operand" "")
10913         (not:DI (match_dup 3)))]
10914   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10915   [(parallel [(set (match_dup 0)
10916                    (match_op_dup 2
10917                      [(xor:DI (match_dup 3) (const_int -1))
10918                       (const_int 0)]))
10919               (set (match_dup 1)
10920                    (xor:DI (match_dup 3) (const_int -1)))])]
10921   "")
10922
10923 (define_expand "one_cmplsi2"
10924   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10925         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10926   ""
10927   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10928
10929 (define_insn "*one_cmplsi2_1"
10930   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10931         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10932   "ix86_unary_operator_ok (NOT, SImode, operands)"
10933   "not{l}\t%0"
10934   [(set_attr "type" "negnot")
10935    (set_attr "mode" "SI")])
10936
10937 ;; ??? Currently never generated - xor is used instead.
10938 (define_insn "*one_cmplsi2_1_zext"
10939   [(set (match_operand:DI 0 "register_operand" "=r")
10940         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10941   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10942   "not{l}\t%k0"
10943   [(set_attr "type" "negnot")
10944    (set_attr "mode" "SI")])
10945
10946 (define_insn "*one_cmplsi2_2"
10947   [(set (reg FLAGS_REG)
10948         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10949                  (const_int 0)))
10950    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10951         (not:SI (match_dup 1)))]
10952   "ix86_match_ccmode (insn, CCNOmode)
10953    && ix86_unary_operator_ok (NOT, SImode, operands)"
10954   "#"
10955   [(set_attr "type" "alu1")
10956    (set_attr "mode" "SI")])
10957
10958 (define_split
10959   [(set (match_operand 0 "flags_reg_operand" "")
10960         (match_operator 2 "compare_operator"
10961           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10962            (const_int 0)]))
10963    (set (match_operand:SI 1 "nonimmediate_operand" "")
10964         (not:SI (match_dup 3)))]
10965   "ix86_match_ccmode (insn, CCNOmode)"
10966   [(parallel [(set (match_dup 0)
10967                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10968                                     (const_int 0)]))
10969               (set (match_dup 1)
10970                    (xor:SI (match_dup 3) (const_int -1)))])]
10971   "")
10972
10973 ;; ??? Currently never generated - xor is used instead.
10974 (define_insn "*one_cmplsi2_2_zext"
10975   [(set (reg FLAGS_REG)
10976         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10977                  (const_int 0)))
10978    (set (match_operand:DI 0 "register_operand" "=r")
10979         (zero_extend:DI (not:SI (match_dup 1))))]
10980   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10981    && ix86_unary_operator_ok (NOT, SImode, operands)"
10982   "#"
10983   [(set_attr "type" "alu1")
10984    (set_attr "mode" "SI")])
10985
10986 (define_split
10987   [(set (match_operand 0 "flags_reg_operand" "")
10988         (match_operator 2 "compare_operator"
10989           [(not:SI (match_operand:SI 3 "register_operand" ""))
10990            (const_int 0)]))
10991    (set (match_operand:DI 1 "register_operand" "")
10992         (zero_extend:DI (not:SI (match_dup 3))))]
10993   "ix86_match_ccmode (insn, CCNOmode)"
10994   [(parallel [(set (match_dup 0)
10995                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10996                                     (const_int 0)]))
10997               (set (match_dup 1)
10998                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10999   "")
11000
11001 (define_expand "one_cmplhi2"
11002   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11003         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11004   "TARGET_HIMODE_MATH"
11005   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11006
11007 (define_insn "*one_cmplhi2_1"
11008   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11009         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11010   "ix86_unary_operator_ok (NOT, HImode, operands)"
11011   "not{w}\t%0"
11012   [(set_attr "type" "negnot")
11013    (set_attr "mode" "HI")])
11014
11015 (define_insn "*one_cmplhi2_2"
11016   [(set (reg FLAGS_REG)
11017         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11018                  (const_int 0)))
11019    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11020         (not:HI (match_dup 1)))]
11021   "ix86_match_ccmode (insn, CCNOmode)
11022    && ix86_unary_operator_ok (NEG, HImode, operands)"
11023   "#"
11024   [(set_attr "type" "alu1")
11025    (set_attr "mode" "HI")])
11026
11027 (define_split
11028   [(set (match_operand 0 "flags_reg_operand" "")
11029         (match_operator 2 "compare_operator"
11030           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11031            (const_int 0)]))
11032    (set (match_operand:HI 1 "nonimmediate_operand" "")
11033         (not:HI (match_dup 3)))]
11034   "ix86_match_ccmode (insn, CCNOmode)"
11035   [(parallel [(set (match_dup 0)
11036                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11037                                     (const_int 0)]))
11038               (set (match_dup 1)
11039                    (xor:HI (match_dup 3) (const_int -1)))])]
11040   "")
11041
11042 ;; %%% Potential partial reg stall on alternative 1.  What to do?
11043 (define_expand "one_cmplqi2"
11044   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11045         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11046   "TARGET_QIMODE_MATH"
11047   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11048
11049 (define_insn "*one_cmplqi2_1"
11050   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11051         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11052   "ix86_unary_operator_ok (NOT, QImode, operands)"
11053   "@
11054    not{b}\t%0
11055    not{l}\t%k0"
11056   [(set_attr "type" "negnot")
11057    (set_attr "mode" "QI,SI")])
11058
11059 (define_insn "*one_cmplqi2_2"
11060   [(set (reg FLAGS_REG)
11061         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11062                  (const_int 0)))
11063    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11064         (not:QI (match_dup 1)))]
11065   "ix86_match_ccmode (insn, CCNOmode)
11066    && ix86_unary_operator_ok (NOT, QImode, operands)"
11067   "#"
11068   [(set_attr "type" "alu1")
11069    (set_attr "mode" "QI")])
11070
11071 (define_split
11072   [(set (match_operand 0 "flags_reg_operand" "")
11073         (match_operator 2 "compare_operator"
11074           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11075            (const_int 0)]))
11076    (set (match_operand:QI 1 "nonimmediate_operand" "")
11077         (not:QI (match_dup 3)))]
11078   "ix86_match_ccmode (insn, CCNOmode)"
11079   [(parallel [(set (match_dup 0)
11080                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11081                                     (const_int 0)]))
11082               (set (match_dup 1)
11083                    (xor:QI (match_dup 3) (const_int -1)))])]
11084   "")
11085 \f
11086 ;; Arithmetic shift instructions
11087
11088 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11089 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11090 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11091 ;; from the assembler input.
11092 ;;
11093 ;; This instruction shifts the target reg/mem as usual, but instead of
11094 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11095 ;; is a left shift double, bits are taken from the high order bits of
11096 ;; reg, else if the insn is a shift right double, bits are taken from the
11097 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11098 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11099 ;;
11100 ;; Since sh[lr]d does not change the `reg' operand, that is done
11101 ;; separately, making all shifts emit pairs of shift double and normal
11102 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11103 ;; support a 63 bit shift, each shift where the count is in a reg expands
11104 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11105 ;;
11106 ;; If the shift count is a constant, we need never emit more than one
11107 ;; shift pair, instead using moves and sign extension for counts greater
11108 ;; than 31.
11109
11110 (define_expand "ashlti3"
11111   [(set (match_operand:TI 0 "register_operand" "")
11112         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11113                    (match_operand:QI 2 "nonmemory_operand" "")))]
11114   "TARGET_64BIT"
11115   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11116
11117 ;; This pattern must be defined before *ashlti3_1 to prevent
11118 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11119
11120 (define_insn "*avx_ashlti3"
11121   [(set (match_operand:TI 0 "register_operand" "=x")
11122         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11123                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11124   "TARGET_AVX"
11125 {
11126   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11127   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11128 }
11129   [(set_attr "type" "sseishft")
11130    (set_attr "prefix" "vex")
11131    (set_attr "mode" "TI")])
11132
11133 (define_insn "sse2_ashlti3"
11134   [(set (match_operand:TI 0 "register_operand" "=x")
11135         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11136                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11137   "TARGET_SSE2"
11138 {
11139   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11140   return "pslldq\t{%2, %0|%0, %2}";
11141 }
11142   [(set_attr "type" "sseishft")
11143    (set_attr "prefix_data16" "1")
11144    (set_attr "mode" "TI")])
11145
11146 (define_insn "*ashlti3_1"
11147   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11148         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11149                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11150    (clobber (reg:CC FLAGS_REG))]
11151   "TARGET_64BIT"
11152   "#"
11153   [(set_attr "type" "multi")])
11154
11155 (define_peephole2
11156   [(match_scratch:DI 3 "r")
11157    (parallel [(set (match_operand:TI 0 "register_operand" "")
11158                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11159                               (match_operand:QI 2 "nonmemory_operand" "")))
11160               (clobber (reg:CC FLAGS_REG))])
11161    (match_dup 3)]
11162   "TARGET_64BIT"
11163   [(const_int 0)]
11164   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11165
11166 (define_split
11167   [(set (match_operand:TI 0 "register_operand" "")
11168         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11169                    (match_operand:QI 2 "nonmemory_operand" "")))
11170    (clobber (reg:CC FLAGS_REG))]
11171   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11172                     ? epilogue_completed : reload_completed)"
11173   [(const_int 0)]
11174   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11175
11176 (define_insn "x86_64_shld"
11177   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11178         (ior:DI (ashift:DI (match_dup 0)
11179                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11180                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11181                   (minus:QI (const_int 64) (match_dup 2)))))
11182    (clobber (reg:CC FLAGS_REG))]
11183   "TARGET_64BIT"
11184   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11185   [(set_attr "type" "ishift")
11186    (set_attr "prefix_0f" "1")
11187    (set_attr "mode" "DI")
11188    (set_attr "athlon_decode" "vector")
11189    (set_attr "amdfam10_decode" "vector")])
11190
11191 (define_expand "x86_64_shift_adj_1"
11192   [(set (reg:CCZ FLAGS_REG)
11193         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11194                              (const_int 64))
11195                      (const_int 0)))
11196    (set (match_operand:DI 0 "register_operand" "")
11197         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11198                          (match_operand:DI 1 "register_operand" "")
11199                          (match_dup 0)))
11200    (set (match_dup 1)
11201         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11202                          (match_operand:DI 3 "register_operand" "r")
11203                          (match_dup 1)))]
11204   "TARGET_64BIT"
11205   "")
11206
11207 (define_expand "x86_64_shift_adj_2"
11208   [(use (match_operand:DI 0 "register_operand" ""))
11209    (use (match_operand:DI 1 "register_operand" ""))
11210    (use (match_operand:QI 2 "register_operand" ""))]
11211   "TARGET_64BIT"
11212 {
11213   rtx label = gen_label_rtx ();
11214   rtx tmp;
11215
11216   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11217
11218   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11219   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11220   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11221                               gen_rtx_LABEL_REF (VOIDmode, label),
11222                               pc_rtx);
11223   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11224   JUMP_LABEL (tmp) = label;
11225
11226   emit_move_insn (operands[0], operands[1]);
11227   ix86_expand_clear (operands[1]);
11228
11229   emit_label (label);
11230   LABEL_NUSES (label) = 1;
11231
11232   DONE;
11233 })
11234
11235 (define_expand "ashldi3"
11236   [(set (match_operand:DI 0 "shiftdi_operand" "")
11237         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11238                    (match_operand:QI 2 "nonmemory_operand" "")))]
11239   ""
11240   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11241
11242 (define_insn "*ashldi3_1_rex64"
11243   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11244         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11245                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11246    (clobber (reg:CC FLAGS_REG))]
11247   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11248 {
11249   switch (get_attr_type (insn))
11250     {
11251     case TYPE_ALU:
11252       gcc_assert (operands[2] == const1_rtx);
11253       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11254       return "add{q}\t%0, %0";
11255
11256     case TYPE_LEA:
11257       gcc_assert (CONST_INT_P (operands[2]));
11258       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11259       operands[1] = gen_rtx_MULT (DImode, operands[1],
11260                                   GEN_INT (1 << INTVAL (operands[2])));
11261       return "lea{q}\t{%a1, %0|%0, %a1}";
11262
11263     default:
11264       if (REG_P (operands[2]))
11265         return "sal{q}\t{%b2, %0|%0, %b2}";
11266       else if (operands[2] == const1_rtx
11267                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11268         return "sal{q}\t%0";
11269       else
11270         return "sal{q}\t{%2, %0|%0, %2}";
11271     }
11272 }
11273   [(set (attr "type")
11274      (cond [(eq_attr "alternative" "1")
11275               (const_string "lea")
11276             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11277                           (const_int 0))
11278                       (match_operand 0 "register_operand" ""))
11279                  (match_operand 2 "const1_operand" ""))
11280               (const_string "alu")
11281            ]
11282            (const_string "ishift")))
11283    (set_attr "mode" "DI")])
11284
11285 ;; Convert lea to the lea pattern to avoid flags dependency.
11286 (define_split
11287   [(set (match_operand:DI 0 "register_operand" "")
11288         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11289                    (match_operand:QI 2 "immediate_operand" "")))
11290    (clobber (reg:CC FLAGS_REG))]
11291   "TARGET_64BIT && reload_completed
11292    && true_regnum (operands[0]) != true_regnum (operands[1])"
11293   [(set (match_dup 0)
11294         (mult:DI (match_dup 1)
11295                  (match_dup 2)))]
11296   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11297
11298 ;; This pattern can't accept a variable shift count, since shifts by
11299 ;; zero don't affect the flags.  We assume that shifts by constant
11300 ;; zero are optimized away.
11301 (define_insn "*ashldi3_cmp_rex64"
11302   [(set (reg FLAGS_REG)
11303         (compare
11304           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11305                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11306           (const_int 0)))
11307    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11308         (ashift:DI (match_dup 1) (match_dup 2)))]
11309   "TARGET_64BIT
11310    && (optimize_function_for_size_p (cfun)
11311        || !TARGET_PARTIAL_FLAG_REG_STALL
11312        || (operands[2] == const1_rtx
11313            && (TARGET_SHIFT1
11314                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11315    && ix86_match_ccmode (insn, CCGOCmode)
11316    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11317 {
11318   switch (get_attr_type (insn))
11319     {
11320     case TYPE_ALU:
11321       gcc_assert (operands[2] == const1_rtx);
11322       return "add{q}\t%0, %0";
11323
11324     default:
11325       if (REG_P (operands[2]))
11326         return "sal{q}\t{%b2, %0|%0, %b2}";
11327       else if (operands[2] == const1_rtx
11328                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11329         return "sal{q}\t%0";
11330       else
11331         return "sal{q}\t{%2, %0|%0, %2}";
11332     }
11333 }
11334   [(set (attr "type")
11335      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11336                           (const_int 0))
11337                       (match_operand 0 "register_operand" ""))
11338                  (match_operand 2 "const1_operand" ""))
11339               (const_string "alu")
11340            ]
11341            (const_string "ishift")))
11342    (set_attr "mode" "DI")])
11343
11344 (define_insn "*ashldi3_cconly_rex64"
11345   [(set (reg FLAGS_REG)
11346         (compare
11347           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11348                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11349           (const_int 0)))
11350    (clobber (match_scratch:DI 0 "=r"))]
11351   "TARGET_64BIT
11352    && (optimize_function_for_size_p (cfun)
11353        || !TARGET_PARTIAL_FLAG_REG_STALL
11354        || (operands[2] == const1_rtx
11355            && (TARGET_SHIFT1
11356                || TARGET_DOUBLE_WITH_ADD)))
11357    && ix86_match_ccmode (insn, CCGOCmode)
11358    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11359 {
11360   switch (get_attr_type (insn))
11361     {
11362     case TYPE_ALU:
11363       gcc_assert (operands[2] == const1_rtx);
11364       return "add{q}\t%0, %0";
11365
11366     default:
11367       if (REG_P (operands[2]))
11368         return "sal{q}\t{%b2, %0|%0, %b2}";
11369       else if (operands[2] == const1_rtx
11370                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11371         return "sal{q}\t%0";
11372       else
11373         return "sal{q}\t{%2, %0|%0, %2}";
11374     }
11375 }
11376   [(set (attr "type")
11377      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11378                           (const_int 0))
11379                       (match_operand 0 "register_operand" ""))
11380                  (match_operand 2 "const1_operand" ""))
11381               (const_string "alu")
11382            ]
11383            (const_string "ishift")))
11384    (set_attr "mode" "DI")])
11385
11386 (define_insn "*ashldi3_1"
11387   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11388         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11389                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11390    (clobber (reg:CC FLAGS_REG))]
11391   "!TARGET_64BIT"
11392   "#"
11393   [(set_attr "type" "multi")])
11394
11395 ;; By default we don't ask for a scratch register, because when DImode
11396 ;; values are manipulated, registers are already at a premium.  But if
11397 ;; we have one handy, we won't turn it away.
11398 (define_peephole2
11399   [(match_scratch:SI 3 "r")
11400    (parallel [(set (match_operand:DI 0 "register_operand" "")
11401                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11402                               (match_operand:QI 2 "nonmemory_operand" "")))
11403               (clobber (reg:CC FLAGS_REG))])
11404    (match_dup 3)]
11405   "!TARGET_64BIT && TARGET_CMOVE"
11406   [(const_int 0)]
11407   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11408
11409 (define_split
11410   [(set (match_operand:DI 0 "register_operand" "")
11411         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11412                    (match_operand:QI 2 "nonmemory_operand" "")))
11413    (clobber (reg:CC FLAGS_REG))]
11414   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11415                      ? epilogue_completed : reload_completed)"
11416   [(const_int 0)]
11417   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11418
11419 (define_insn "x86_shld"
11420   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11421         (ior:SI (ashift:SI (match_dup 0)
11422                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11423                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11424                   (minus:QI (const_int 32) (match_dup 2)))))
11425    (clobber (reg:CC FLAGS_REG))]
11426   ""
11427   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11428   [(set_attr "type" "ishift")
11429    (set_attr "prefix_0f" "1")
11430    (set_attr "mode" "SI")
11431    (set_attr "pent_pair" "np")
11432    (set_attr "athlon_decode" "vector")
11433    (set_attr "amdfam10_decode" "vector")])
11434
11435 (define_expand "x86_shift_adj_1"
11436   [(set (reg:CCZ FLAGS_REG)
11437         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11438                              (const_int 32))
11439                      (const_int 0)))
11440    (set (match_operand:SI 0 "register_operand" "")
11441         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11442                          (match_operand:SI 1 "register_operand" "")
11443                          (match_dup 0)))
11444    (set (match_dup 1)
11445         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11446                          (match_operand:SI 3 "register_operand" "r")
11447                          (match_dup 1)))]
11448   "TARGET_CMOVE"
11449   "")
11450
11451 (define_expand "x86_shift_adj_2"
11452   [(use (match_operand:SI 0 "register_operand" ""))
11453    (use (match_operand:SI 1 "register_operand" ""))
11454    (use (match_operand:QI 2 "register_operand" ""))]
11455   ""
11456 {
11457   rtx label = gen_label_rtx ();
11458   rtx tmp;
11459
11460   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11461
11462   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11463   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11464   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11465                               gen_rtx_LABEL_REF (VOIDmode, label),
11466                               pc_rtx);
11467   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11468   JUMP_LABEL (tmp) = label;
11469
11470   emit_move_insn (operands[0], operands[1]);
11471   ix86_expand_clear (operands[1]);
11472
11473   emit_label (label);
11474   LABEL_NUSES (label) = 1;
11475
11476   DONE;
11477 })
11478
11479 (define_expand "ashlsi3"
11480   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11481         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11482                    (match_operand:QI 2 "nonmemory_operand" "")))]
11483   ""
11484   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11485
11486 (define_insn "*ashlsi3_1"
11487   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11488         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11489                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11490    (clobber (reg:CC FLAGS_REG))]
11491   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11492 {
11493   switch (get_attr_type (insn))
11494     {
11495     case TYPE_ALU:
11496       gcc_assert (operands[2] == const1_rtx);
11497       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11498       return "add{l}\t%0, %0";
11499
11500     case TYPE_LEA:
11501       return "#";
11502
11503     default:
11504       if (REG_P (operands[2]))
11505         return "sal{l}\t{%b2, %0|%0, %b2}";
11506       else if (operands[2] == const1_rtx
11507                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11508         return "sal{l}\t%0";
11509       else
11510         return "sal{l}\t{%2, %0|%0, %2}";
11511     }
11512 }
11513   [(set (attr "type")
11514      (cond [(eq_attr "alternative" "1")
11515               (const_string "lea")
11516             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11517                           (const_int 0))
11518                       (match_operand 0 "register_operand" ""))
11519                  (match_operand 2 "const1_operand" ""))
11520               (const_string "alu")
11521            ]
11522            (const_string "ishift")))
11523    (set_attr "mode" "SI")])
11524
11525 ;; Convert lea to the lea pattern to avoid flags dependency.
11526 (define_split
11527   [(set (match_operand 0 "register_operand" "")
11528         (ashift (match_operand 1 "index_register_operand" "")
11529                 (match_operand:QI 2 "const_int_operand" "")))
11530    (clobber (reg:CC FLAGS_REG))]
11531   "reload_completed
11532    && true_regnum (operands[0]) != true_regnum (operands[1])
11533    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11534   [(const_int 0)]
11535 {
11536   rtx pat;
11537   enum machine_mode mode = GET_MODE (operands[0]);
11538
11539   if (GET_MODE_SIZE (mode) < 4)
11540     operands[0] = gen_lowpart (SImode, operands[0]);
11541   if (mode != Pmode)
11542     operands[1] = gen_lowpart (Pmode, operands[1]);
11543   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11544
11545   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11546   if (Pmode != SImode)
11547     pat = gen_rtx_SUBREG (SImode, pat, 0);
11548   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11549   DONE;
11550 })
11551
11552 ;; Rare case of shifting RSP is handled by generating move and shift
11553 (define_split
11554   [(set (match_operand 0 "register_operand" "")
11555         (ashift (match_operand 1 "register_operand" "")
11556                 (match_operand:QI 2 "const_int_operand" "")))
11557    (clobber (reg:CC FLAGS_REG))]
11558   "reload_completed
11559    && true_regnum (operands[0]) != true_regnum (operands[1])"
11560   [(const_int 0)]
11561 {
11562   rtx pat, clob;
11563   emit_move_insn (operands[0], operands[1]);
11564   pat = gen_rtx_SET (VOIDmode, operands[0],
11565                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11566                                      operands[0], operands[2]));
11567   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11568   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11569   DONE;
11570 })
11571
11572 (define_insn "*ashlsi3_1_zext"
11573   [(set (match_operand:DI 0 "register_operand" "=r,r")
11574         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11575                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11576    (clobber (reg:CC FLAGS_REG))]
11577   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11578 {
11579   switch (get_attr_type (insn))
11580     {
11581     case TYPE_ALU:
11582       gcc_assert (operands[2] == const1_rtx);
11583       return "add{l}\t%k0, %k0";
11584
11585     case TYPE_LEA:
11586       return "#";
11587
11588     default:
11589       if (REG_P (operands[2]))
11590         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11591       else if (operands[2] == const1_rtx
11592                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11593         return "sal{l}\t%k0";
11594       else
11595         return "sal{l}\t{%2, %k0|%k0, %2}";
11596     }
11597 }
11598   [(set (attr "type")
11599      (cond [(eq_attr "alternative" "1")
11600               (const_string "lea")
11601             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11602                      (const_int 0))
11603                  (match_operand 2 "const1_operand" ""))
11604               (const_string "alu")
11605            ]
11606            (const_string "ishift")))
11607    (set_attr "mode" "SI")])
11608
11609 ;; Convert lea to the lea pattern to avoid flags dependency.
11610 (define_split
11611   [(set (match_operand:DI 0 "register_operand" "")
11612         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11613                                 (match_operand:QI 2 "const_int_operand" ""))))
11614    (clobber (reg:CC FLAGS_REG))]
11615   "TARGET_64BIT && reload_completed
11616    && true_regnum (operands[0]) != true_regnum (operands[1])"
11617   [(set (match_dup 0) (zero_extend:DI
11618                         (subreg:SI (mult:SI (match_dup 1)
11619                                             (match_dup 2)) 0)))]
11620 {
11621   operands[1] = gen_lowpart (Pmode, operands[1]);
11622   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11623 })
11624
11625 ;; This pattern can't accept a variable shift count, since shifts by
11626 ;; zero don't affect the flags.  We assume that shifts by constant
11627 ;; zero are optimized away.
11628 (define_insn "*ashlsi3_cmp"
11629   [(set (reg FLAGS_REG)
11630         (compare
11631           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11632                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11633           (const_int 0)))
11634    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11635         (ashift:SI (match_dup 1) (match_dup 2)))]
11636    "(optimize_function_for_size_p (cfun)
11637      || !TARGET_PARTIAL_FLAG_REG_STALL
11638      || (operands[2] == const1_rtx
11639          && (TARGET_SHIFT1
11640              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11641    && ix86_match_ccmode (insn, CCGOCmode)
11642    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11643 {
11644   switch (get_attr_type (insn))
11645     {
11646     case TYPE_ALU:
11647       gcc_assert (operands[2] == const1_rtx);
11648       return "add{l}\t%0, %0";
11649
11650     default:
11651       if (REG_P (operands[2]))
11652         return "sal{l}\t{%b2, %0|%0, %b2}";
11653       else if (operands[2] == const1_rtx
11654                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11655         return "sal{l}\t%0";
11656       else
11657         return "sal{l}\t{%2, %0|%0, %2}";
11658     }
11659 }
11660   [(set (attr "type")
11661      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11662                           (const_int 0))
11663                       (match_operand 0 "register_operand" ""))
11664                  (match_operand 2 "const1_operand" ""))
11665               (const_string "alu")
11666            ]
11667            (const_string "ishift")))
11668    (set_attr "mode" "SI")])
11669
11670 (define_insn "*ashlsi3_cconly"
11671   [(set (reg FLAGS_REG)
11672         (compare
11673           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11674                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11675           (const_int 0)))
11676    (clobber (match_scratch:SI 0 "=r"))]
11677   "(optimize_function_for_size_p (cfun)
11678     || !TARGET_PARTIAL_FLAG_REG_STALL
11679     || (operands[2] == const1_rtx
11680         && (TARGET_SHIFT1
11681             || TARGET_DOUBLE_WITH_ADD)))
11682    && ix86_match_ccmode (insn, CCGOCmode)
11683    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11684 {
11685   switch (get_attr_type (insn))
11686     {
11687     case TYPE_ALU:
11688       gcc_assert (operands[2] == const1_rtx);
11689       return "add{l}\t%0, %0";
11690
11691     default:
11692       if (REG_P (operands[2]))
11693         return "sal{l}\t{%b2, %0|%0, %b2}";
11694       else if (operands[2] == const1_rtx
11695                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11696         return "sal{l}\t%0";
11697       else
11698         return "sal{l}\t{%2, %0|%0, %2}";
11699     }
11700 }
11701   [(set (attr "type")
11702      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11703                           (const_int 0))
11704                       (match_operand 0 "register_operand" ""))
11705                  (match_operand 2 "const1_operand" ""))
11706               (const_string "alu")
11707            ]
11708            (const_string "ishift")))
11709    (set_attr "mode" "SI")])
11710
11711 (define_insn "*ashlsi3_cmp_zext"
11712   [(set (reg FLAGS_REG)
11713         (compare
11714           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11715                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11716           (const_int 0)))
11717    (set (match_operand:DI 0 "register_operand" "=r")
11718         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11719   "TARGET_64BIT
11720    && (optimize_function_for_size_p (cfun)
11721        || !TARGET_PARTIAL_FLAG_REG_STALL
11722        || (operands[2] == const1_rtx
11723            && (TARGET_SHIFT1
11724                || TARGET_DOUBLE_WITH_ADD)))
11725    && ix86_match_ccmode (insn, CCGOCmode)
11726    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11727 {
11728   switch (get_attr_type (insn))
11729     {
11730     case TYPE_ALU:
11731       gcc_assert (operands[2] == const1_rtx);
11732       return "add{l}\t%k0, %k0";
11733
11734     default:
11735       if (REG_P (operands[2]))
11736         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11737       else if (operands[2] == const1_rtx
11738                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11739         return "sal{l}\t%k0";
11740       else
11741         return "sal{l}\t{%2, %k0|%k0, %2}";
11742     }
11743 }
11744   [(set (attr "type")
11745      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11746                      (const_int 0))
11747                  (match_operand 2 "const1_operand" ""))
11748               (const_string "alu")
11749            ]
11750            (const_string "ishift")))
11751    (set_attr "mode" "SI")])
11752
11753 (define_expand "ashlhi3"
11754   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11755         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11756                    (match_operand:QI 2 "nonmemory_operand" "")))]
11757   "TARGET_HIMODE_MATH"
11758   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11759
11760 (define_insn "*ashlhi3_1_lea"
11761   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11762         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11763                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11764    (clobber (reg:CC FLAGS_REG))]
11765   "!TARGET_PARTIAL_REG_STALL
11766    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11767 {
11768   switch (get_attr_type (insn))
11769     {
11770     case TYPE_LEA:
11771       return "#";
11772     case TYPE_ALU:
11773       gcc_assert (operands[2] == const1_rtx);
11774       return "add{w}\t%0, %0";
11775
11776     default:
11777       if (REG_P (operands[2]))
11778         return "sal{w}\t{%b2, %0|%0, %b2}";
11779       else if (operands[2] == const1_rtx
11780                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11781         return "sal{w}\t%0";
11782       else
11783         return "sal{w}\t{%2, %0|%0, %2}";
11784     }
11785 }
11786   [(set (attr "type")
11787      (cond [(eq_attr "alternative" "1")
11788               (const_string "lea")
11789             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11790                           (const_int 0))
11791                       (match_operand 0 "register_operand" ""))
11792                  (match_operand 2 "const1_operand" ""))
11793               (const_string "alu")
11794            ]
11795            (const_string "ishift")))
11796    (set_attr "mode" "HI,SI")])
11797
11798 (define_insn "*ashlhi3_1"
11799   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11800         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11801                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11802    (clobber (reg:CC FLAGS_REG))]
11803   "TARGET_PARTIAL_REG_STALL
11804    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11805 {
11806   switch (get_attr_type (insn))
11807     {
11808     case TYPE_ALU:
11809       gcc_assert (operands[2] == const1_rtx);
11810       return "add{w}\t%0, %0";
11811
11812     default:
11813       if (REG_P (operands[2]))
11814         return "sal{w}\t{%b2, %0|%0, %b2}";
11815       else if (operands[2] == const1_rtx
11816                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11817         return "sal{w}\t%0";
11818       else
11819         return "sal{w}\t{%2, %0|%0, %2}";
11820     }
11821 }
11822   [(set (attr "type")
11823      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11824                           (const_int 0))
11825                       (match_operand 0 "register_operand" ""))
11826                  (match_operand 2 "const1_operand" ""))
11827               (const_string "alu")
11828            ]
11829            (const_string "ishift")))
11830    (set_attr "mode" "HI")])
11831
11832 ;; This pattern can't accept a variable shift count, since shifts by
11833 ;; zero don't affect the flags.  We assume that shifts by constant
11834 ;; zero are optimized away.
11835 (define_insn "*ashlhi3_cmp"
11836   [(set (reg FLAGS_REG)
11837         (compare
11838           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11839                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11840           (const_int 0)))
11841    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11842         (ashift:HI (match_dup 1) (match_dup 2)))]
11843   "(optimize_function_for_size_p (cfun)
11844     || !TARGET_PARTIAL_FLAG_REG_STALL
11845     || (operands[2] == const1_rtx
11846         && (TARGET_SHIFT1
11847             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11848    && ix86_match_ccmode (insn, CCGOCmode)
11849    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11850 {
11851   switch (get_attr_type (insn))
11852     {
11853     case TYPE_ALU:
11854       gcc_assert (operands[2] == const1_rtx);
11855       return "add{w}\t%0, %0";
11856
11857     default:
11858       if (REG_P (operands[2]))
11859         return "sal{w}\t{%b2, %0|%0, %b2}";
11860       else if (operands[2] == const1_rtx
11861                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11862         return "sal{w}\t%0";
11863       else
11864         return "sal{w}\t{%2, %0|%0, %2}";
11865     }
11866 }
11867   [(set (attr "type")
11868      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11869                           (const_int 0))
11870                       (match_operand 0 "register_operand" ""))
11871                  (match_operand 2 "const1_operand" ""))
11872               (const_string "alu")
11873            ]
11874            (const_string "ishift")))
11875    (set_attr "mode" "HI")])
11876
11877 (define_insn "*ashlhi3_cconly"
11878   [(set (reg FLAGS_REG)
11879         (compare
11880           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11881                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11882           (const_int 0)))
11883    (clobber (match_scratch:HI 0 "=r"))]
11884   "(optimize_function_for_size_p (cfun)
11885     || !TARGET_PARTIAL_FLAG_REG_STALL
11886     || (operands[2] == const1_rtx
11887         && (TARGET_SHIFT1
11888             || TARGET_DOUBLE_WITH_ADD)))
11889    && ix86_match_ccmode (insn, CCGOCmode)
11890    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11891 {
11892   switch (get_attr_type (insn))
11893     {
11894     case TYPE_ALU:
11895       gcc_assert (operands[2] == const1_rtx);
11896       return "add{w}\t%0, %0";
11897
11898     default:
11899       if (REG_P (operands[2]))
11900         return "sal{w}\t{%b2, %0|%0, %b2}";
11901       else if (operands[2] == const1_rtx
11902                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11903         return "sal{w}\t%0";
11904       else
11905         return "sal{w}\t{%2, %0|%0, %2}";
11906     }
11907 }
11908   [(set (attr "type")
11909      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11910                           (const_int 0))
11911                       (match_operand 0 "register_operand" ""))
11912                  (match_operand 2 "const1_operand" ""))
11913               (const_string "alu")
11914            ]
11915            (const_string "ishift")))
11916    (set_attr "mode" "HI")])
11917
11918 (define_expand "ashlqi3"
11919   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11920         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11921                    (match_operand:QI 2 "nonmemory_operand" "")))]
11922   "TARGET_QIMODE_MATH"
11923   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11924
11925 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11926
11927 (define_insn "*ashlqi3_1_lea"
11928   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11929         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11930                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11931    (clobber (reg:CC FLAGS_REG))]
11932   "!TARGET_PARTIAL_REG_STALL
11933    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11934 {
11935   switch (get_attr_type (insn))
11936     {
11937     case TYPE_LEA:
11938       return "#";
11939     case TYPE_ALU:
11940       gcc_assert (operands[2] == const1_rtx);
11941       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11942         return "add{l}\t%k0, %k0";
11943       else
11944         return "add{b}\t%0, %0";
11945
11946     default:
11947       if (REG_P (operands[2]))
11948         {
11949           if (get_attr_mode (insn) == MODE_SI)
11950             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11951           else
11952             return "sal{b}\t{%b2, %0|%0, %b2}";
11953         }
11954       else if (operands[2] == const1_rtx
11955                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11956         {
11957           if (get_attr_mode (insn) == MODE_SI)
11958             return "sal{l}\t%0";
11959           else
11960             return "sal{b}\t%0";
11961         }
11962       else
11963         {
11964           if (get_attr_mode (insn) == MODE_SI)
11965             return "sal{l}\t{%2, %k0|%k0, %2}";
11966           else
11967             return "sal{b}\t{%2, %0|%0, %2}";
11968         }
11969     }
11970 }
11971   [(set (attr "type")
11972      (cond [(eq_attr "alternative" "2")
11973               (const_string "lea")
11974             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11975                           (const_int 0))
11976                       (match_operand 0 "register_operand" ""))
11977                  (match_operand 2 "const1_operand" ""))
11978               (const_string "alu")
11979            ]
11980            (const_string "ishift")))
11981    (set_attr "mode" "QI,SI,SI")])
11982
11983 (define_insn "*ashlqi3_1"
11984   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11985         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11986                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11987    (clobber (reg:CC FLAGS_REG))]
11988   "TARGET_PARTIAL_REG_STALL
11989    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11990 {
11991   switch (get_attr_type (insn))
11992     {
11993     case TYPE_ALU:
11994       gcc_assert (operands[2] == const1_rtx);
11995       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11996         return "add{l}\t%k0, %k0";
11997       else
11998         return "add{b}\t%0, %0";
11999
12000     default:
12001       if (REG_P (operands[2]))
12002         {
12003           if (get_attr_mode (insn) == MODE_SI)
12004             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12005           else
12006             return "sal{b}\t{%b2, %0|%0, %b2}";
12007         }
12008       else if (operands[2] == const1_rtx
12009                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12010         {
12011           if (get_attr_mode (insn) == MODE_SI)
12012             return "sal{l}\t%0";
12013           else
12014             return "sal{b}\t%0";
12015         }
12016       else
12017         {
12018           if (get_attr_mode (insn) == MODE_SI)
12019             return "sal{l}\t{%2, %k0|%k0, %2}";
12020           else
12021             return "sal{b}\t{%2, %0|%0, %2}";
12022         }
12023     }
12024 }
12025   [(set (attr "type")
12026      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12027                           (const_int 0))
12028                       (match_operand 0 "register_operand" ""))
12029                  (match_operand 2 "const1_operand" ""))
12030               (const_string "alu")
12031            ]
12032            (const_string "ishift")))
12033    (set_attr "mode" "QI,SI")])
12034
12035 ;; This pattern can't accept a variable shift count, since shifts by
12036 ;; zero don't affect the flags.  We assume that shifts by constant
12037 ;; zero are optimized away.
12038 (define_insn "*ashlqi3_cmp"
12039   [(set (reg FLAGS_REG)
12040         (compare
12041           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12042                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12043           (const_int 0)))
12044    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12045         (ashift:QI (match_dup 1) (match_dup 2)))]
12046   "(optimize_function_for_size_p (cfun)
12047     || !TARGET_PARTIAL_FLAG_REG_STALL
12048     || (operands[2] == const1_rtx
12049         && (TARGET_SHIFT1
12050             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12051    && ix86_match_ccmode (insn, CCGOCmode)
12052    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12053 {
12054   switch (get_attr_type (insn))
12055     {
12056     case TYPE_ALU:
12057       gcc_assert (operands[2] == const1_rtx);
12058       return "add{b}\t%0, %0";
12059
12060     default:
12061       if (REG_P (operands[2]))
12062         return "sal{b}\t{%b2, %0|%0, %b2}";
12063       else if (operands[2] == const1_rtx
12064                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12065         return "sal{b}\t%0";
12066       else
12067         return "sal{b}\t{%2, %0|%0, %2}";
12068     }
12069 }
12070   [(set (attr "type")
12071      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12072                           (const_int 0))
12073                       (match_operand 0 "register_operand" ""))
12074                  (match_operand 2 "const1_operand" ""))
12075               (const_string "alu")
12076            ]
12077            (const_string "ishift")))
12078    (set_attr "mode" "QI")])
12079
12080 (define_insn "*ashlqi3_cconly"
12081   [(set (reg FLAGS_REG)
12082         (compare
12083           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12084                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12085           (const_int 0)))
12086    (clobber (match_scratch:QI 0 "=q"))]
12087   "(optimize_function_for_size_p (cfun)
12088     || !TARGET_PARTIAL_FLAG_REG_STALL
12089     || (operands[2] == const1_rtx
12090         && (TARGET_SHIFT1
12091             || TARGET_DOUBLE_WITH_ADD)))
12092    && ix86_match_ccmode (insn, CCGOCmode)
12093    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12094 {
12095   switch (get_attr_type (insn))
12096     {
12097     case TYPE_ALU:
12098       gcc_assert (operands[2] == const1_rtx);
12099       return "add{b}\t%0, %0";
12100
12101     default:
12102       if (REG_P (operands[2]))
12103         return "sal{b}\t{%b2, %0|%0, %b2}";
12104       else if (operands[2] == const1_rtx
12105                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12106         return "sal{b}\t%0";
12107       else
12108         return "sal{b}\t{%2, %0|%0, %2}";
12109     }
12110 }
12111   [(set (attr "type")
12112      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12113                           (const_int 0))
12114                       (match_operand 0 "register_operand" ""))
12115                  (match_operand 2 "const1_operand" ""))
12116               (const_string "alu")
12117            ]
12118            (const_string "ishift")))
12119    (set_attr "mode" "QI")])
12120
12121 ;; See comment above `ashldi3' about how this works.
12122
12123 (define_expand "ashrti3"
12124   [(set (match_operand:TI 0 "register_operand" "")
12125         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12126                      (match_operand:QI 2 "nonmemory_operand" "")))]
12127   "TARGET_64BIT"
12128   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12129
12130 (define_insn "*ashrti3_1"
12131   [(set (match_operand:TI 0 "register_operand" "=r")
12132         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12133                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "TARGET_64BIT"
12136   "#"
12137   [(set_attr "type" "multi")])
12138
12139 (define_peephole2
12140   [(match_scratch:DI 3 "r")
12141    (parallel [(set (match_operand:TI 0 "register_operand" "")
12142                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12143                                 (match_operand:QI 2 "nonmemory_operand" "")))
12144               (clobber (reg:CC FLAGS_REG))])
12145    (match_dup 3)]
12146   "TARGET_64BIT"
12147   [(const_int 0)]
12148   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12149
12150 (define_split
12151   [(set (match_operand:TI 0 "register_operand" "")
12152         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12153                      (match_operand:QI 2 "nonmemory_operand" "")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12156                     ? epilogue_completed : reload_completed)"
12157   [(const_int 0)]
12158   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12159
12160 (define_insn "x86_64_shrd"
12161   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12162         (ior:DI (ashiftrt:DI (match_dup 0)
12163                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12164                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12165                   (minus:QI (const_int 64) (match_dup 2)))))
12166    (clobber (reg:CC FLAGS_REG))]
12167   "TARGET_64BIT"
12168   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12169   [(set_attr "type" "ishift")
12170    (set_attr "prefix_0f" "1")
12171    (set_attr "mode" "DI")
12172    (set_attr "athlon_decode" "vector")
12173    (set_attr "amdfam10_decode" "vector")])
12174
12175 (define_expand "ashrdi3"
12176   [(set (match_operand:DI 0 "shiftdi_operand" "")
12177         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12178                      (match_operand:QI 2 "nonmemory_operand" "")))]
12179   ""
12180   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12181
12182 (define_expand "x86_64_shift_adj_3"
12183   [(use (match_operand:DI 0 "register_operand" ""))
12184    (use (match_operand:DI 1 "register_operand" ""))
12185    (use (match_operand:QI 2 "register_operand" ""))]
12186   ""
12187 {
12188   rtx label = gen_label_rtx ();
12189   rtx tmp;
12190
12191   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12192
12193   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12194   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12195   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12196                               gen_rtx_LABEL_REF (VOIDmode, label),
12197                               pc_rtx);
12198   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12199   JUMP_LABEL (tmp) = label;
12200
12201   emit_move_insn (operands[0], operands[1]);
12202   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12203
12204   emit_label (label);
12205   LABEL_NUSES (label) = 1;
12206
12207   DONE;
12208 })
12209
12210 (define_insn "ashrdi3_63_rex64"
12211   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12212         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12213                      (match_operand:DI 2 "const_int_operand" "i,i")))
12214    (clobber (reg:CC FLAGS_REG))]
12215   "TARGET_64BIT && INTVAL (operands[2]) == 63
12216    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12217    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12218   "@
12219    {cqto|cqo}
12220    sar{q}\t{%2, %0|%0, %2}"
12221   [(set_attr "type" "imovx,ishift")
12222    (set_attr "prefix_0f" "0,*")
12223    (set_attr "length_immediate" "0,*")
12224    (set_attr "modrm" "0,1")
12225    (set_attr "mode" "DI")])
12226
12227 (define_insn "*ashrdi3_1_one_bit_rex64"
12228   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12229         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12230                      (match_operand:QI 2 "const1_operand" "")))
12231    (clobber (reg:CC FLAGS_REG))]
12232   "TARGET_64BIT
12233    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12234    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12235   "sar{q}\t%0"
12236   [(set_attr "type" "ishift")
12237    (set (attr "length")
12238      (if_then_else (match_operand:DI 0 "register_operand" "")
12239         (const_string "2")
12240         (const_string "*")))])
12241
12242 (define_insn "*ashrdi3_1_rex64"
12243   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12244         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12245                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12246    (clobber (reg:CC FLAGS_REG))]
12247   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12248   "@
12249    sar{q}\t{%2, %0|%0, %2}
12250    sar{q}\t{%b2, %0|%0, %b2}"
12251   [(set_attr "type" "ishift")
12252    (set_attr "mode" "DI")])
12253
12254 ;; This pattern can't accept a variable shift count, since shifts by
12255 ;; zero don't affect the flags.  We assume that shifts by constant
12256 ;; zero are optimized away.
12257 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12258   [(set (reg FLAGS_REG)
12259         (compare
12260           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12261                        (match_operand:QI 2 "const1_operand" ""))
12262           (const_int 0)))
12263    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12264         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12265   "TARGET_64BIT
12266    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12267    && ix86_match_ccmode (insn, CCGOCmode)
12268    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12269   "sar{q}\t%0"
12270   [(set_attr "type" "ishift")
12271    (set (attr "length")
12272      (if_then_else (match_operand:DI 0 "register_operand" "")
12273         (const_string "2")
12274         (const_string "*")))])
12275
12276 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12277   [(set (reg FLAGS_REG)
12278         (compare
12279           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12280                        (match_operand:QI 2 "const1_operand" ""))
12281           (const_int 0)))
12282    (clobber (match_scratch:DI 0 "=r"))]
12283   "TARGET_64BIT
12284    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12285    && ix86_match_ccmode (insn, CCGOCmode)
12286    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12287   "sar{q}\t%0"
12288   [(set_attr "type" "ishift")
12289    (set_attr "length" "2")])
12290
12291 ;; This pattern can't accept a variable shift count, since shifts by
12292 ;; zero don't affect the flags.  We assume that shifts by constant
12293 ;; zero are optimized away.
12294 (define_insn "*ashrdi3_cmp_rex64"
12295   [(set (reg FLAGS_REG)
12296         (compare
12297           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12298                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12299           (const_int 0)))
12300    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12301         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12302   "TARGET_64BIT
12303    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12304    && ix86_match_ccmode (insn, CCGOCmode)
12305    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12306   "sar{q}\t{%2, %0|%0, %2}"
12307   [(set_attr "type" "ishift")
12308    (set_attr "mode" "DI")])
12309
12310 (define_insn "*ashrdi3_cconly_rex64"
12311   [(set (reg FLAGS_REG)
12312         (compare
12313           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12314                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12315           (const_int 0)))
12316    (clobber (match_scratch:DI 0 "=r"))]
12317   "TARGET_64BIT
12318    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12319    && ix86_match_ccmode (insn, CCGOCmode)
12320    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12321   "sar{q}\t{%2, %0|%0, %2}"
12322   [(set_attr "type" "ishift")
12323    (set_attr "mode" "DI")])
12324
12325 (define_insn "*ashrdi3_1"
12326   [(set (match_operand:DI 0 "register_operand" "=r")
12327         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12328                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12329    (clobber (reg:CC FLAGS_REG))]
12330   "!TARGET_64BIT"
12331   "#"
12332   [(set_attr "type" "multi")])
12333
12334 ;; By default we don't ask for a scratch register, because when DImode
12335 ;; values are manipulated, registers are already at a premium.  But if
12336 ;; we have one handy, we won't turn it away.
12337 (define_peephole2
12338   [(match_scratch:SI 3 "r")
12339    (parallel [(set (match_operand:DI 0 "register_operand" "")
12340                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12341                                 (match_operand:QI 2 "nonmemory_operand" "")))
12342               (clobber (reg:CC FLAGS_REG))])
12343    (match_dup 3)]
12344   "!TARGET_64BIT && TARGET_CMOVE"
12345   [(const_int 0)]
12346   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12347
12348 (define_split
12349   [(set (match_operand:DI 0 "register_operand" "")
12350         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12351                      (match_operand:QI 2 "nonmemory_operand" "")))
12352    (clobber (reg:CC FLAGS_REG))]
12353   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12354                      ? epilogue_completed : reload_completed)"
12355   [(const_int 0)]
12356   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12357
12358 (define_insn "x86_shrd"
12359   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12360         (ior:SI (ashiftrt:SI (match_dup 0)
12361                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12362                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12363                   (minus:QI (const_int 32) (match_dup 2)))))
12364    (clobber (reg:CC FLAGS_REG))]
12365   ""
12366   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12367   [(set_attr "type" "ishift")
12368    (set_attr "prefix_0f" "1")
12369    (set_attr "pent_pair" "np")
12370    (set_attr "mode" "SI")])
12371
12372 (define_expand "x86_shift_adj_3"
12373   [(use (match_operand:SI 0 "register_operand" ""))
12374    (use (match_operand:SI 1 "register_operand" ""))
12375    (use (match_operand:QI 2 "register_operand" ""))]
12376   ""
12377 {
12378   rtx label = gen_label_rtx ();
12379   rtx tmp;
12380
12381   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12382
12383   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12384   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12385   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12386                               gen_rtx_LABEL_REF (VOIDmode, label),
12387                               pc_rtx);
12388   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12389   JUMP_LABEL (tmp) = label;
12390
12391   emit_move_insn (operands[0], operands[1]);
12392   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12393
12394   emit_label (label);
12395   LABEL_NUSES (label) = 1;
12396
12397   DONE;
12398 })
12399
12400 (define_expand "ashrsi3_31"
12401   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12402                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12403                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12404               (clobber (reg:CC FLAGS_REG))])]
12405   "")
12406
12407 (define_insn "*ashrsi3_31"
12408   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12409         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12410                      (match_operand:SI 2 "const_int_operand" "i,i")))
12411    (clobber (reg:CC FLAGS_REG))]
12412   "INTVAL (operands[2]) == 31
12413    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12414    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12415   "@
12416    {cltd|cdq}
12417    sar{l}\t{%2, %0|%0, %2}"
12418   [(set_attr "type" "imovx,ishift")
12419    (set_attr "prefix_0f" "0,*")
12420    (set_attr "length_immediate" "0,*")
12421    (set_attr "modrm" "0,1")
12422    (set_attr "mode" "SI")])
12423
12424 (define_insn "*ashrsi3_31_zext"
12425   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12426         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12427                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12428    (clobber (reg:CC FLAGS_REG))]
12429   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12430    && INTVAL (operands[2]) == 31
12431    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12432   "@
12433    {cltd|cdq}
12434    sar{l}\t{%2, %k0|%k0, %2}"
12435   [(set_attr "type" "imovx,ishift")
12436    (set_attr "prefix_0f" "0,*")
12437    (set_attr "length_immediate" "0,*")
12438    (set_attr "modrm" "0,1")
12439    (set_attr "mode" "SI")])
12440
12441 (define_expand "ashrsi3"
12442   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12443         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12444                      (match_operand:QI 2 "nonmemory_operand" "")))]
12445   ""
12446   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12447
12448 (define_insn "*ashrsi3_1_one_bit"
12449   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12450         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12451                      (match_operand:QI 2 "const1_operand" "")))
12452    (clobber (reg:CC FLAGS_REG))]
12453   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12454    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12455   "sar{l}\t%0"
12456   [(set_attr "type" "ishift")
12457    (set (attr "length")
12458      (if_then_else (match_operand:SI 0 "register_operand" "")
12459         (const_string "2")
12460         (const_string "*")))])
12461
12462 (define_insn "*ashrsi3_1_one_bit_zext"
12463   [(set (match_operand:DI 0 "register_operand" "=r")
12464         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12465                                      (match_operand:QI 2 "const1_operand" ""))))
12466    (clobber (reg:CC FLAGS_REG))]
12467   "TARGET_64BIT
12468    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12469    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12470   "sar{l}\t%k0"
12471   [(set_attr "type" "ishift")
12472    (set_attr "length" "2")])
12473
12474 (define_insn "*ashrsi3_1"
12475   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12476         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12477                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478    (clobber (reg:CC FLAGS_REG))]
12479   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12480   "@
12481    sar{l}\t{%2, %0|%0, %2}
12482    sar{l}\t{%b2, %0|%0, %b2}"
12483   [(set_attr "type" "ishift")
12484    (set_attr "mode" "SI")])
12485
12486 (define_insn "*ashrsi3_1_zext"
12487   [(set (match_operand:DI 0 "register_operand" "=r,r")
12488         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12489                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12490    (clobber (reg:CC FLAGS_REG))]
12491   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12492   "@
12493    sar{l}\t{%2, %k0|%k0, %2}
12494    sar{l}\t{%b2, %k0|%k0, %b2}"
12495   [(set_attr "type" "ishift")
12496    (set_attr "mode" "SI")])
12497
12498 ;; This pattern can't accept a variable shift count, since shifts by
12499 ;; zero don't affect the flags.  We assume that shifts by constant
12500 ;; zero are optimized away.
12501 (define_insn "*ashrsi3_one_bit_cmp"
12502   [(set (reg FLAGS_REG)
12503         (compare
12504           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12505                        (match_operand:QI 2 "const1_operand" ""))
12506           (const_int 0)))
12507    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12508         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12509   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12510    && ix86_match_ccmode (insn, CCGOCmode)
12511    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12512   "sar{l}\t%0"
12513   [(set_attr "type" "ishift")
12514    (set (attr "length")
12515      (if_then_else (match_operand:SI 0 "register_operand" "")
12516         (const_string "2")
12517         (const_string "*")))])
12518
12519 (define_insn "*ashrsi3_one_bit_cconly"
12520   [(set (reg FLAGS_REG)
12521         (compare
12522           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12523                        (match_operand:QI 2 "const1_operand" ""))
12524           (const_int 0)))
12525    (clobber (match_scratch:SI 0 "=r"))]
12526   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12527    && ix86_match_ccmode (insn, CCGOCmode)
12528    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12529   "sar{l}\t%0"
12530   [(set_attr "type" "ishift")
12531    (set_attr "length" "2")])
12532
12533 (define_insn "*ashrsi3_one_bit_cmp_zext"
12534   [(set (reg FLAGS_REG)
12535         (compare
12536           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12537                        (match_operand:QI 2 "const1_operand" ""))
12538           (const_int 0)))
12539    (set (match_operand:DI 0 "register_operand" "=r")
12540         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12541   "TARGET_64BIT
12542    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12543    && ix86_match_ccmode (insn, CCmode)
12544    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12545   "sar{l}\t%k0"
12546   [(set_attr "type" "ishift")
12547    (set_attr "length" "2")])
12548
12549 ;; This pattern can't accept a variable shift count, since shifts by
12550 ;; zero don't affect the flags.  We assume that shifts by constant
12551 ;; zero are optimized away.
12552 (define_insn "*ashrsi3_cmp"
12553   [(set (reg FLAGS_REG)
12554         (compare
12555           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12556                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12557           (const_int 0)))
12558    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12559         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12560   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12561    && ix86_match_ccmode (insn, CCGOCmode)
12562    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12563   "sar{l}\t{%2, %0|%0, %2}"
12564   [(set_attr "type" "ishift")
12565    (set_attr "mode" "SI")])
12566
12567 (define_insn "*ashrsi3_cconly"
12568   [(set (reg FLAGS_REG)
12569         (compare
12570           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12571                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12572           (const_int 0)))
12573    (clobber (match_scratch:SI 0 "=r"))]
12574   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12575    && ix86_match_ccmode (insn, CCGOCmode)
12576    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12577   "sar{l}\t{%2, %0|%0, %2}"
12578   [(set_attr "type" "ishift")
12579    (set_attr "mode" "SI")])
12580
12581 (define_insn "*ashrsi3_cmp_zext"
12582   [(set (reg FLAGS_REG)
12583         (compare
12584           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12585                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12586           (const_int 0)))
12587    (set (match_operand:DI 0 "register_operand" "=r")
12588         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12589   "TARGET_64BIT
12590    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12591    && ix86_match_ccmode (insn, CCGOCmode)
12592    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12593   "sar{l}\t{%2, %k0|%k0, %2}"
12594   [(set_attr "type" "ishift")
12595    (set_attr "mode" "SI")])
12596
12597 (define_expand "ashrhi3"
12598   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12599         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12600                      (match_operand:QI 2 "nonmemory_operand" "")))]
12601   "TARGET_HIMODE_MATH"
12602   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12603
12604 (define_insn "*ashrhi3_1_one_bit"
12605   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12606         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12607                      (match_operand:QI 2 "const1_operand" "")))
12608    (clobber (reg:CC FLAGS_REG))]
12609   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12610    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12611   "sar{w}\t%0"
12612   [(set_attr "type" "ishift")
12613    (set (attr "length")
12614      (if_then_else (match_operand 0 "register_operand" "")
12615         (const_string "2")
12616         (const_string "*")))])
12617
12618 (define_insn "*ashrhi3_1"
12619   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12620         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12621                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12622    (clobber (reg:CC FLAGS_REG))]
12623   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12624   "@
12625    sar{w}\t{%2, %0|%0, %2}
12626    sar{w}\t{%b2, %0|%0, %b2}"
12627   [(set_attr "type" "ishift")
12628    (set_attr "mode" "HI")])
12629
12630 ;; This pattern can't accept a variable shift count, since shifts by
12631 ;; zero don't affect the flags.  We assume that shifts by constant
12632 ;; zero are optimized away.
12633 (define_insn "*ashrhi3_one_bit_cmp"
12634   [(set (reg FLAGS_REG)
12635         (compare
12636           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12637                        (match_operand:QI 2 "const1_operand" ""))
12638           (const_int 0)))
12639    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12640         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12641   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12642    && ix86_match_ccmode (insn, CCGOCmode)
12643    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12644   "sar{w}\t%0"
12645   [(set_attr "type" "ishift")
12646    (set (attr "length")
12647      (if_then_else (match_operand 0 "register_operand" "")
12648         (const_string "2")
12649         (const_string "*")))])
12650
12651 (define_insn "*ashrhi3_one_bit_cconly"
12652   [(set (reg FLAGS_REG)
12653         (compare
12654           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12655                        (match_operand:QI 2 "const1_operand" ""))
12656           (const_int 0)))
12657    (clobber (match_scratch:HI 0 "=r"))]
12658   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12659    && ix86_match_ccmode (insn, CCGOCmode)
12660    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12661   "sar{w}\t%0"
12662   [(set_attr "type" "ishift")
12663    (set_attr "length" "2")])
12664
12665 ;; This pattern can't accept a variable shift count, since shifts by
12666 ;; zero don't affect the flags.  We assume that shifts by constant
12667 ;; zero are optimized away.
12668 (define_insn "*ashrhi3_cmp"
12669   [(set (reg FLAGS_REG)
12670         (compare
12671           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12672                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12673           (const_int 0)))
12674    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12675         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12676   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12677    && ix86_match_ccmode (insn, CCGOCmode)
12678    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12679   "sar{w}\t{%2, %0|%0, %2}"
12680   [(set_attr "type" "ishift")
12681    (set_attr "mode" "HI")])
12682
12683 (define_insn "*ashrhi3_cconly"
12684   [(set (reg FLAGS_REG)
12685         (compare
12686           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12687                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12688           (const_int 0)))
12689    (clobber (match_scratch:HI 0 "=r"))]
12690   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12691    && ix86_match_ccmode (insn, CCGOCmode)
12692    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12693   "sar{w}\t{%2, %0|%0, %2}"
12694   [(set_attr "type" "ishift")
12695    (set_attr "mode" "HI")])
12696
12697 (define_expand "ashrqi3"
12698   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12699         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12700                      (match_operand:QI 2 "nonmemory_operand" "")))]
12701   "TARGET_QIMODE_MATH"
12702   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12703
12704 (define_insn "*ashrqi3_1_one_bit"
12705   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12706         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12707                      (match_operand:QI 2 "const1_operand" "")))
12708    (clobber (reg:CC FLAGS_REG))]
12709   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12710    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12711   "sar{b}\t%0"
12712   [(set_attr "type" "ishift")
12713    (set (attr "length")
12714      (if_then_else (match_operand 0 "register_operand" "")
12715         (const_string "2")
12716         (const_string "*")))])
12717
12718 (define_insn "*ashrqi3_1_one_bit_slp"
12719   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12720         (ashiftrt:QI (match_dup 0)
12721                      (match_operand:QI 1 "const1_operand" "")))
12722    (clobber (reg:CC FLAGS_REG))]
12723   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12724    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12725    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12726   "sar{b}\t%0"
12727   [(set_attr "type" "ishift1")
12728    (set (attr "length")
12729      (if_then_else (match_operand 0 "register_operand" "")
12730         (const_string "2")
12731         (const_string "*")))])
12732
12733 (define_insn "*ashrqi3_1"
12734   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12735         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12736                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12737    (clobber (reg:CC FLAGS_REG))]
12738   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12739   "@
12740    sar{b}\t{%2, %0|%0, %2}
12741    sar{b}\t{%b2, %0|%0, %b2}"
12742   [(set_attr "type" "ishift")
12743    (set_attr "mode" "QI")])
12744
12745 (define_insn "*ashrqi3_1_slp"
12746   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12747         (ashiftrt:QI (match_dup 0)
12748                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12749    (clobber (reg:CC FLAGS_REG))]
12750   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12751    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12752   "@
12753    sar{b}\t{%1, %0|%0, %1}
12754    sar{b}\t{%b1, %0|%0, %b1}"
12755   [(set_attr "type" "ishift1")
12756    (set_attr "mode" "QI")])
12757
12758 ;; This pattern can't accept a variable shift count, since shifts by
12759 ;; zero don't affect the flags.  We assume that shifts by constant
12760 ;; zero are optimized away.
12761 (define_insn "*ashrqi3_one_bit_cmp"
12762   [(set (reg FLAGS_REG)
12763         (compare
12764           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12765                        (match_operand:QI 2 "const1_operand" "I"))
12766           (const_int 0)))
12767    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12768         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12769   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12770    && ix86_match_ccmode (insn, CCGOCmode)
12771    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12772   "sar{b}\t%0"
12773   [(set_attr "type" "ishift")
12774    (set (attr "length")
12775      (if_then_else (match_operand 0 "register_operand" "")
12776         (const_string "2")
12777         (const_string "*")))])
12778
12779 (define_insn "*ashrqi3_one_bit_cconly"
12780   [(set (reg FLAGS_REG)
12781         (compare
12782           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12783                        (match_operand:QI 2 "const1_operand" ""))
12784           (const_int 0)))
12785    (clobber (match_scratch:QI 0 "=q"))]
12786   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12787    && ix86_match_ccmode (insn, CCGOCmode)
12788    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12789   "sar{b}\t%0"
12790   [(set_attr "type" "ishift")
12791    (set_attr "length" "2")])
12792
12793 ;; This pattern can't accept a variable shift count, since shifts by
12794 ;; zero don't affect the flags.  We assume that shifts by constant
12795 ;; zero are optimized away.
12796 (define_insn "*ashrqi3_cmp"
12797   [(set (reg FLAGS_REG)
12798         (compare
12799           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12800                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12801           (const_int 0)))
12802    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12803         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12804   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12805    && ix86_match_ccmode (insn, CCGOCmode)
12806    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12807   "sar{b}\t{%2, %0|%0, %2}"
12808   [(set_attr "type" "ishift")
12809    (set_attr "mode" "QI")])
12810
12811 (define_insn "*ashrqi3_cconly"
12812   [(set (reg FLAGS_REG)
12813         (compare
12814           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12815                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12816           (const_int 0)))
12817    (clobber (match_scratch:QI 0 "=q"))]
12818   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12819    && ix86_match_ccmode (insn, CCGOCmode)
12820    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12821   "sar{b}\t{%2, %0|%0, %2}"
12822   [(set_attr "type" "ishift")
12823    (set_attr "mode" "QI")])
12824
12825 \f
12826 ;; Logical shift instructions
12827
12828 ;; See comment above `ashldi3' about how this works.
12829
12830 (define_expand "lshrti3"
12831   [(set (match_operand:TI 0 "register_operand" "")
12832         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12833                      (match_operand:QI 2 "nonmemory_operand" "")))]
12834   "TARGET_64BIT"
12835   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12836
12837 ;; This pattern must be defined before *lshrti3_1 to prevent
12838 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12839
12840 (define_insn "*avx_lshrti3"
12841   [(set (match_operand:TI 0 "register_operand" "=x")
12842         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12843                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12844   "TARGET_AVX"
12845 {
12846   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12847   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12848 }
12849   [(set_attr "type" "sseishft")
12850    (set_attr "prefix" "vex")
12851    (set_attr "mode" "TI")])
12852
12853 (define_insn "sse2_lshrti3"
12854   [(set (match_operand:TI 0 "register_operand" "=x")
12855         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12856                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12857   "TARGET_SSE2"
12858 {
12859   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12860   return "psrldq\t{%2, %0|%0, %2}";
12861 }
12862   [(set_attr "type" "sseishft")
12863    (set_attr "prefix_data16" "1")
12864    (set_attr "mode" "TI")])
12865
12866 (define_insn "*lshrti3_1"
12867   [(set (match_operand:TI 0 "register_operand" "=r")
12868         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12869                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12870    (clobber (reg:CC FLAGS_REG))]
12871   "TARGET_64BIT"
12872   "#"
12873   [(set_attr "type" "multi")])
12874
12875 (define_peephole2
12876   [(match_scratch:DI 3 "r")
12877    (parallel [(set (match_operand:TI 0 "register_operand" "")
12878                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12879                                 (match_operand:QI 2 "nonmemory_operand" "")))
12880               (clobber (reg:CC FLAGS_REG))])
12881    (match_dup 3)]
12882   "TARGET_64BIT"
12883   [(const_int 0)]
12884   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12885
12886 (define_split
12887   [(set (match_operand:TI 0 "register_operand" "")
12888         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12889                      (match_operand:QI 2 "nonmemory_operand" "")))
12890    (clobber (reg:CC FLAGS_REG))]
12891   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12892                     ? epilogue_completed : reload_completed)"
12893   [(const_int 0)]
12894   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12895
12896 (define_expand "lshrdi3"
12897   [(set (match_operand:DI 0 "shiftdi_operand" "")
12898         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12899                      (match_operand:QI 2 "nonmemory_operand" "")))]
12900   ""
12901   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12902
12903 (define_insn "*lshrdi3_1_one_bit_rex64"
12904   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12905         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12906                      (match_operand:QI 2 "const1_operand" "")))
12907    (clobber (reg:CC FLAGS_REG))]
12908   "TARGET_64BIT
12909    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12910    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12911   "shr{q}\t%0"
12912   [(set_attr "type" "ishift")
12913    (set (attr "length")
12914      (if_then_else (match_operand:DI 0 "register_operand" "")
12915         (const_string "2")
12916         (const_string "*")))])
12917
12918 (define_insn "*lshrdi3_1_rex64"
12919   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12920         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12921                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12922    (clobber (reg:CC FLAGS_REG))]
12923   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12924   "@
12925    shr{q}\t{%2, %0|%0, %2}
12926    shr{q}\t{%b2, %0|%0, %b2}"
12927   [(set_attr "type" "ishift")
12928    (set_attr "mode" "DI")])
12929
12930 ;; This pattern can't accept a variable shift count, since shifts by
12931 ;; zero don't affect the flags.  We assume that shifts by constant
12932 ;; zero are optimized away.
12933 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12934   [(set (reg FLAGS_REG)
12935         (compare
12936           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12937                        (match_operand:QI 2 "const1_operand" ""))
12938           (const_int 0)))
12939    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12940         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12941   "TARGET_64BIT
12942    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12943    && ix86_match_ccmode (insn, CCGOCmode)
12944    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12945   "shr{q}\t%0"
12946   [(set_attr "type" "ishift")
12947    (set (attr "length")
12948      (if_then_else (match_operand:DI 0 "register_operand" "")
12949         (const_string "2")
12950         (const_string "*")))])
12951
12952 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12953   [(set (reg FLAGS_REG)
12954         (compare
12955           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12956                        (match_operand:QI 2 "const1_operand" ""))
12957           (const_int 0)))
12958    (clobber (match_scratch:DI 0 "=r"))]
12959   "TARGET_64BIT
12960    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12961    && ix86_match_ccmode (insn, CCGOCmode)
12962    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12963   "shr{q}\t%0"
12964   [(set_attr "type" "ishift")
12965    (set_attr "length" "2")])
12966
12967 ;; This pattern can't accept a variable shift count, since shifts by
12968 ;; zero don't affect the flags.  We assume that shifts by constant
12969 ;; zero are optimized away.
12970 (define_insn "*lshrdi3_cmp_rex64"
12971   [(set (reg FLAGS_REG)
12972         (compare
12973           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12974                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12975           (const_int 0)))
12976    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12977         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12978   "TARGET_64BIT
12979    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12980    && ix86_match_ccmode (insn, CCGOCmode)
12981    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12982   "shr{q}\t{%2, %0|%0, %2}"
12983   [(set_attr "type" "ishift")
12984    (set_attr "mode" "DI")])
12985
12986 (define_insn "*lshrdi3_cconly_rex64"
12987   [(set (reg FLAGS_REG)
12988         (compare
12989           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12990                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12991           (const_int 0)))
12992    (clobber (match_scratch:DI 0 "=r"))]
12993   "TARGET_64BIT
12994    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12995    && ix86_match_ccmode (insn, CCGOCmode)
12996    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12997   "shr{q}\t{%2, %0|%0, %2}"
12998   [(set_attr "type" "ishift")
12999    (set_attr "mode" "DI")])
13000
13001 (define_insn "*lshrdi3_1"
13002   [(set (match_operand:DI 0 "register_operand" "=r")
13003         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13004                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
13005    (clobber (reg:CC FLAGS_REG))]
13006   "!TARGET_64BIT"
13007   "#"
13008   [(set_attr "type" "multi")])
13009
13010 ;; By default we don't ask for a scratch register, because when DImode
13011 ;; values are manipulated, registers are already at a premium.  But if
13012 ;; we have one handy, we won't turn it away.
13013 (define_peephole2
13014   [(match_scratch:SI 3 "r")
13015    (parallel [(set (match_operand:DI 0 "register_operand" "")
13016                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13017                                 (match_operand:QI 2 "nonmemory_operand" "")))
13018               (clobber (reg:CC FLAGS_REG))])
13019    (match_dup 3)]
13020   "!TARGET_64BIT && TARGET_CMOVE"
13021   [(const_int 0)]
13022   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13023
13024 (define_split
13025   [(set (match_operand:DI 0 "register_operand" "")
13026         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13027                      (match_operand:QI 2 "nonmemory_operand" "")))
13028    (clobber (reg:CC FLAGS_REG))]
13029   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13030                      ? epilogue_completed : reload_completed)"
13031   [(const_int 0)]
13032   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13033
13034 (define_expand "lshrsi3"
13035   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13036         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13037                      (match_operand:QI 2 "nonmemory_operand" "")))]
13038   ""
13039   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13040
13041 (define_insn "*lshrsi3_1_one_bit"
13042   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13043         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13044                      (match_operand:QI 2 "const1_operand" "")))
13045    (clobber (reg:CC FLAGS_REG))]
13046   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13047    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13048   "shr{l}\t%0"
13049   [(set_attr "type" "ishift")
13050    (set (attr "length")
13051      (if_then_else (match_operand:SI 0 "register_operand" "")
13052         (const_string "2")
13053         (const_string "*")))])
13054
13055 (define_insn "*lshrsi3_1_one_bit_zext"
13056   [(set (match_operand:DI 0 "register_operand" "=r")
13057         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13058                      (match_operand:QI 2 "const1_operand" "")))
13059    (clobber (reg:CC FLAGS_REG))]
13060   "TARGET_64BIT
13061    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13062    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13063   "shr{l}\t%k0"
13064   [(set_attr "type" "ishift")
13065    (set_attr "length" "2")])
13066
13067 (define_insn "*lshrsi3_1"
13068   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
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   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13073   "@
13074    shr{l}\t{%2, %0|%0, %2}
13075    shr{l}\t{%b2, %0|%0, %b2}"
13076   [(set_attr "type" "ishift")
13077    (set_attr "mode" "SI")])
13078
13079 (define_insn "*lshrsi3_1_zext"
13080   [(set (match_operand:DI 0 "register_operand" "=r,r")
13081         (zero_extend:DI
13082           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13083                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13084    (clobber (reg:CC FLAGS_REG))]
13085   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13086   "@
13087    shr{l}\t{%2, %k0|%k0, %2}
13088    shr{l}\t{%b2, %k0|%k0, %b2}"
13089   [(set_attr "type" "ishift")
13090    (set_attr "mode" "SI")])
13091
13092 ;; This pattern can't accept a variable shift count, since shifts by
13093 ;; zero don't affect the flags.  We assume that shifts by constant
13094 ;; zero are optimized away.
13095 (define_insn "*lshrsi3_one_bit_cmp"
13096   [(set (reg FLAGS_REG)
13097         (compare
13098           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13099                        (match_operand:QI 2 "const1_operand" ""))
13100           (const_int 0)))
13101    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13102         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13103   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13104    && ix86_match_ccmode (insn, CCGOCmode)
13105    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13106   "shr{l}\t%0"
13107   [(set_attr "type" "ishift")
13108    (set (attr "length")
13109      (if_then_else (match_operand:SI 0 "register_operand" "")
13110         (const_string "2")
13111         (const_string "*")))])
13112
13113 (define_insn "*lshrsi3_one_bit_cconly"
13114   [(set (reg FLAGS_REG)
13115         (compare
13116           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13117                        (match_operand:QI 2 "const1_operand" ""))
13118           (const_int 0)))
13119    (clobber (match_scratch:SI 0 "=r"))]
13120   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13121    && ix86_match_ccmode (insn, CCGOCmode)
13122    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13123   "shr{l}\t%0"
13124   [(set_attr "type" "ishift")
13125    (set_attr "length" "2")])
13126
13127 (define_insn "*lshrsi3_cmp_one_bit_zext"
13128   [(set (reg FLAGS_REG)
13129         (compare
13130           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13131                        (match_operand:QI 2 "const1_operand" ""))
13132           (const_int 0)))
13133    (set (match_operand:DI 0 "register_operand" "=r")
13134         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13135   "TARGET_64BIT
13136    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13137    && ix86_match_ccmode (insn, CCGOCmode)
13138    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13139   "shr{l}\t%k0"
13140   [(set_attr "type" "ishift")
13141    (set_attr "length" "2")])
13142
13143 ;; This pattern can't accept a variable shift count, since shifts by
13144 ;; zero don't affect the flags.  We assume that shifts by constant
13145 ;; zero are optimized away.
13146 (define_insn "*lshrsi3_cmp"
13147   [(set (reg FLAGS_REG)
13148         (compare
13149           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13150                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13151           (const_int 0)))
13152    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13153         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13154   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13155    && ix86_match_ccmode (insn, CCGOCmode)
13156    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13157   "shr{l}\t{%2, %0|%0, %2}"
13158   [(set_attr "type" "ishift")
13159    (set_attr "mode" "SI")])
13160
13161 (define_insn "*lshrsi3_cconly"
13162   [(set (reg FLAGS_REG)
13163       (compare
13164         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13165                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13166         (const_int 0)))
13167    (clobber (match_scratch:SI 0 "=r"))]
13168   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13169    && ix86_match_ccmode (insn, CCGOCmode)
13170    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13171   "shr{l}\t{%2, %0|%0, %2}"
13172   [(set_attr "type" "ishift")
13173    (set_attr "mode" "SI")])
13174
13175 (define_insn "*lshrsi3_cmp_zext"
13176   [(set (reg FLAGS_REG)
13177         (compare
13178           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13179                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13180           (const_int 0)))
13181    (set (match_operand:DI 0 "register_operand" "=r")
13182         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13183   "TARGET_64BIT
13184    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13185    && ix86_match_ccmode (insn, CCGOCmode)
13186    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13187   "shr{l}\t{%2, %k0|%k0, %2}"
13188   [(set_attr "type" "ishift")
13189    (set_attr "mode" "SI")])
13190
13191 (define_expand "lshrhi3"
13192   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13193         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13194                      (match_operand:QI 2 "nonmemory_operand" "")))]
13195   "TARGET_HIMODE_MATH"
13196   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13197
13198 (define_insn "*lshrhi3_1_one_bit"
13199   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13200         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13201                      (match_operand:QI 2 "const1_operand" "")))
13202    (clobber (reg:CC FLAGS_REG))]
13203   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13204    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13205   "shr{w}\t%0"
13206   [(set_attr "type" "ishift")
13207    (set (attr "length")
13208      (if_then_else (match_operand 0 "register_operand" "")
13209         (const_string "2")
13210         (const_string "*")))])
13211
13212 (define_insn "*lshrhi3_1"
13213   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13214         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13215                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13216    (clobber (reg:CC FLAGS_REG))]
13217   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13218   "@
13219    shr{w}\t{%2, %0|%0, %2}
13220    shr{w}\t{%b2, %0|%0, %b2}"
13221   [(set_attr "type" "ishift")
13222    (set_attr "mode" "HI")])
13223
13224 ;; This pattern can't accept a variable shift count, since shifts by
13225 ;; zero don't affect the flags.  We assume that shifts by constant
13226 ;; zero are optimized away.
13227 (define_insn "*lshrhi3_one_bit_cmp"
13228   [(set (reg FLAGS_REG)
13229         (compare
13230           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13231                        (match_operand:QI 2 "const1_operand" ""))
13232           (const_int 0)))
13233    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13234         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13235   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13236    && ix86_match_ccmode (insn, CCGOCmode)
13237    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13238   "shr{w}\t%0"
13239   [(set_attr "type" "ishift")
13240    (set (attr "length")
13241      (if_then_else (match_operand:SI 0 "register_operand" "")
13242         (const_string "2")
13243         (const_string "*")))])
13244
13245 (define_insn "*lshrhi3_one_bit_cconly"
13246   [(set (reg FLAGS_REG)
13247         (compare
13248           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13249                        (match_operand:QI 2 "const1_operand" ""))
13250           (const_int 0)))
13251    (clobber (match_scratch:HI 0 "=r"))]
13252   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13253    && ix86_match_ccmode (insn, CCGOCmode)
13254    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13255   "shr{w}\t%0"
13256   [(set_attr "type" "ishift")
13257    (set_attr "length" "2")])
13258
13259 ;; This pattern can't accept a variable shift count, since shifts by
13260 ;; zero don't affect the flags.  We assume that shifts by constant
13261 ;; zero are optimized away.
13262 (define_insn "*lshrhi3_cmp"
13263   [(set (reg FLAGS_REG)
13264         (compare
13265           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13266                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13267           (const_int 0)))
13268    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13269         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13270   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13271    && ix86_match_ccmode (insn, CCGOCmode)
13272    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13273   "shr{w}\t{%2, %0|%0, %2}"
13274   [(set_attr "type" "ishift")
13275    (set_attr "mode" "HI")])
13276
13277 (define_insn "*lshrhi3_cconly"
13278   [(set (reg FLAGS_REG)
13279         (compare
13280           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13281                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13282           (const_int 0)))
13283    (clobber (match_scratch:HI 0 "=r"))]
13284   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13285    && ix86_match_ccmode (insn, CCGOCmode)
13286    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13287   "shr{w}\t{%2, %0|%0, %2}"
13288   [(set_attr "type" "ishift")
13289    (set_attr "mode" "HI")])
13290
13291 (define_expand "lshrqi3"
13292   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13293         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13294                      (match_operand:QI 2 "nonmemory_operand" "")))]
13295   "TARGET_QIMODE_MATH"
13296   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13297
13298 (define_insn "*lshrqi3_1_one_bit"
13299   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13300         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13301                      (match_operand:QI 2 "const1_operand" "")))
13302    (clobber (reg:CC FLAGS_REG))]
13303   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13304    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13305   "shr{b}\t%0"
13306   [(set_attr "type" "ishift")
13307    (set (attr "length")
13308      (if_then_else (match_operand 0 "register_operand" "")
13309         (const_string "2")
13310         (const_string "*")))])
13311
13312 (define_insn "*lshrqi3_1_one_bit_slp"
13313   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13314         (lshiftrt:QI (match_dup 0)
13315                      (match_operand:QI 1 "const1_operand" "")))
13316    (clobber (reg:CC FLAGS_REG))]
13317   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13318    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13319   "shr{b}\t%0"
13320   [(set_attr "type" "ishift1")
13321    (set (attr "length")
13322      (if_then_else (match_operand 0 "register_operand" "")
13323         (const_string "2")
13324         (const_string "*")))])
13325
13326 (define_insn "*lshrqi3_1"
13327   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13328         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13329                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13330    (clobber (reg:CC FLAGS_REG))]
13331   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13332   "@
13333    shr{b}\t{%2, %0|%0, %2}
13334    shr{b}\t{%b2, %0|%0, %b2}"
13335   [(set_attr "type" "ishift")
13336    (set_attr "mode" "QI")])
13337
13338 (define_insn "*lshrqi3_1_slp"
13339   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13340         (lshiftrt:QI (match_dup 0)
13341                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13342    (clobber (reg:CC FLAGS_REG))]
13343   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13344    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13345   "@
13346    shr{b}\t{%1, %0|%0, %1}
13347    shr{b}\t{%b1, %0|%0, %b1}"
13348   [(set_attr "type" "ishift1")
13349    (set_attr "mode" "QI")])
13350
13351 ;; This pattern can't accept a variable shift count, since shifts by
13352 ;; zero don't affect the flags.  We assume that shifts by constant
13353 ;; zero are optimized away.
13354 (define_insn "*lshrqi2_one_bit_cmp"
13355   [(set (reg FLAGS_REG)
13356         (compare
13357           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13358                        (match_operand:QI 2 "const1_operand" ""))
13359           (const_int 0)))
13360    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13361         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13362   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13363    && ix86_match_ccmode (insn, CCGOCmode)
13364    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13365   "shr{b}\t%0"
13366   [(set_attr "type" "ishift")
13367    (set (attr "length")
13368      (if_then_else (match_operand:SI 0 "register_operand" "")
13369         (const_string "2")
13370         (const_string "*")))])
13371
13372 (define_insn "*lshrqi2_one_bit_cconly"
13373   [(set (reg FLAGS_REG)
13374         (compare
13375           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13376                        (match_operand:QI 2 "const1_operand" ""))
13377           (const_int 0)))
13378    (clobber (match_scratch:QI 0 "=q"))]
13379   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13380    && ix86_match_ccmode (insn, CCGOCmode)
13381    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13382   "shr{b}\t%0"
13383   [(set_attr "type" "ishift")
13384    (set_attr "length" "2")])
13385
13386 ;; This pattern can't accept a variable shift count, since shifts by
13387 ;; zero don't affect the flags.  We assume that shifts by constant
13388 ;; zero are optimized away.
13389 (define_insn "*lshrqi2_cmp"
13390   [(set (reg FLAGS_REG)
13391         (compare
13392           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13393                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13394           (const_int 0)))
13395    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13396         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13397   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13398    && ix86_match_ccmode (insn, CCGOCmode)
13399    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13400   "shr{b}\t{%2, %0|%0, %2}"
13401   [(set_attr "type" "ishift")
13402    (set_attr "mode" "QI")])
13403
13404 (define_insn "*lshrqi2_cconly"
13405   [(set (reg FLAGS_REG)
13406         (compare
13407           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13408                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13409           (const_int 0)))
13410    (clobber (match_scratch:QI 0 "=q"))]
13411   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13412    && ix86_match_ccmode (insn, CCGOCmode)
13413    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13414   "shr{b}\t{%2, %0|%0, %2}"
13415   [(set_attr "type" "ishift")
13416    (set_attr "mode" "QI")])
13417 \f
13418 ;; Rotate instructions
13419
13420 (define_expand "rotldi3"
13421   [(set (match_operand:DI 0 "shiftdi_operand" "")
13422         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13423                    (match_operand:QI 2 "nonmemory_operand" "")))]
13424  ""
13425 {
13426   if (TARGET_64BIT)
13427     {
13428       ix86_expand_binary_operator (ROTATE, DImode, operands);
13429       DONE;
13430     }
13431   if (!const_1_to_31_operand (operands[2], VOIDmode))
13432     FAIL;
13433   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13434   DONE;
13435 })
13436
13437 ;; Implement rotation using two double-precision shift instructions
13438 ;; and a scratch register.
13439 (define_insn_and_split "ix86_rotldi3"
13440  [(set (match_operand:DI 0 "register_operand" "=r")
13441        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13442                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13443   (clobber (reg:CC FLAGS_REG))
13444   (clobber (match_scratch:SI 3 "=&r"))]
13445  "!TARGET_64BIT"
13446  ""
13447  "&& reload_completed"
13448  [(set (match_dup 3) (match_dup 4))
13449   (parallel
13450    [(set (match_dup 4)
13451          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13452                  (lshiftrt:SI (match_dup 5)
13453                               (minus:QI (const_int 32) (match_dup 2)))))
13454     (clobber (reg:CC FLAGS_REG))])
13455   (parallel
13456    [(set (match_dup 5)
13457          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13458                  (lshiftrt:SI (match_dup 3)
13459                               (minus:QI (const_int 32) (match_dup 2)))))
13460     (clobber (reg:CC FLAGS_REG))])]
13461  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13462
13463 (define_insn "*rotlsi3_1_one_bit_rex64"
13464   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13465         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13466                    (match_operand:QI 2 "const1_operand" "")))
13467    (clobber (reg:CC FLAGS_REG))]
13468   "TARGET_64BIT
13469    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13470    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13471   "rol{q}\t%0"
13472   [(set_attr "type" "rotate")
13473    (set (attr "length")
13474      (if_then_else (match_operand:DI 0 "register_operand" "")
13475         (const_string "2")
13476         (const_string "*")))])
13477
13478 (define_insn "*rotldi3_1_rex64"
13479   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13480         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13481                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13482    (clobber (reg:CC FLAGS_REG))]
13483   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13484   "@
13485    rol{q}\t{%2, %0|%0, %2}
13486    rol{q}\t{%b2, %0|%0, %b2}"
13487   [(set_attr "type" "rotate")
13488    (set_attr "mode" "DI")])
13489
13490 (define_expand "rotlsi3"
13491   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13492         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13493                    (match_operand:QI 2 "nonmemory_operand" "")))]
13494   ""
13495   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13496
13497 (define_insn "*rotlsi3_1_one_bit"
13498   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13499         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13500                    (match_operand:QI 2 "const1_operand" "")))
13501    (clobber (reg:CC FLAGS_REG))]
13502   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13503    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13504   "rol{l}\t%0"
13505   [(set_attr "type" "rotate")
13506    (set (attr "length")
13507      (if_then_else (match_operand:SI 0 "register_operand" "")
13508         (const_string "2")
13509         (const_string "*")))])
13510
13511 (define_insn "*rotlsi3_1_one_bit_zext"
13512   [(set (match_operand:DI 0 "register_operand" "=r")
13513         (zero_extend:DI
13514           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13515                      (match_operand:QI 2 "const1_operand" ""))))
13516    (clobber (reg:CC FLAGS_REG))]
13517   "TARGET_64BIT
13518    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13519    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13520   "rol{l}\t%k0"
13521   [(set_attr "type" "rotate")
13522    (set_attr "length" "2")])
13523
13524 (define_insn "*rotlsi3_1"
13525   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13526         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13527                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13528    (clobber (reg:CC FLAGS_REG))]
13529   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13530   "@
13531    rol{l}\t{%2, %0|%0, %2}
13532    rol{l}\t{%b2, %0|%0, %b2}"
13533   [(set_attr "type" "rotate")
13534    (set_attr "mode" "SI")])
13535
13536 (define_insn "*rotlsi3_1_zext"
13537   [(set (match_operand:DI 0 "register_operand" "=r,r")
13538         (zero_extend:DI
13539           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13540                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13541    (clobber (reg:CC FLAGS_REG))]
13542   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13543   "@
13544    rol{l}\t{%2, %k0|%k0, %2}
13545    rol{l}\t{%b2, %k0|%k0, %b2}"
13546   [(set_attr "type" "rotate")
13547    (set_attr "mode" "SI")])
13548
13549 (define_expand "rotlhi3"
13550   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13551         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13552                    (match_operand:QI 2 "nonmemory_operand" "")))]
13553   "TARGET_HIMODE_MATH"
13554   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13555
13556 (define_insn "*rotlhi3_1_one_bit"
13557   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13558         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13559                    (match_operand:QI 2 "const1_operand" "")))
13560    (clobber (reg:CC FLAGS_REG))]
13561   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13562    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13563   "rol{w}\t%0"
13564   [(set_attr "type" "rotate")
13565    (set (attr "length")
13566      (if_then_else (match_operand 0 "register_operand" "")
13567         (const_string "2")
13568         (const_string "*")))])
13569
13570 (define_insn "*rotlhi3_1"
13571   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13572         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13573                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13574    (clobber (reg:CC FLAGS_REG))]
13575   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13576   "@
13577    rol{w}\t{%2, %0|%0, %2}
13578    rol{w}\t{%b2, %0|%0, %b2}"
13579   [(set_attr "type" "rotate")
13580    (set_attr "mode" "HI")])
13581
13582 (define_split
13583  [(set (match_operand:HI 0 "register_operand" "")
13584        (rotate:HI (match_dup 0) (const_int 8)))
13585   (clobber (reg:CC FLAGS_REG))]
13586  "reload_completed"
13587  [(parallel [(set (strict_low_part (match_dup 0))
13588                   (bswap:HI (match_dup 0)))
13589              (clobber (reg:CC FLAGS_REG))])]
13590  "")
13591
13592 (define_expand "rotlqi3"
13593   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13594         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13595                    (match_operand:QI 2 "nonmemory_operand" "")))]
13596   "TARGET_QIMODE_MATH"
13597   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13598
13599 (define_insn "*rotlqi3_1_one_bit_slp"
13600   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13601         (rotate:QI (match_dup 0)
13602                    (match_operand:QI 1 "const1_operand" "")))
13603    (clobber (reg:CC FLAGS_REG))]
13604   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13605    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13606   "rol{b}\t%0"
13607   [(set_attr "type" "rotate1")
13608    (set (attr "length")
13609      (if_then_else (match_operand 0 "register_operand" "")
13610         (const_string "2")
13611         (const_string "*")))])
13612
13613 (define_insn "*rotlqi3_1_one_bit"
13614   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13615         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13616                    (match_operand:QI 2 "const1_operand" "")))
13617    (clobber (reg:CC FLAGS_REG))]
13618   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13619    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13620   "rol{b}\t%0"
13621   [(set_attr "type" "rotate")
13622    (set (attr "length")
13623      (if_then_else (match_operand 0 "register_operand" "")
13624         (const_string "2")
13625         (const_string "*")))])
13626
13627 (define_insn "*rotlqi3_1_slp"
13628   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13629         (rotate:QI (match_dup 0)
13630                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13631    (clobber (reg:CC FLAGS_REG))]
13632   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13633    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13634   "@
13635    rol{b}\t{%1, %0|%0, %1}
13636    rol{b}\t{%b1, %0|%0, %b1}"
13637   [(set_attr "type" "rotate1")
13638    (set_attr "mode" "QI")])
13639
13640 (define_insn "*rotlqi3_1"
13641   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13642         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13643                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13644    (clobber (reg:CC FLAGS_REG))]
13645   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13646   "@
13647    rol{b}\t{%2, %0|%0, %2}
13648    rol{b}\t{%b2, %0|%0, %b2}"
13649   [(set_attr "type" "rotate")
13650    (set_attr "mode" "QI")])
13651
13652 (define_expand "rotrdi3"
13653   [(set (match_operand:DI 0 "shiftdi_operand" "")
13654         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13655                    (match_operand:QI 2 "nonmemory_operand" "")))]
13656  ""
13657 {
13658   if (TARGET_64BIT)
13659     {
13660       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13661       DONE;
13662     }
13663   if (!const_1_to_31_operand (operands[2], VOIDmode))
13664     FAIL;
13665   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13666   DONE;
13667 })
13668
13669 ;; Implement rotation using two double-precision shift instructions
13670 ;; and a scratch register.
13671 (define_insn_and_split "ix86_rotrdi3"
13672  [(set (match_operand:DI 0 "register_operand" "=r")
13673        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13674                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13675   (clobber (reg:CC FLAGS_REG))
13676   (clobber (match_scratch:SI 3 "=&r"))]
13677  "!TARGET_64BIT"
13678  ""
13679  "&& reload_completed"
13680  [(set (match_dup 3) (match_dup 4))
13681   (parallel
13682    [(set (match_dup 4)
13683          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13684                  (ashift:SI (match_dup 5)
13685                             (minus:QI (const_int 32) (match_dup 2)))))
13686     (clobber (reg:CC FLAGS_REG))])
13687   (parallel
13688    [(set (match_dup 5)
13689          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13690                  (ashift:SI (match_dup 3)
13691                             (minus:QI (const_int 32) (match_dup 2)))))
13692     (clobber (reg:CC FLAGS_REG))])]
13693  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13694
13695 (define_insn "*rotrdi3_1_one_bit_rex64"
13696   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13697         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13698                      (match_operand:QI 2 "const1_operand" "")))
13699    (clobber (reg:CC FLAGS_REG))]
13700   "TARGET_64BIT
13701    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13702    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13703   "ror{q}\t%0"
13704   [(set_attr "type" "rotate")
13705    (set (attr "length")
13706      (if_then_else (match_operand:DI 0 "register_operand" "")
13707         (const_string "2")
13708         (const_string "*")))])
13709
13710 (define_insn "*rotrdi3_1_rex64"
13711   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13712         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13713                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13714    (clobber (reg:CC FLAGS_REG))]
13715   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13716   "@
13717    ror{q}\t{%2, %0|%0, %2}
13718    ror{q}\t{%b2, %0|%0, %b2}"
13719   [(set_attr "type" "rotate")
13720    (set_attr "mode" "DI")])
13721
13722 (define_expand "rotrsi3"
13723   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13724         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13725                      (match_operand:QI 2 "nonmemory_operand" "")))]
13726   ""
13727   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13728
13729 (define_insn "*rotrsi3_1_one_bit"
13730   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13731         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13732                      (match_operand:QI 2 "const1_operand" "")))
13733    (clobber (reg:CC FLAGS_REG))]
13734   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13735    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13736   "ror{l}\t%0"
13737   [(set_attr "type" "rotate")
13738    (set (attr "length")
13739      (if_then_else (match_operand:SI 0 "register_operand" "")
13740         (const_string "2")
13741         (const_string "*")))])
13742
13743 (define_insn "*rotrsi3_1_one_bit_zext"
13744   [(set (match_operand:DI 0 "register_operand" "=r")
13745         (zero_extend:DI
13746           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13747                        (match_operand:QI 2 "const1_operand" ""))))
13748    (clobber (reg:CC FLAGS_REG))]
13749   "TARGET_64BIT
13750    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13751    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13752   "ror{l}\t%k0"
13753   [(set_attr "type" "rotate")
13754    (set (attr "length")
13755      (if_then_else (match_operand:SI 0 "register_operand" "")
13756         (const_string "2")
13757         (const_string "*")))])
13758
13759 (define_insn "*rotrsi3_1"
13760   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13761         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13762                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13763    (clobber (reg:CC FLAGS_REG))]
13764   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13765   "@
13766    ror{l}\t{%2, %0|%0, %2}
13767    ror{l}\t{%b2, %0|%0, %b2}"
13768   [(set_attr "type" "rotate")
13769    (set_attr "mode" "SI")])
13770
13771 (define_insn "*rotrsi3_1_zext"
13772   [(set (match_operand:DI 0 "register_operand" "=r,r")
13773         (zero_extend:DI
13774           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13775                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13776    (clobber (reg:CC FLAGS_REG))]
13777   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13778   "@
13779    ror{l}\t{%2, %k0|%k0, %2}
13780    ror{l}\t{%b2, %k0|%k0, %b2}"
13781   [(set_attr "type" "rotate")
13782    (set_attr "mode" "SI")])
13783
13784 (define_expand "rotrhi3"
13785   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13786         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13787                      (match_operand:QI 2 "nonmemory_operand" "")))]
13788   "TARGET_HIMODE_MATH"
13789   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13790
13791 (define_insn "*rotrhi3_one_bit"
13792   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13793         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13794                      (match_operand:QI 2 "const1_operand" "")))
13795    (clobber (reg:CC FLAGS_REG))]
13796   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13797    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13798   "ror{w}\t%0"
13799   [(set_attr "type" "rotate")
13800    (set (attr "length")
13801      (if_then_else (match_operand 0 "register_operand" "")
13802         (const_string "2")
13803         (const_string "*")))])
13804
13805 (define_insn "*rotrhi3_1"
13806   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13807         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13808                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13809    (clobber (reg:CC FLAGS_REG))]
13810   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13811   "@
13812    ror{w}\t{%2, %0|%0, %2}
13813    ror{w}\t{%b2, %0|%0, %b2}"
13814   [(set_attr "type" "rotate")
13815    (set_attr "mode" "HI")])
13816
13817 (define_split
13818  [(set (match_operand:HI 0 "register_operand" "")
13819        (rotatert:HI (match_dup 0) (const_int 8)))
13820   (clobber (reg:CC FLAGS_REG))]
13821  "reload_completed"
13822  [(parallel [(set (strict_low_part (match_dup 0))
13823                   (bswap:HI (match_dup 0)))
13824              (clobber (reg:CC FLAGS_REG))])]
13825  "")
13826
13827 (define_expand "rotrqi3"
13828   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13829         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13830                      (match_operand:QI 2 "nonmemory_operand" "")))]
13831   "TARGET_QIMODE_MATH"
13832   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13833
13834 (define_insn "*rotrqi3_1_one_bit"
13835   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13836         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13837                      (match_operand:QI 2 "const1_operand" "")))
13838    (clobber (reg:CC FLAGS_REG))]
13839   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13840    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13841   "ror{b}\t%0"
13842   [(set_attr "type" "rotate")
13843    (set (attr "length")
13844      (if_then_else (match_operand 0 "register_operand" "")
13845         (const_string "2")
13846         (const_string "*")))])
13847
13848 (define_insn "*rotrqi3_1_one_bit_slp"
13849   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13850         (rotatert:QI (match_dup 0)
13851                      (match_operand:QI 1 "const1_operand" "")))
13852    (clobber (reg:CC FLAGS_REG))]
13853   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13854    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13855   "ror{b}\t%0"
13856   [(set_attr "type" "rotate1")
13857    (set (attr "length")
13858      (if_then_else (match_operand 0 "register_operand" "")
13859         (const_string "2")
13860         (const_string "*")))])
13861
13862 (define_insn "*rotrqi3_1"
13863   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13864         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13865                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13866    (clobber (reg:CC FLAGS_REG))]
13867   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13868   "@
13869    ror{b}\t{%2, %0|%0, %2}
13870    ror{b}\t{%b2, %0|%0, %b2}"
13871   [(set_attr "type" "rotate")
13872    (set_attr "mode" "QI")])
13873
13874 (define_insn "*rotrqi3_1_slp"
13875   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13876         (rotatert:QI (match_dup 0)
13877                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13878    (clobber (reg:CC FLAGS_REG))]
13879   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13880    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13881   "@
13882    ror{b}\t{%1, %0|%0, %1}
13883    ror{b}\t{%b1, %0|%0, %b1}"
13884   [(set_attr "type" "rotate1")
13885    (set_attr "mode" "QI")])
13886 \f
13887 ;; Bit set / bit test instructions
13888
13889 (define_expand "extv"
13890   [(set (match_operand:SI 0 "register_operand" "")
13891         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13892                          (match_operand:SI 2 "const8_operand" "")
13893                          (match_operand:SI 3 "const8_operand" "")))]
13894   ""
13895 {
13896   /* Handle extractions from %ah et al.  */
13897   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13898     FAIL;
13899
13900   /* From mips.md: extract_bit_field doesn't verify that our source
13901      matches the predicate, so check it again here.  */
13902   if (! ext_register_operand (operands[1], VOIDmode))
13903     FAIL;
13904 })
13905
13906 (define_expand "extzv"
13907   [(set (match_operand:SI 0 "register_operand" "")
13908         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13909                          (match_operand:SI 2 "const8_operand" "")
13910                          (match_operand:SI 3 "const8_operand" "")))]
13911   ""
13912 {
13913   /* Handle extractions from %ah et al.  */
13914   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13915     FAIL;
13916
13917   /* From mips.md: extract_bit_field doesn't verify that our source
13918      matches the predicate, so check it again here.  */
13919   if (! ext_register_operand (operands[1], VOIDmode))
13920     FAIL;
13921 })
13922
13923 (define_expand "insv"
13924   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13925                       (match_operand 1 "const8_operand" "")
13926                       (match_operand 2 "const8_operand" ""))
13927         (match_operand 3 "register_operand" ""))]
13928   ""
13929 {
13930   /* Handle insertions to %ah et al.  */
13931   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13932     FAIL;
13933
13934   /* From mips.md: insert_bit_field doesn't verify that our source
13935      matches the predicate, so check it again here.  */
13936   if (! ext_register_operand (operands[0], VOIDmode))
13937     FAIL;
13938
13939   if (TARGET_64BIT)
13940     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13941   else
13942     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13943
13944   DONE;
13945 })
13946
13947 ;; %%% bts, btr, btc, bt.
13948 ;; In general these instructions are *slow* when applied to memory,
13949 ;; since they enforce atomic operation.  When applied to registers,
13950 ;; it depends on the cpu implementation.  They're never faster than
13951 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13952 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13953 ;; within the instruction itself, so operating on bits in the high
13954 ;; 32-bits of a register becomes easier.
13955 ;;
13956 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13957 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13958 ;; negdf respectively, so they can never be disabled entirely.
13959
13960 (define_insn "*btsq"
13961   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13962                          (const_int 1)
13963                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13964         (const_int 1))
13965    (clobber (reg:CC FLAGS_REG))]
13966   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13967   "bts{q}\t{%1, %0|%0, %1}"
13968   [(set_attr "type" "alu1")])
13969
13970 (define_insn "*btrq"
13971   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13972                          (const_int 1)
13973                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13974         (const_int 0))
13975    (clobber (reg:CC FLAGS_REG))]
13976   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13977   "btr{q}\t{%1, %0|%0, %1}"
13978   [(set_attr "type" "alu1")])
13979
13980 (define_insn "*btcq"
13981   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13982                          (const_int 1)
13983                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13984         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13985    (clobber (reg:CC FLAGS_REG))]
13986   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13987   "btc{q}\t{%1, %0|%0, %1}"
13988   [(set_attr "type" "alu1")])
13989
13990 ;; Allow Nocona to avoid these instructions if a register is available.
13991
13992 (define_peephole2
13993   [(match_scratch:DI 2 "r")
13994    (parallel [(set (zero_extract:DI
13995                      (match_operand:DI 0 "register_operand" "")
13996                      (const_int 1)
13997                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13998                    (const_int 1))
13999               (clobber (reg:CC FLAGS_REG))])]
14000   "TARGET_64BIT && !TARGET_USE_BT"
14001   [(const_int 0)]
14002 {
14003   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14004   rtx op1;
14005
14006   if (HOST_BITS_PER_WIDE_INT >= 64)
14007     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14008   else if (i < HOST_BITS_PER_WIDE_INT)
14009     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14010   else
14011     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14012
14013   op1 = immed_double_const (lo, hi, DImode);
14014   if (i >= 31)
14015     {
14016       emit_move_insn (operands[2], op1);
14017       op1 = operands[2];
14018     }
14019
14020   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14021   DONE;
14022 })
14023
14024 (define_peephole2
14025   [(match_scratch:DI 2 "r")
14026    (parallel [(set (zero_extract:DI
14027                      (match_operand:DI 0 "register_operand" "")
14028                      (const_int 1)
14029                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14030                    (const_int 0))
14031               (clobber (reg:CC FLAGS_REG))])]
14032   "TARGET_64BIT && !TARGET_USE_BT"
14033   [(const_int 0)]
14034 {
14035   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14036   rtx op1;
14037
14038   if (HOST_BITS_PER_WIDE_INT >= 64)
14039     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14040   else if (i < HOST_BITS_PER_WIDE_INT)
14041     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14042   else
14043     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14044
14045   op1 = immed_double_const (~lo, ~hi, DImode);
14046   if (i >= 32)
14047     {
14048       emit_move_insn (operands[2], op1);
14049       op1 = operands[2];
14050     }
14051
14052   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14053   DONE;
14054 })
14055
14056 (define_peephole2
14057   [(match_scratch:DI 2 "r")
14058    (parallel [(set (zero_extract:DI
14059                      (match_operand:DI 0 "register_operand" "")
14060                      (const_int 1)
14061                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14062               (not:DI (zero_extract:DI
14063                         (match_dup 0) (const_int 1) (match_dup 1))))
14064               (clobber (reg:CC FLAGS_REG))])]
14065   "TARGET_64BIT && !TARGET_USE_BT"
14066   [(const_int 0)]
14067 {
14068   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14069   rtx op1;
14070
14071   if (HOST_BITS_PER_WIDE_INT >= 64)
14072     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14073   else if (i < HOST_BITS_PER_WIDE_INT)
14074     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14075   else
14076     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14077
14078   op1 = immed_double_const (lo, hi, DImode);
14079   if (i >= 31)
14080     {
14081       emit_move_insn (operands[2], op1);
14082       op1 = operands[2];
14083     }
14084
14085   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14086   DONE;
14087 })
14088
14089 (define_insn "*btdi_rex64"
14090   [(set (reg:CCC FLAGS_REG)
14091         (compare:CCC
14092           (zero_extract:DI
14093             (match_operand:DI 0 "register_operand" "r")
14094             (const_int 1)
14095             (match_operand:DI 1 "nonmemory_operand" "rN"))
14096           (const_int 0)))]
14097   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14098   "bt{q}\t{%1, %0|%0, %1}"
14099   [(set_attr "type" "alu1")])
14100
14101 (define_insn "*btsi"
14102   [(set (reg:CCC FLAGS_REG)
14103         (compare:CCC
14104           (zero_extract:SI
14105             (match_operand:SI 0 "register_operand" "r")
14106             (const_int 1)
14107             (match_operand:SI 1 "nonmemory_operand" "rN"))
14108           (const_int 0)))]
14109   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14110   "bt{l}\t{%1, %0|%0, %1}"
14111   [(set_attr "type" "alu1")])
14112 \f
14113 ;; Store-flag instructions.
14114
14115 ;; For all sCOND expanders, also expand the compare or test insn that
14116 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14117
14118 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14119 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14120 ;; way, which can later delete the movzx if only QImode is needed.
14121
14122 (define_expand "s<code>"
14123   [(set (match_operand:QI 0 "register_operand" "")
14124         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14125   ""
14126   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14127
14128 (define_expand "s<code>"
14129   [(set (match_operand:QI 0 "register_operand" "")
14130         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14131   "TARGET_80387 || TARGET_SSE"
14132   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14133
14134 (define_insn "*setcc_1"
14135   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14136         (match_operator:QI 1 "ix86_comparison_operator"
14137           [(reg FLAGS_REG) (const_int 0)]))]
14138   ""
14139   "set%C1\t%0"
14140   [(set_attr "type" "setcc")
14141    (set_attr "mode" "QI")])
14142
14143 (define_insn "*setcc_2"
14144   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14145         (match_operator:QI 1 "ix86_comparison_operator"
14146           [(reg FLAGS_REG) (const_int 0)]))]
14147   ""
14148   "set%C1\t%0"
14149   [(set_attr "type" "setcc")
14150    (set_attr "mode" "QI")])
14151
14152 ;; In general it is not safe to assume too much about CCmode registers,
14153 ;; so simplify-rtx stops when it sees a second one.  Under certain
14154 ;; conditions this is safe on x86, so help combine not create
14155 ;;
14156 ;;      seta    %al
14157 ;;      testb   %al, %al
14158 ;;      sete    %al
14159
14160 (define_split
14161   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14162         (ne:QI (match_operator 1 "ix86_comparison_operator"
14163                  [(reg FLAGS_REG) (const_int 0)])
14164             (const_int 0)))]
14165   ""
14166   [(set (match_dup 0) (match_dup 1))]
14167 {
14168   PUT_MODE (operands[1], QImode);
14169 })
14170
14171 (define_split
14172   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14173         (ne:QI (match_operator 1 "ix86_comparison_operator"
14174                  [(reg FLAGS_REG) (const_int 0)])
14175             (const_int 0)))]
14176   ""
14177   [(set (match_dup 0) (match_dup 1))]
14178 {
14179   PUT_MODE (operands[1], QImode);
14180 })
14181
14182 (define_split
14183   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14184         (eq:QI (match_operator 1 "ix86_comparison_operator"
14185                  [(reg FLAGS_REG) (const_int 0)])
14186             (const_int 0)))]
14187   ""
14188   [(set (match_dup 0) (match_dup 1))]
14189 {
14190   rtx new_op1 = copy_rtx (operands[1]);
14191   operands[1] = new_op1;
14192   PUT_MODE (new_op1, QImode);
14193   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14194                                              GET_MODE (XEXP (new_op1, 0))));
14195
14196   /* Make sure that (a) the CCmode we have for the flags is strong
14197      enough for the reversed compare or (b) we have a valid FP compare.  */
14198   if (! ix86_comparison_operator (new_op1, VOIDmode))
14199     FAIL;
14200 })
14201
14202 (define_split
14203   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14204         (eq:QI (match_operator 1 "ix86_comparison_operator"
14205                  [(reg FLAGS_REG) (const_int 0)])
14206             (const_int 0)))]
14207   ""
14208   [(set (match_dup 0) (match_dup 1))]
14209 {
14210   rtx new_op1 = copy_rtx (operands[1]);
14211   operands[1] = new_op1;
14212   PUT_MODE (new_op1, QImode);
14213   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14214                                              GET_MODE (XEXP (new_op1, 0))));
14215
14216   /* Make sure that (a) the CCmode we have for the flags is strong
14217      enough for the reversed compare or (b) we have a valid FP compare.  */
14218   if (! ix86_comparison_operator (new_op1, VOIDmode))
14219     FAIL;
14220 })
14221
14222 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14223 ;; subsequent logical operations are used to imitate conditional moves.
14224 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14225 ;; it directly.
14226
14227 (define_insn "*avx_setcc<mode>"
14228   [(set (match_operand:MODEF 0 "register_operand" "=x")
14229         (match_operator:MODEF 1 "avx_comparison_float_operator"
14230           [(match_operand:MODEF 2 "register_operand" "x")
14231            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14232   "TARGET_AVX"
14233   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14234   [(set_attr "type" "ssecmp")
14235    (set_attr "prefix" "vex")
14236    (set_attr "mode" "<MODE>")])
14237
14238 (define_insn "*sse_setcc<mode>"
14239   [(set (match_operand:MODEF 0 "register_operand" "=x")
14240         (match_operator:MODEF 1 "sse_comparison_operator"
14241           [(match_operand:MODEF 2 "register_operand" "0")
14242            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14243   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14244   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14245   [(set_attr "type" "ssecmp")
14246    (set_attr "mode" "<MODE>")])
14247
14248 (define_insn "*sse5_setcc<mode>"
14249   [(set (match_operand:MODEF 0 "register_operand" "=x")
14250         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14251           [(match_operand:MODEF 2 "register_operand" "x")
14252            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14253   "TARGET_SSE5"
14254   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14255   [(set_attr "type" "sse4arg")
14256    (set_attr "mode" "<MODE>")])
14257
14258 \f
14259 ;; Basic conditional jump instructions.
14260 ;; We ignore the overflow flag for signed branch instructions.
14261
14262 ;; For all bCOND expanders, also expand the compare or test insn that
14263 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14264
14265 (define_expand "b<code>"
14266   [(set (pc)
14267         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14268                                    (const_int 0))
14269                       (label_ref (match_operand 0 ""))
14270                       (pc)))]
14271   ""
14272   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14273
14274 (define_expand "b<code>"
14275   [(set (pc)
14276         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14277                                   (const_int 0))
14278                       (label_ref (match_operand 0 ""))
14279                       (pc)))]
14280   "TARGET_80387 || TARGET_SSE_MATH"
14281   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14282
14283 (define_insn "*jcc_1"
14284   [(set (pc)
14285         (if_then_else (match_operator 1 "ix86_comparison_operator"
14286                                       [(reg FLAGS_REG) (const_int 0)])
14287                       (label_ref (match_operand 0 "" ""))
14288                       (pc)))]
14289   ""
14290   "%+j%C1\t%l0"
14291   [(set_attr "type" "ibr")
14292    (set_attr "modrm" "0")
14293    (set (attr "length")
14294            (if_then_else (and (ge (minus (match_dup 0) (pc))
14295                                   (const_int -126))
14296                               (lt (minus (match_dup 0) (pc))
14297                                   (const_int 128)))
14298              (const_int 2)
14299              (const_int 6)))])
14300
14301 (define_insn "*jcc_2"
14302   [(set (pc)
14303         (if_then_else (match_operator 1 "ix86_comparison_operator"
14304                                       [(reg FLAGS_REG) (const_int 0)])
14305                       (pc)
14306                       (label_ref (match_operand 0 "" ""))))]
14307   ""
14308   "%+j%c1\t%l0"
14309   [(set_attr "type" "ibr")
14310    (set_attr "modrm" "0")
14311    (set (attr "length")
14312            (if_then_else (and (ge (minus (match_dup 0) (pc))
14313                                   (const_int -126))
14314                               (lt (minus (match_dup 0) (pc))
14315                                   (const_int 128)))
14316              (const_int 2)
14317              (const_int 6)))])
14318
14319 ;; In general it is not safe to assume too much about CCmode registers,
14320 ;; so simplify-rtx stops when it sees a second one.  Under certain
14321 ;; conditions this is safe on x86, so help combine not create
14322 ;;
14323 ;;      seta    %al
14324 ;;      testb   %al, %al
14325 ;;      je      Lfoo
14326
14327 (define_split
14328   [(set (pc)
14329         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14330                                       [(reg FLAGS_REG) (const_int 0)])
14331                           (const_int 0))
14332                       (label_ref (match_operand 1 "" ""))
14333                       (pc)))]
14334   ""
14335   [(set (pc)
14336         (if_then_else (match_dup 0)
14337                       (label_ref (match_dup 1))
14338                       (pc)))]
14339 {
14340   PUT_MODE (operands[0], VOIDmode);
14341 })
14342
14343 (define_split
14344   [(set (pc)
14345         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14346                                       [(reg FLAGS_REG) (const_int 0)])
14347                           (const_int 0))
14348                       (label_ref (match_operand 1 "" ""))
14349                       (pc)))]
14350   ""
14351   [(set (pc)
14352         (if_then_else (match_dup 0)
14353                       (label_ref (match_dup 1))
14354                       (pc)))]
14355 {
14356   rtx new_op0 = copy_rtx (operands[0]);
14357   operands[0] = new_op0;
14358   PUT_MODE (new_op0, VOIDmode);
14359   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14360                                              GET_MODE (XEXP (new_op0, 0))));
14361
14362   /* Make sure that (a) the CCmode we have for the flags is strong
14363      enough for the reversed compare or (b) we have a valid FP compare.  */
14364   if (! ix86_comparison_operator (new_op0, VOIDmode))
14365     FAIL;
14366 })
14367
14368 ;; zero_extend in SImode is correct, since this is what combine pass
14369 ;; generates from shift insn with QImode operand.  Actually, the mode of
14370 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14371 ;; appropriate modulo of the bit offset value.
14372
14373 (define_insn_and_split "*jcc_btdi_rex64"
14374   [(set (pc)
14375         (if_then_else (match_operator 0 "bt_comparison_operator"
14376                         [(zero_extract:DI
14377                            (match_operand:DI 1 "register_operand" "r")
14378                            (const_int 1)
14379                            (zero_extend:SI
14380                              (match_operand:QI 2 "register_operand" "r")))
14381                          (const_int 0)])
14382                       (label_ref (match_operand 3 "" ""))
14383                       (pc)))
14384    (clobber (reg:CC FLAGS_REG))]
14385   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14386   "#"
14387   "&& 1"
14388   [(set (reg:CCC FLAGS_REG)
14389         (compare:CCC
14390           (zero_extract:DI
14391             (match_dup 1)
14392             (const_int 1)
14393             (match_dup 2))
14394           (const_int 0)))
14395    (set (pc)
14396         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14397                       (label_ref (match_dup 3))
14398                       (pc)))]
14399 {
14400   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14401
14402   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14403 })
14404
14405 ;; avoid useless masking of bit offset operand
14406 (define_insn_and_split "*jcc_btdi_mask_rex64"
14407   [(set (pc)
14408         (if_then_else (match_operator 0 "bt_comparison_operator"
14409                         [(zero_extract:DI
14410                            (match_operand:DI 1 "register_operand" "r")
14411                            (const_int 1)
14412                            (and:SI
14413                              (match_operand:SI 2 "register_operand" "r")
14414                              (match_operand:SI 3 "const_int_operand" "n")))])
14415                       (label_ref (match_operand 4 "" ""))
14416                       (pc)))
14417    (clobber (reg:CC FLAGS_REG))]
14418   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14419    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14420   "#"
14421   "&& 1"
14422   [(set (reg:CCC FLAGS_REG)
14423         (compare:CCC
14424           (zero_extract:DI
14425             (match_dup 1)
14426             (const_int 1)
14427             (match_dup 2))
14428           (const_int 0)))
14429    (set (pc)
14430         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14431                       (label_ref (match_dup 4))
14432                       (pc)))]
14433 {
14434   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14435
14436   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14437 })
14438
14439 (define_insn_and_split "*jcc_btsi"
14440   [(set (pc)
14441         (if_then_else (match_operator 0 "bt_comparison_operator"
14442                         [(zero_extract:SI
14443                            (match_operand:SI 1 "register_operand" "r")
14444                            (const_int 1)
14445                            (zero_extend:SI
14446                              (match_operand:QI 2 "register_operand" "r")))
14447                          (const_int 0)])
14448                       (label_ref (match_operand 3 "" ""))
14449                       (pc)))
14450    (clobber (reg:CC FLAGS_REG))]
14451   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14452   "#"
14453   "&& 1"
14454   [(set (reg:CCC FLAGS_REG)
14455         (compare:CCC
14456           (zero_extract:SI
14457             (match_dup 1)
14458             (const_int 1)
14459             (match_dup 2))
14460           (const_int 0)))
14461    (set (pc)
14462         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14463                       (label_ref (match_dup 3))
14464                       (pc)))]
14465 {
14466   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14467
14468   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14469 })
14470
14471 ;; avoid useless masking of bit offset operand
14472 (define_insn_and_split "*jcc_btsi_mask"
14473   [(set (pc)
14474         (if_then_else (match_operator 0 "bt_comparison_operator"
14475                         [(zero_extract:SI
14476                            (match_operand:SI 1 "register_operand" "r")
14477                            (const_int 1)
14478                            (and:SI
14479                              (match_operand:SI 2 "register_operand" "r")
14480                              (match_operand:SI 3 "const_int_operand" "n")))])
14481                       (label_ref (match_operand 4 "" ""))
14482                       (pc)))
14483    (clobber (reg:CC FLAGS_REG))]
14484   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14485    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14486   "#"
14487   "&& 1"
14488   [(set (reg:CCC FLAGS_REG)
14489         (compare:CCC
14490           (zero_extract:SI
14491             (match_dup 1)
14492             (const_int 1)
14493             (match_dup 2))
14494           (const_int 0)))
14495    (set (pc)
14496         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14497                       (label_ref (match_dup 4))
14498                       (pc)))]
14499   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14500
14501 (define_insn_and_split "*jcc_btsi_1"
14502   [(set (pc)
14503         (if_then_else (match_operator 0 "bt_comparison_operator"
14504                         [(and:SI
14505                            (lshiftrt:SI
14506                              (match_operand:SI 1 "register_operand" "r")
14507                              (match_operand:QI 2 "register_operand" "r"))
14508                            (const_int 1))
14509                          (const_int 0)])
14510                       (label_ref (match_operand 3 "" ""))
14511                       (pc)))
14512    (clobber (reg:CC FLAGS_REG))]
14513   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14514   "#"
14515   "&& 1"
14516   [(set (reg:CCC FLAGS_REG)
14517         (compare:CCC
14518           (zero_extract:SI
14519             (match_dup 1)
14520             (const_int 1)
14521             (match_dup 2))
14522           (const_int 0)))
14523    (set (pc)
14524         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14525                       (label_ref (match_dup 3))
14526                       (pc)))]
14527 {
14528   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14529
14530   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14531 })
14532
14533 ;; avoid useless masking of bit offset operand
14534 (define_insn_and_split "*jcc_btsi_mask_1"
14535   [(set (pc)
14536         (if_then_else
14537           (match_operator 0 "bt_comparison_operator"
14538             [(and:SI
14539                (lshiftrt:SI
14540                  (match_operand:SI 1 "register_operand" "r")
14541                  (subreg:QI
14542                    (and:SI
14543                      (match_operand:SI 2 "register_operand" "r")
14544                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14545                (const_int 1))
14546              (const_int 0)])
14547           (label_ref (match_operand 4 "" ""))
14548           (pc)))
14549    (clobber (reg:CC FLAGS_REG))]
14550   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14551    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14552   "#"
14553   "&& 1"
14554   [(set (reg:CCC FLAGS_REG)
14555         (compare:CCC
14556           (zero_extract:SI
14557             (match_dup 1)
14558             (const_int 1)
14559             (match_dup 2))
14560           (const_int 0)))
14561    (set (pc)
14562         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14563                       (label_ref (match_dup 4))
14564                       (pc)))]
14565   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14566
14567 ;; Define combination compare-and-branch fp compare instructions to use
14568 ;; during early optimization.  Splitting the operation apart early makes
14569 ;; for bad code when we want to reverse the operation.
14570
14571 (define_insn "*fp_jcc_1_mixed"
14572   [(set (pc)
14573         (if_then_else (match_operator 0 "comparison_operator"
14574                         [(match_operand 1 "register_operand" "f,x")
14575                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14576           (label_ref (match_operand 3 "" ""))
14577           (pc)))
14578    (clobber (reg:CCFP FPSR_REG))
14579    (clobber (reg:CCFP FLAGS_REG))]
14580   "TARGET_MIX_SSE_I387
14581    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14582    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14583    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14584   "#")
14585
14586 (define_insn "*fp_jcc_1_sse"
14587   [(set (pc)
14588         (if_then_else (match_operator 0 "comparison_operator"
14589                         [(match_operand 1 "register_operand" "x")
14590                          (match_operand 2 "nonimmediate_operand" "xm")])
14591           (label_ref (match_operand 3 "" ""))
14592           (pc)))
14593    (clobber (reg:CCFP FPSR_REG))
14594    (clobber (reg:CCFP FLAGS_REG))]
14595   "TARGET_SSE_MATH
14596    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14597    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14598    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14599   "#")
14600
14601 (define_insn "*fp_jcc_1_387"
14602   [(set (pc)
14603         (if_then_else (match_operator 0 "comparison_operator"
14604                         [(match_operand 1 "register_operand" "f")
14605                          (match_operand 2 "register_operand" "f")])
14606           (label_ref (match_operand 3 "" ""))
14607           (pc)))
14608    (clobber (reg:CCFP FPSR_REG))
14609    (clobber (reg:CCFP FLAGS_REG))]
14610   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14611    && TARGET_CMOVE
14612    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14613    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14614   "#")
14615
14616 (define_insn "*fp_jcc_2_mixed"
14617   [(set (pc)
14618         (if_then_else (match_operator 0 "comparison_operator"
14619                         [(match_operand 1 "register_operand" "f,x")
14620                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14621           (pc)
14622           (label_ref (match_operand 3 "" ""))))
14623    (clobber (reg:CCFP FPSR_REG))
14624    (clobber (reg:CCFP FLAGS_REG))]
14625   "TARGET_MIX_SSE_I387
14626    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14627    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14628    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14629   "#")
14630
14631 (define_insn "*fp_jcc_2_sse"
14632   [(set (pc)
14633         (if_then_else (match_operator 0 "comparison_operator"
14634                         [(match_operand 1 "register_operand" "x")
14635                          (match_operand 2 "nonimmediate_operand" "xm")])
14636           (pc)
14637           (label_ref (match_operand 3 "" ""))))
14638    (clobber (reg:CCFP FPSR_REG))
14639    (clobber (reg:CCFP FLAGS_REG))]
14640   "TARGET_SSE_MATH
14641    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14642    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14643    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14644   "#")
14645
14646 (define_insn "*fp_jcc_2_387"
14647   [(set (pc)
14648         (if_then_else (match_operator 0 "comparison_operator"
14649                         [(match_operand 1 "register_operand" "f")
14650                          (match_operand 2 "register_operand" "f")])
14651           (pc)
14652           (label_ref (match_operand 3 "" ""))))
14653    (clobber (reg:CCFP FPSR_REG))
14654    (clobber (reg:CCFP FLAGS_REG))]
14655   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14656    && TARGET_CMOVE
14657    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14658    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14659   "#")
14660
14661 (define_insn "*fp_jcc_3_387"
14662   [(set (pc)
14663         (if_then_else (match_operator 0 "comparison_operator"
14664                         [(match_operand 1 "register_operand" "f")
14665                          (match_operand 2 "nonimmediate_operand" "fm")])
14666           (label_ref (match_operand 3 "" ""))
14667           (pc)))
14668    (clobber (reg:CCFP FPSR_REG))
14669    (clobber (reg:CCFP FLAGS_REG))
14670    (clobber (match_scratch:HI 4 "=a"))]
14671   "TARGET_80387
14672    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14673    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14674    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14675    && SELECT_CC_MODE (GET_CODE (operands[0]),
14676                       operands[1], operands[2]) == CCFPmode
14677    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14678   "#")
14679
14680 (define_insn "*fp_jcc_4_387"
14681   [(set (pc)
14682         (if_then_else (match_operator 0 "comparison_operator"
14683                         [(match_operand 1 "register_operand" "f")
14684                          (match_operand 2 "nonimmediate_operand" "fm")])
14685           (pc)
14686           (label_ref (match_operand 3 "" ""))))
14687    (clobber (reg:CCFP FPSR_REG))
14688    (clobber (reg:CCFP FLAGS_REG))
14689    (clobber (match_scratch:HI 4 "=a"))]
14690   "TARGET_80387
14691    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14692    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14693    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14694    && SELECT_CC_MODE (GET_CODE (operands[0]),
14695                       operands[1], operands[2]) == CCFPmode
14696    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14697   "#")
14698
14699 (define_insn "*fp_jcc_5_387"
14700   [(set (pc)
14701         (if_then_else (match_operator 0 "comparison_operator"
14702                         [(match_operand 1 "register_operand" "f")
14703                          (match_operand 2 "register_operand" "f")])
14704           (label_ref (match_operand 3 "" ""))
14705           (pc)))
14706    (clobber (reg:CCFP FPSR_REG))
14707    (clobber (reg:CCFP FLAGS_REG))
14708    (clobber (match_scratch:HI 4 "=a"))]
14709   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14710    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14711    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14712   "#")
14713
14714 (define_insn "*fp_jcc_6_387"
14715   [(set (pc)
14716         (if_then_else (match_operator 0 "comparison_operator"
14717                         [(match_operand 1 "register_operand" "f")
14718                          (match_operand 2 "register_operand" "f")])
14719           (pc)
14720           (label_ref (match_operand 3 "" ""))))
14721    (clobber (reg:CCFP FPSR_REG))
14722    (clobber (reg:CCFP FLAGS_REG))
14723    (clobber (match_scratch:HI 4 "=a"))]
14724   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14725    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14726    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14727   "#")
14728
14729 (define_insn "*fp_jcc_7_387"
14730   [(set (pc)
14731         (if_then_else (match_operator 0 "comparison_operator"
14732                         [(match_operand 1 "register_operand" "f")
14733                          (match_operand 2 "const0_operand" "")])
14734           (label_ref (match_operand 3 "" ""))
14735           (pc)))
14736    (clobber (reg:CCFP FPSR_REG))
14737    (clobber (reg:CCFP FLAGS_REG))
14738    (clobber (match_scratch:HI 4 "=a"))]
14739   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14740    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14741    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14742    && SELECT_CC_MODE (GET_CODE (operands[0]),
14743                       operands[1], operands[2]) == CCFPmode
14744    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14745   "#")
14746
14747 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14748 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14749 ;; with a precedence over other operators and is always put in the first
14750 ;; place. Swap condition and operands to match ficom instruction.
14751
14752 (define_insn "*fp_jcc_8<mode>_387"
14753   [(set (pc)
14754         (if_then_else (match_operator 0 "comparison_operator"
14755                         [(match_operator 1 "float_operator"
14756                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14757                            (match_operand 3 "register_operand" "f,f")])
14758           (label_ref (match_operand 4 "" ""))
14759           (pc)))
14760    (clobber (reg:CCFP FPSR_REG))
14761    (clobber (reg:CCFP FLAGS_REG))
14762    (clobber (match_scratch:HI 5 "=a,a"))]
14763   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14764    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14765    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14766    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14767    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14768    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14769   "#")
14770
14771 (define_split
14772   [(set (pc)
14773         (if_then_else (match_operator 0 "comparison_operator"
14774                         [(match_operand 1 "register_operand" "")
14775                          (match_operand 2 "nonimmediate_operand" "")])
14776           (match_operand 3 "" "")
14777           (match_operand 4 "" "")))
14778    (clobber (reg:CCFP FPSR_REG))
14779    (clobber (reg:CCFP FLAGS_REG))]
14780   "reload_completed"
14781   [(const_int 0)]
14782 {
14783   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14784                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14785   DONE;
14786 })
14787
14788 (define_split
14789   [(set (pc)
14790         (if_then_else (match_operator 0 "comparison_operator"
14791                         [(match_operand 1 "register_operand" "")
14792                          (match_operand 2 "general_operand" "")])
14793           (match_operand 3 "" "")
14794           (match_operand 4 "" "")))
14795    (clobber (reg:CCFP FPSR_REG))
14796    (clobber (reg:CCFP FLAGS_REG))
14797    (clobber (match_scratch:HI 5 "=a"))]
14798   "reload_completed"
14799   [(const_int 0)]
14800 {
14801   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14802                         operands[3], operands[4], operands[5], NULL_RTX);
14803   DONE;
14804 })
14805
14806 (define_split
14807   [(set (pc)
14808         (if_then_else (match_operator 0 "comparison_operator"
14809                         [(match_operator 1 "float_operator"
14810                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14811                            (match_operand 3 "register_operand" "")])
14812           (match_operand 4 "" "")
14813           (match_operand 5 "" "")))
14814    (clobber (reg:CCFP FPSR_REG))
14815    (clobber (reg:CCFP FLAGS_REG))
14816    (clobber (match_scratch:HI 6 "=a"))]
14817   "reload_completed"
14818   [(const_int 0)]
14819 {
14820   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14821   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14822                         operands[3], operands[7],
14823                         operands[4], operands[5], operands[6], NULL_RTX);
14824   DONE;
14825 })
14826
14827 ;; %%% Kill this when reload knows how to do it.
14828 (define_split
14829   [(set (pc)
14830         (if_then_else (match_operator 0 "comparison_operator"
14831                         [(match_operator 1 "float_operator"
14832                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14833                            (match_operand 3 "register_operand" "")])
14834           (match_operand 4 "" "")
14835           (match_operand 5 "" "")))
14836    (clobber (reg:CCFP FPSR_REG))
14837    (clobber (reg:CCFP FLAGS_REG))
14838    (clobber (match_scratch:HI 6 "=a"))]
14839   "reload_completed"
14840   [(const_int 0)]
14841 {
14842   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14843   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14844   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14845                         operands[3], operands[7],
14846                         operands[4], operands[5], operands[6], operands[2]);
14847   DONE;
14848 })
14849 \f
14850 ;; Unconditional and other jump instructions
14851
14852 (define_insn "jump"
14853   [(set (pc)
14854         (label_ref (match_operand 0 "" "")))]
14855   ""
14856   "jmp\t%l0"
14857   [(set_attr "type" "ibr")
14858    (set (attr "length")
14859            (if_then_else (and (ge (minus (match_dup 0) (pc))
14860                                   (const_int -126))
14861                               (lt (minus (match_dup 0) (pc))
14862                                   (const_int 128)))
14863              (const_int 2)
14864              (const_int 5)))
14865    (set_attr "modrm" "0")])
14866
14867 (define_expand "indirect_jump"
14868   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14869   ""
14870   "")
14871
14872 (define_insn "*indirect_jump"
14873   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14874   ""
14875   "jmp\t%A0"
14876   [(set_attr "type" "ibr")
14877    (set_attr "length_immediate" "0")])
14878
14879 (define_expand "tablejump"
14880   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14881               (use (label_ref (match_operand 1 "" "")))])]
14882   ""
14883 {
14884   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14885      relative.  Convert the relative address to an absolute address.  */
14886   if (flag_pic)
14887     {
14888       rtx op0, op1;
14889       enum rtx_code code;
14890
14891       /* We can't use @GOTOFF for text labels on VxWorks;
14892          see gotoff_operand.  */
14893       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14894         {
14895           code = PLUS;
14896           op0 = operands[0];
14897           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14898         }
14899       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14900         {
14901           code = PLUS;
14902           op0 = operands[0];
14903           op1 = pic_offset_table_rtx;
14904         }
14905       else
14906         {
14907           code = MINUS;
14908           op0 = pic_offset_table_rtx;
14909           op1 = operands[0];
14910         }
14911
14912       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14913                                          OPTAB_DIRECT);
14914     }
14915 })
14916
14917 (define_insn "*tablejump_1"
14918   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14919    (use (label_ref (match_operand 1 "" "")))]
14920   ""
14921   "jmp\t%A0"
14922   [(set_attr "type" "ibr")
14923    (set_attr "length_immediate" "0")])
14924 \f
14925 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14926
14927 (define_peephole2
14928   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14929    (set (match_operand:QI 1 "register_operand" "")
14930         (match_operator:QI 2 "ix86_comparison_operator"
14931           [(reg FLAGS_REG) (const_int 0)]))
14932    (set (match_operand 3 "q_regs_operand" "")
14933         (zero_extend (match_dup 1)))]
14934   "(peep2_reg_dead_p (3, operands[1])
14935     || operands_match_p (operands[1], operands[3]))
14936    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14937   [(set (match_dup 4) (match_dup 0))
14938    (set (strict_low_part (match_dup 5))
14939         (match_dup 2))]
14940 {
14941   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14942   operands[5] = gen_lowpart (QImode, operands[3]);
14943   ix86_expand_clear (operands[3]);
14944 })
14945
14946 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14947
14948 (define_peephole2
14949   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14950    (set (match_operand:QI 1 "register_operand" "")
14951         (match_operator:QI 2 "ix86_comparison_operator"
14952           [(reg FLAGS_REG) (const_int 0)]))
14953    (parallel [(set (match_operand 3 "q_regs_operand" "")
14954                    (zero_extend (match_dup 1)))
14955               (clobber (reg:CC FLAGS_REG))])]
14956   "(peep2_reg_dead_p (3, operands[1])
14957     || operands_match_p (operands[1], operands[3]))
14958    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14959   [(set (match_dup 4) (match_dup 0))
14960    (set (strict_low_part (match_dup 5))
14961         (match_dup 2))]
14962 {
14963   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14964   operands[5] = gen_lowpart (QImode, operands[3]);
14965   ix86_expand_clear (operands[3]);
14966 })
14967 \f
14968 ;; Call instructions.
14969
14970 ;; The predicates normally associated with named expanders are not properly
14971 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14972 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14973
14974 ;; Call subroutine returning no value.
14975
14976 (define_expand "call_pop"
14977   [(parallel [(call (match_operand:QI 0 "" "")
14978                     (match_operand:SI 1 "" ""))
14979               (set (reg:SI SP_REG)
14980                    (plus:SI (reg:SI SP_REG)
14981                             (match_operand:SI 3 "" "")))])]
14982   "!TARGET_64BIT"
14983 {
14984   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14985   DONE;
14986 })
14987
14988 (define_insn "*call_pop_0"
14989   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14990          (match_operand:SI 1 "" ""))
14991    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14992                             (match_operand:SI 2 "immediate_operand" "")))]
14993   "!TARGET_64BIT"
14994 {
14995   if (SIBLING_CALL_P (insn))
14996     return "jmp\t%P0";
14997   else
14998     return "call\t%P0";
14999 }
15000   [(set_attr "type" "call")])
15001
15002 (define_insn "*call_pop_1"
15003   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15004          (match_operand:SI 1 "" ""))
15005    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15006                             (match_operand:SI 2 "immediate_operand" "i")))]
15007   "!TARGET_64BIT"
15008 {
15009   if (constant_call_address_operand (operands[0], Pmode))
15010     {
15011       if (SIBLING_CALL_P (insn))
15012         return "jmp\t%P0";
15013       else
15014         return "call\t%P0";
15015     }
15016   if (SIBLING_CALL_P (insn))
15017     return "jmp\t%A0";
15018   else
15019     return "call\t%A0";
15020 }
15021   [(set_attr "type" "call")])
15022
15023 (define_expand "call"
15024   [(call (match_operand:QI 0 "" "")
15025          (match_operand 1 "" ""))
15026    (use (match_operand 2 "" ""))]
15027   ""
15028 {
15029   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15030   DONE;
15031 })
15032
15033 (define_expand "sibcall"
15034   [(call (match_operand:QI 0 "" "")
15035          (match_operand 1 "" ""))
15036    (use (match_operand 2 "" ""))]
15037   ""
15038 {
15039   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15040   DONE;
15041 })
15042
15043 (define_insn "*call_0"
15044   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15045          (match_operand 1 "" ""))]
15046   ""
15047 {
15048   if (SIBLING_CALL_P (insn))
15049     return "jmp\t%P0";
15050   else
15051     return "call\t%P0";
15052 }
15053   [(set_attr "type" "call")])
15054
15055 (define_insn "*call_1"
15056   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15057          (match_operand 1 "" ""))]
15058   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15059 {
15060   if (constant_call_address_operand (operands[0], Pmode))
15061     return "call\t%P0";
15062   return "call\t%A0";
15063 }
15064   [(set_attr "type" "call")])
15065
15066 (define_insn "*sibcall_1"
15067   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15068          (match_operand 1 "" ""))]
15069   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15070 {
15071   if (constant_call_address_operand (operands[0], Pmode))
15072     return "jmp\t%P0";
15073   return "jmp\t%A0";
15074 }
15075   [(set_attr "type" "call")])
15076
15077 (define_insn "*call_1_rex64"
15078   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15079          (match_operand 1 "" ""))]
15080   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15081    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15082 {
15083   if (constant_call_address_operand (operands[0], Pmode))
15084     return "call\t%P0";
15085   return "call\t%A0";
15086 }
15087   [(set_attr "type" "call")])
15088
15089 (define_insn "*call_1_rex64_ms_sysv"
15090   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15091          (match_operand 1 "" ""))
15092    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15093    (clobber (reg:TI XMM6_REG))
15094    (clobber (reg:TI XMM7_REG))
15095    (clobber (reg:TI XMM8_REG))
15096    (clobber (reg:TI XMM9_REG))
15097    (clobber (reg:TI XMM10_REG))
15098    (clobber (reg:TI XMM11_REG))
15099    (clobber (reg:TI XMM12_REG))
15100    (clobber (reg:TI XMM13_REG))
15101    (clobber (reg:TI XMM14_REG))
15102    (clobber (reg:TI XMM15_REG))
15103    (clobber (reg:DI SI_REG))
15104    (clobber (reg:DI DI_REG))]
15105   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15106 {
15107   if (constant_call_address_operand (operands[0], Pmode))
15108     return "call\t%P0";
15109   return "call\t%A0";
15110 }
15111   [(set_attr "type" "call")])
15112
15113 (define_insn "*call_1_rex64_large"
15114   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15115          (match_operand 1 "" ""))]
15116   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15117   "call\t%A0"
15118   [(set_attr "type" "call")])
15119
15120 (define_insn "*sibcall_1_rex64"
15121   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15122          (match_operand 1 "" ""))]
15123   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15124   "jmp\t%P0"
15125   [(set_attr "type" "call")])
15126
15127 (define_insn "*sibcall_1_rex64_v"
15128   [(call (mem:QI (reg:DI R11_REG))
15129          (match_operand 0 "" ""))]
15130   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15131   "jmp\t{*%%}r11"
15132   [(set_attr "type" "call")])
15133
15134
15135 ;; Call subroutine, returning value in operand 0
15136
15137 (define_expand "call_value_pop"
15138   [(parallel [(set (match_operand 0 "" "")
15139                    (call (match_operand:QI 1 "" "")
15140                          (match_operand:SI 2 "" "")))
15141               (set (reg:SI SP_REG)
15142                    (plus:SI (reg:SI SP_REG)
15143                             (match_operand:SI 4 "" "")))])]
15144   "!TARGET_64BIT"
15145 {
15146   ix86_expand_call (operands[0], operands[1], operands[2],
15147                     operands[3], operands[4], 0);
15148   DONE;
15149 })
15150
15151 (define_expand "call_value"
15152   [(set (match_operand 0 "" "")
15153         (call (match_operand:QI 1 "" "")
15154               (match_operand:SI 2 "" "")))
15155    (use (match_operand:SI 3 "" ""))]
15156   ;; Operand 2 not used on the i386.
15157   ""
15158 {
15159   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15160   DONE;
15161 })
15162
15163 (define_expand "sibcall_value"
15164   [(set (match_operand 0 "" "")
15165         (call (match_operand:QI 1 "" "")
15166               (match_operand:SI 2 "" "")))
15167    (use (match_operand:SI 3 "" ""))]
15168   ;; Operand 2 not used on the i386.
15169   ""
15170 {
15171   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15172   DONE;
15173 })
15174
15175 ;; Call subroutine returning any type.
15176
15177 (define_expand "untyped_call"
15178   [(parallel [(call (match_operand 0 "" "")
15179                     (const_int 0))
15180               (match_operand 1 "" "")
15181               (match_operand 2 "" "")])]
15182   ""
15183 {
15184   int i;
15185
15186   /* In order to give reg-stack an easier job in validating two
15187      coprocessor registers as containing a possible return value,
15188      simply pretend the untyped call returns a complex long double
15189      value. 
15190
15191      We can't use SSE_REGPARM_MAX here since callee is unprototyped
15192      and should have the default ABI.  */
15193
15194   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15195                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15196                     operands[0], const0_rtx,
15197                     GEN_INT ((TARGET_64BIT
15198                               ? (ix86_abi == SYSV_ABI
15199                                  ? X86_64_SSE_REGPARM_MAX
15200                                  : X64_SSE_REGPARM_MAX)
15201                               : X86_32_SSE_REGPARM_MAX)
15202                              - 1),
15203                     NULL, 0);
15204
15205   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15206     {
15207       rtx set = XVECEXP (operands[2], 0, i);
15208       emit_move_insn (SET_DEST (set), SET_SRC (set));
15209     }
15210
15211   /* The optimizer does not know that the call sets the function value
15212      registers we stored in the result block.  We avoid problems by
15213      claiming that all hard registers are used and clobbered at this
15214      point.  */
15215   emit_insn (gen_blockage ());
15216
15217   DONE;
15218 })
15219 \f
15220 ;; Prologue and epilogue instructions
15221
15222 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15223 ;; all of memory.  This blocks insns from being moved across this point.
15224
15225 (define_insn "blockage"
15226   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15227   ""
15228   ""
15229   [(set_attr "length" "0")])
15230
15231 ;; Do not schedule instructions accessing memory across this point.
15232
15233 (define_expand "memory_blockage"
15234   [(set (match_dup 0)
15235         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15236   ""
15237 {
15238   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15239   MEM_VOLATILE_P (operands[0]) = 1;
15240 })
15241
15242 (define_insn "*memory_blockage"
15243   [(set (match_operand:BLK 0 "" "")
15244         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15245   ""
15246   ""
15247   [(set_attr "length" "0")])
15248
15249 ;; As USE insns aren't meaningful after reload, this is used instead
15250 ;; to prevent deleting instructions setting registers for PIC code
15251 (define_insn "prologue_use"
15252   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15253   ""
15254   ""
15255   [(set_attr "length" "0")])
15256
15257 ;; Insn emitted into the body of a function to return from a function.
15258 ;; This is only done if the function's epilogue is known to be simple.
15259 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15260
15261 (define_expand "return"
15262   [(return)]
15263   "ix86_can_use_return_insn_p ()"
15264 {
15265   if (crtl->args.pops_args)
15266     {
15267       rtx popc = GEN_INT (crtl->args.pops_args);
15268       emit_jump_insn (gen_return_pop_internal (popc));
15269       DONE;
15270     }
15271 })
15272
15273 (define_insn "return_internal"
15274   [(return)]
15275   "reload_completed"
15276   "ret"
15277   [(set_attr "length" "1")
15278    (set_attr "length_immediate" "0")
15279    (set_attr "modrm" "0")])
15280
15281 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15282 ;; instruction Athlon and K8 have.
15283
15284 (define_insn "return_internal_long"
15285   [(return)
15286    (unspec [(const_int 0)] UNSPEC_REP)]
15287   "reload_completed"
15288   "rep\;ret"
15289   [(set_attr "length" "1")
15290    (set_attr "length_immediate" "0")
15291    (set_attr "prefix_rep" "1")
15292    (set_attr "modrm" "0")])
15293
15294 (define_insn "return_pop_internal"
15295   [(return)
15296    (use (match_operand:SI 0 "const_int_operand" ""))]
15297   "reload_completed"
15298   "ret\t%0"
15299   [(set_attr "length" "3")
15300    (set_attr "length_immediate" "2")
15301    (set_attr "modrm" "0")])
15302
15303 (define_insn "return_indirect_internal"
15304   [(return)
15305    (use (match_operand:SI 0 "register_operand" "r"))]
15306   "reload_completed"
15307   "jmp\t%A0"
15308   [(set_attr "type" "ibr")
15309    (set_attr "length_immediate" "0")])
15310
15311 (define_insn "nop"
15312   [(const_int 0)]
15313   ""
15314   "nop"
15315   [(set_attr "length" "1")
15316    (set_attr "length_immediate" "0")
15317    (set_attr "modrm" "0")])
15318
15319 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15320 ;; branch prediction penalty for the third jump in a 16-byte
15321 ;; block on K8.
15322
15323 (define_insn "align"
15324   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15325   ""
15326 {
15327 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15328   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15329 #else
15330   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15331      The align insn is used to avoid 3 jump instructions in the row to improve
15332      branch prediction and the benefits hardly outweigh the cost of extra 8
15333      nops on the average inserted by full alignment pseudo operation.  */
15334 #endif
15335   return "";
15336 }
15337   [(set_attr "length" "16")])
15338
15339 (define_expand "prologue"
15340   [(const_int 0)]
15341   ""
15342   "ix86_expand_prologue (); DONE;")
15343
15344 (define_insn "set_got"
15345   [(set (match_operand:SI 0 "register_operand" "=r")
15346         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15347    (clobber (reg:CC FLAGS_REG))]
15348   "!TARGET_64BIT"
15349   { return output_set_got (operands[0], NULL_RTX); }
15350   [(set_attr "type" "multi")
15351    (set_attr "length" "12")])
15352
15353 (define_insn "set_got_labelled"
15354   [(set (match_operand:SI 0 "register_operand" "=r")
15355         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15356          UNSPEC_SET_GOT))
15357    (clobber (reg:CC FLAGS_REG))]
15358   "!TARGET_64BIT"
15359   { return output_set_got (operands[0], operands[1]); }
15360   [(set_attr "type" "multi")
15361    (set_attr "length" "12")])
15362
15363 (define_insn "set_got_rex64"
15364   [(set (match_operand:DI 0 "register_operand" "=r")
15365         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15366   "TARGET_64BIT"
15367   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15368   [(set_attr "type" "lea")
15369    (set_attr "length" "6")])
15370
15371 (define_insn "set_rip_rex64"
15372   [(set (match_operand:DI 0 "register_operand" "=r")
15373         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15374   "TARGET_64BIT"
15375   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15376   [(set_attr "type" "lea")
15377    (set_attr "length" "6")])
15378
15379 (define_insn "set_got_offset_rex64"
15380   [(set (match_operand:DI 0 "register_operand" "=r")
15381         (unspec:DI
15382           [(label_ref (match_operand 1 "" ""))]
15383           UNSPEC_SET_GOT_OFFSET))]
15384   "TARGET_64BIT"
15385   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15386   [(set_attr "type" "imov")
15387    (set_attr "length" "11")])
15388
15389 (define_expand "epilogue"
15390   [(const_int 0)]
15391   ""
15392   "ix86_expand_epilogue (1); DONE;")
15393
15394 (define_expand "sibcall_epilogue"
15395   [(const_int 0)]
15396   ""
15397   "ix86_expand_epilogue (0); DONE;")
15398
15399 (define_expand "eh_return"
15400   [(use (match_operand 0 "register_operand" ""))]
15401   ""
15402 {
15403   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15404
15405   /* Tricky bit: we write the address of the handler to which we will
15406      be returning into someone else's stack frame, one word below the
15407      stack address we wish to restore.  */
15408   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15409   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15410   tmp = gen_rtx_MEM (Pmode, tmp);
15411   emit_move_insn (tmp, ra);
15412
15413   if (Pmode == SImode)
15414     emit_jump_insn (gen_eh_return_si (sa));
15415   else
15416     emit_jump_insn (gen_eh_return_di (sa));
15417   emit_barrier ();
15418   DONE;
15419 })
15420
15421 (define_insn_and_split "eh_return_<mode>"
15422   [(set (pc)
15423         (unspec [(match_operand:P 0 "register_operand" "c")]
15424                  UNSPEC_EH_RETURN))]
15425   ""
15426   "#"
15427   "reload_completed"
15428   [(const_int 0)]
15429   "ix86_expand_epilogue (2); DONE;")
15430
15431 (define_insn "leave"
15432   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15433    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15434    (clobber (mem:BLK (scratch)))]
15435   "!TARGET_64BIT"
15436   "leave"
15437   [(set_attr "type" "leave")])
15438
15439 (define_insn "leave_rex64"
15440   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15441    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15442    (clobber (mem:BLK (scratch)))]
15443   "TARGET_64BIT"
15444   "leave"
15445   [(set_attr "type" "leave")])
15446 \f
15447 (define_expand "ffssi2"
15448   [(parallel
15449      [(set (match_operand:SI 0 "register_operand" "")
15450            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15451       (clobber (match_scratch:SI 2 ""))
15452       (clobber (reg:CC FLAGS_REG))])]
15453   ""
15454 {
15455   if (TARGET_CMOVE)
15456     {
15457       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15458       DONE;
15459     }
15460 })
15461
15462 (define_expand "ffs_cmove"
15463   [(set (match_dup 2) (const_int -1))
15464    (parallel [(set (reg:CCZ FLAGS_REG)
15465                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15466                                 (const_int 0)))
15467               (set (match_operand:SI 0 "register_operand" "")
15468                    (ctz:SI (match_dup 1)))])
15469    (set (match_dup 0) (if_then_else:SI
15470                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15471                         (match_dup 2)
15472                         (match_dup 0)))
15473    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15474               (clobber (reg:CC FLAGS_REG))])]
15475   "TARGET_CMOVE"
15476   "operands[2] = gen_reg_rtx (SImode);")
15477
15478 (define_insn_and_split "*ffs_no_cmove"
15479   [(set (match_operand:SI 0 "register_operand" "=r")
15480         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15481    (clobber (match_scratch:SI 2 "=&q"))
15482    (clobber (reg:CC FLAGS_REG))]
15483   "!TARGET_CMOVE"
15484   "#"
15485   "&& reload_completed"
15486   [(parallel [(set (reg:CCZ FLAGS_REG)
15487                    (compare:CCZ (match_dup 1) (const_int 0)))
15488               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15489    (set (strict_low_part (match_dup 3))
15490         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15491    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15492               (clobber (reg:CC FLAGS_REG))])
15493    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15494               (clobber (reg:CC FLAGS_REG))])
15495    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15496               (clobber (reg:CC FLAGS_REG))])]
15497 {
15498   operands[3] = gen_lowpart (QImode, operands[2]);
15499   ix86_expand_clear (operands[2]);
15500 })
15501
15502 (define_insn "*ffssi_1"
15503   [(set (reg:CCZ FLAGS_REG)
15504         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15505                      (const_int 0)))
15506    (set (match_operand:SI 0 "register_operand" "=r")
15507         (ctz:SI (match_dup 1)))]
15508   ""
15509   "bsf{l}\t{%1, %0|%0, %1}"
15510   [(set_attr "prefix_0f" "1")])
15511
15512 (define_expand "ffsdi2"
15513   [(set (match_dup 2) (const_int -1))
15514    (parallel [(set (reg:CCZ FLAGS_REG)
15515                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15516                                 (const_int 0)))
15517               (set (match_operand:DI 0 "register_operand" "")
15518                    (ctz:DI (match_dup 1)))])
15519    (set (match_dup 0) (if_then_else:DI
15520                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15521                         (match_dup 2)
15522                         (match_dup 0)))
15523    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15524               (clobber (reg:CC FLAGS_REG))])]
15525   "TARGET_64BIT"
15526   "operands[2] = gen_reg_rtx (DImode);")
15527
15528 (define_insn "*ffsdi_1"
15529   [(set (reg:CCZ FLAGS_REG)
15530         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15531                      (const_int 0)))
15532    (set (match_operand:DI 0 "register_operand" "=r")
15533         (ctz:DI (match_dup 1)))]
15534   "TARGET_64BIT"
15535   "bsf{q}\t{%1, %0|%0, %1}"
15536   [(set_attr "prefix_0f" "1")])
15537
15538 (define_insn "ctzsi2"
15539   [(set (match_operand:SI 0 "register_operand" "=r")
15540         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15541    (clobber (reg:CC FLAGS_REG))]
15542   ""
15543   "bsf{l}\t{%1, %0|%0, %1}"
15544   [(set_attr "prefix_0f" "1")])
15545
15546 (define_insn "ctzdi2"
15547   [(set (match_operand:DI 0 "register_operand" "=r")
15548         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15549    (clobber (reg:CC FLAGS_REG))]
15550   "TARGET_64BIT"
15551   "bsf{q}\t{%1, %0|%0, %1}"
15552   [(set_attr "prefix_0f" "1")])
15553
15554 (define_expand "clzsi2"
15555   [(parallel
15556      [(set (match_operand:SI 0 "register_operand" "")
15557            (minus:SI (const_int 31)
15558                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15559       (clobber (reg:CC FLAGS_REG))])
15560    (parallel
15561      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15562       (clobber (reg:CC FLAGS_REG))])]
15563   ""
15564 {
15565   if (TARGET_ABM)
15566     {
15567       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15568       DONE;
15569     }
15570 })
15571
15572 (define_insn "clzsi2_abm"
15573   [(set (match_operand:SI 0 "register_operand" "=r")
15574         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15575    (clobber (reg:CC FLAGS_REG))]
15576   "TARGET_ABM"
15577   "lzcnt{l}\t{%1, %0|%0, %1}"
15578   [(set_attr "prefix_rep" "1")
15579    (set_attr "type" "bitmanip")
15580    (set_attr "mode" "SI")])
15581
15582 (define_insn "*bsr"
15583   [(set (match_operand:SI 0 "register_operand" "=r")
15584         (minus:SI (const_int 31)
15585                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15586    (clobber (reg:CC FLAGS_REG))]
15587   ""
15588   "bsr{l}\t{%1, %0|%0, %1}"
15589   [(set_attr "prefix_0f" "1")
15590    (set_attr "mode" "SI")])
15591
15592 (define_insn "popcount<mode>2"
15593   [(set (match_operand:SWI248 0 "register_operand" "=r")
15594         (popcount:SWI248
15595           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15596    (clobber (reg:CC FLAGS_REG))]
15597   "TARGET_POPCNT"
15598 {
15599 #if TARGET_MACHO
15600   return "popcnt\t{%1, %0|%0, %1}";
15601 #else
15602   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15603 #endif
15604 }
15605   [(set_attr "prefix_rep" "1")
15606    (set_attr "type" "bitmanip")
15607    (set_attr "mode" "<MODE>")])
15608
15609 (define_insn "*popcount<mode>2_cmp"
15610   [(set (reg FLAGS_REG)
15611         (compare
15612           (popcount:SWI248
15613             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15614           (const_int 0)))
15615    (set (match_operand:SWI248 0 "register_operand" "=r")
15616         (popcount:SWI248 (match_dup 1)))]
15617   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15618 {
15619 #if TARGET_MACHO
15620   return "popcnt\t{%1, %0|%0, %1}";
15621 #else
15622   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15623 #endif
15624 }
15625   [(set_attr "prefix_rep" "1")
15626    (set_attr "type" "bitmanip")
15627    (set_attr "mode" "<MODE>")])
15628
15629 (define_insn "*popcountsi2_cmp_zext"
15630   [(set (reg FLAGS_REG)
15631         (compare
15632           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15633           (const_int 0)))
15634    (set (match_operand:DI 0 "register_operand" "=r")
15635         (zero_extend:DI(popcount:SI (match_dup 1))))]
15636   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15637 {
15638 #if TARGET_MACHO
15639   return "popcnt\t{%1, %0|%0, %1}";
15640 #else
15641   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15642 #endif
15643 }
15644   [(set_attr "prefix_rep" "1")
15645    (set_attr "type" "bitmanip")
15646    (set_attr "mode" "SI")])
15647
15648 (define_expand "bswapsi2"
15649   [(set (match_operand:SI 0 "register_operand" "")
15650         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15651   ""
15652 {
15653   if (!TARGET_BSWAP)
15654     {
15655       rtx x = operands[0];
15656
15657       emit_move_insn (x, operands[1]);
15658       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15659       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15660       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15661       DONE;
15662     }
15663 })
15664
15665 (define_insn "*bswapsi_1"
15666   [(set (match_operand:SI 0 "register_operand" "=r")
15667         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15668   "TARGET_BSWAP"
15669   "bswap\t%0"
15670   [(set_attr "prefix_0f" "1")
15671    (set_attr "length" "2")])
15672
15673 (define_insn "*bswaphi_lowpart_1"
15674   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15675         (bswap:HI (match_dup 0)))
15676    (clobber (reg:CC FLAGS_REG))]
15677   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15678   "@
15679     xchg{b}\t{%h0, %b0|%b0, %h0}
15680     rol{w}\t{$8, %0|%0, 8}"
15681   [(set_attr "length" "2,4")
15682    (set_attr "mode" "QI,HI")])
15683
15684 (define_insn "bswaphi_lowpart"
15685   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15686         (bswap:HI (match_dup 0)))
15687    (clobber (reg:CC FLAGS_REG))]
15688   ""
15689   "rol{w}\t{$8, %0|%0, 8}"
15690   [(set_attr "length" "4")
15691    (set_attr "mode" "HI")])
15692
15693 (define_insn "bswapdi2"
15694   [(set (match_operand:DI 0 "register_operand" "=r")
15695         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15696   "TARGET_64BIT"
15697   "bswap\t%0"
15698   [(set_attr "prefix_0f" "1")
15699    (set_attr "length" "3")])
15700
15701 (define_expand "clzdi2"
15702   [(parallel
15703      [(set (match_operand:DI 0 "register_operand" "")
15704            (minus:DI (const_int 63)
15705                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15706       (clobber (reg:CC FLAGS_REG))])
15707    (parallel
15708      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15709       (clobber (reg:CC FLAGS_REG))])]
15710   "TARGET_64BIT"
15711 {
15712   if (TARGET_ABM)
15713     {
15714       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15715       DONE;
15716     }
15717 })
15718
15719 (define_insn "clzdi2_abm"
15720   [(set (match_operand:DI 0 "register_operand" "=r")
15721         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15722    (clobber (reg:CC FLAGS_REG))]
15723   "TARGET_64BIT && TARGET_ABM"
15724   "lzcnt{q}\t{%1, %0|%0, %1}"
15725   [(set_attr "prefix_rep" "1")
15726    (set_attr "type" "bitmanip")
15727    (set_attr "mode" "DI")])
15728
15729 (define_insn "*bsr_rex64"
15730   [(set (match_operand:DI 0 "register_operand" "=r")
15731         (minus:DI (const_int 63)
15732                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15733    (clobber (reg:CC FLAGS_REG))]
15734   "TARGET_64BIT"
15735   "bsr{q}\t{%1, %0|%0, %1}"
15736   [(set_attr "prefix_0f" "1")
15737    (set_attr "mode" "DI")])
15738
15739 (define_expand "clzhi2"
15740   [(parallel
15741      [(set (match_operand:HI 0 "register_operand" "")
15742            (minus:HI (const_int 15)
15743                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15744       (clobber (reg:CC FLAGS_REG))])
15745    (parallel
15746      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15747       (clobber (reg:CC FLAGS_REG))])]
15748   ""
15749 {
15750   if (TARGET_ABM)
15751     {
15752       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15753       DONE;
15754     }
15755 })
15756
15757 (define_insn "clzhi2_abm"
15758   [(set (match_operand:HI 0 "register_operand" "=r")
15759         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15760    (clobber (reg:CC FLAGS_REG))]
15761   "TARGET_ABM"
15762   "lzcnt{w}\t{%1, %0|%0, %1}"
15763   [(set_attr "prefix_rep" "1")
15764    (set_attr "type" "bitmanip")
15765    (set_attr "mode" "HI")])
15766
15767 (define_insn "*bsrhi"
15768   [(set (match_operand:HI 0 "register_operand" "=r")
15769         (minus:HI (const_int 15)
15770                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15771    (clobber (reg:CC FLAGS_REG))]
15772   ""
15773   "bsr{w}\t{%1, %0|%0, %1}"
15774   [(set_attr "prefix_0f" "1")
15775    (set_attr "mode" "HI")])
15776
15777 (define_expand "paritydi2"
15778   [(set (match_operand:DI 0 "register_operand" "")
15779         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15780   "! TARGET_POPCNT"
15781 {
15782   rtx scratch = gen_reg_rtx (QImode);
15783   rtx cond;
15784
15785   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15786                                 NULL_RTX, operands[1]));
15787
15788   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15789                          gen_rtx_REG (CCmode, FLAGS_REG),
15790                          const0_rtx);
15791   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15792
15793   if (TARGET_64BIT)
15794     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15795   else
15796     {
15797       rtx tmp = gen_reg_rtx (SImode);
15798
15799       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15800       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15801     }
15802   DONE;
15803 })
15804
15805 (define_insn_and_split "paritydi2_cmp"
15806   [(set (reg:CC FLAGS_REG)
15807         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15808    (clobber (match_scratch:DI 0 "=r"))
15809    (clobber (match_scratch:SI 1 "=&r"))
15810    (clobber (match_scratch:HI 2 "=Q"))]
15811   "! TARGET_POPCNT"
15812   "#"
15813   "&& reload_completed"
15814   [(parallel
15815      [(set (match_dup 1)
15816            (xor:SI (match_dup 1) (match_dup 4)))
15817       (clobber (reg:CC FLAGS_REG))])
15818    (parallel
15819      [(set (reg:CC FLAGS_REG)
15820            (parity:CC (match_dup 1)))
15821       (clobber (match_dup 1))
15822       (clobber (match_dup 2))])]
15823 {
15824   operands[4] = gen_lowpart (SImode, operands[3]);
15825
15826   if (TARGET_64BIT)
15827     {
15828       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15829       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15830     }
15831   else
15832     operands[1] = gen_highpart (SImode, operands[3]);
15833 })
15834
15835 (define_expand "paritysi2"
15836   [(set (match_operand:SI 0 "register_operand" "")
15837         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15838   "! TARGET_POPCNT"
15839 {
15840   rtx scratch = gen_reg_rtx (QImode);
15841   rtx cond;
15842
15843   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15844
15845   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15846                          gen_rtx_REG (CCmode, FLAGS_REG),
15847                          const0_rtx);
15848   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15849
15850   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15851   DONE;
15852 })
15853
15854 (define_insn_and_split "paritysi2_cmp"
15855   [(set (reg:CC FLAGS_REG)
15856         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15857    (clobber (match_scratch:SI 0 "=r"))
15858    (clobber (match_scratch:HI 1 "=&Q"))]
15859   "! TARGET_POPCNT"
15860   "#"
15861   "&& reload_completed"
15862   [(parallel
15863      [(set (match_dup 1)
15864            (xor:HI (match_dup 1) (match_dup 3)))
15865       (clobber (reg:CC FLAGS_REG))])
15866    (parallel
15867      [(set (reg:CC FLAGS_REG)
15868            (parity:CC (match_dup 1)))
15869       (clobber (match_dup 1))])]
15870 {
15871   operands[3] = gen_lowpart (HImode, operands[2]);
15872
15873   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15874   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15875 })
15876
15877 (define_insn "*parityhi2_cmp"
15878   [(set (reg:CC FLAGS_REG)
15879         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15880    (clobber (match_scratch:HI 0 "=Q"))]
15881   "! TARGET_POPCNT"
15882   "xor{b}\t{%h0, %b0|%b0, %h0}"
15883   [(set_attr "length" "2")
15884    (set_attr "mode" "HI")])
15885
15886 (define_insn "*parityqi2_cmp"
15887   [(set (reg:CC FLAGS_REG)
15888         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15889   "! TARGET_POPCNT"
15890   "test{b}\t%0, %0"
15891   [(set_attr "length" "2")
15892    (set_attr "mode" "QI")])
15893 \f
15894 ;; Thread-local storage patterns for ELF.
15895 ;;
15896 ;; Note that these code sequences must appear exactly as shown
15897 ;; in order to allow linker relaxation.
15898
15899 (define_insn "*tls_global_dynamic_32_gnu"
15900   [(set (match_operand:SI 0 "register_operand" "=a")
15901         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15902                     (match_operand:SI 2 "tls_symbolic_operand" "")
15903                     (match_operand:SI 3 "call_insn_operand" "")]
15904                     UNSPEC_TLS_GD))
15905    (clobber (match_scratch:SI 4 "=d"))
15906    (clobber (match_scratch:SI 5 "=c"))
15907    (clobber (reg:CC FLAGS_REG))]
15908   "!TARGET_64BIT && TARGET_GNU_TLS"
15909   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15910   [(set_attr "type" "multi")
15911    (set_attr "length" "12")])
15912
15913 (define_insn "*tls_global_dynamic_32_sun"
15914   [(set (match_operand:SI 0 "register_operand" "=a")
15915         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15916                     (match_operand:SI 2 "tls_symbolic_operand" "")
15917                     (match_operand:SI 3 "call_insn_operand" "")]
15918                     UNSPEC_TLS_GD))
15919    (clobber (match_scratch:SI 4 "=d"))
15920    (clobber (match_scratch:SI 5 "=c"))
15921    (clobber (reg:CC FLAGS_REG))]
15922   "!TARGET_64BIT && TARGET_SUN_TLS"
15923   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15924         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15925   [(set_attr "type" "multi")
15926    (set_attr "length" "14")])
15927
15928 (define_expand "tls_global_dynamic_32"
15929   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15930                    (unspec:SI
15931                     [(match_dup 2)
15932                      (match_operand:SI 1 "tls_symbolic_operand" "")
15933                      (match_dup 3)]
15934                     UNSPEC_TLS_GD))
15935               (clobber (match_scratch:SI 4 ""))
15936               (clobber (match_scratch:SI 5 ""))
15937               (clobber (reg:CC FLAGS_REG))])]
15938   ""
15939 {
15940   if (flag_pic)
15941     operands[2] = pic_offset_table_rtx;
15942   else
15943     {
15944       operands[2] = gen_reg_rtx (Pmode);
15945       emit_insn (gen_set_got (operands[2]));
15946     }
15947   if (TARGET_GNU2_TLS)
15948     {
15949        emit_insn (gen_tls_dynamic_gnu2_32
15950                   (operands[0], operands[1], operands[2]));
15951        DONE;
15952     }
15953   operands[3] = ix86_tls_get_addr ();
15954 })
15955
15956 (define_insn "*tls_global_dynamic_64"
15957   [(set (match_operand:DI 0 "register_operand" "=a")
15958         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15959                  (match_operand:DI 3 "" "")))
15960    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15961               UNSPEC_TLS_GD)]
15962   "TARGET_64BIT"
15963   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15964   [(set_attr "type" "multi")
15965    (set_attr "length" "16")])
15966
15967 (define_expand "tls_global_dynamic_64"
15968   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15969                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15970               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15971                          UNSPEC_TLS_GD)])]
15972   ""
15973 {
15974   if (TARGET_GNU2_TLS)
15975     {
15976        emit_insn (gen_tls_dynamic_gnu2_64
15977                   (operands[0], operands[1]));
15978        DONE;
15979     }
15980   operands[2] = ix86_tls_get_addr ();
15981 })
15982
15983 (define_insn "*tls_local_dynamic_base_32_gnu"
15984   [(set (match_operand:SI 0 "register_operand" "=a")
15985         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15986                     (match_operand:SI 2 "call_insn_operand" "")]
15987                    UNSPEC_TLS_LD_BASE))
15988    (clobber (match_scratch:SI 3 "=d"))
15989    (clobber (match_scratch:SI 4 "=c"))
15990    (clobber (reg:CC FLAGS_REG))]
15991   "!TARGET_64BIT && TARGET_GNU_TLS"
15992   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15993   [(set_attr "type" "multi")
15994    (set_attr "length" "11")])
15995
15996 (define_insn "*tls_local_dynamic_base_32_sun"
15997   [(set (match_operand:SI 0 "register_operand" "=a")
15998         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15999                     (match_operand:SI 2 "call_insn_operand" "")]
16000                    UNSPEC_TLS_LD_BASE))
16001    (clobber (match_scratch:SI 3 "=d"))
16002    (clobber (match_scratch:SI 4 "=c"))
16003    (clobber (reg:CC FLAGS_REG))]
16004   "!TARGET_64BIT && TARGET_SUN_TLS"
16005   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16006         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16007   [(set_attr "type" "multi")
16008    (set_attr "length" "13")])
16009
16010 (define_expand "tls_local_dynamic_base_32"
16011   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16012                    (unspec:SI [(match_dup 1) (match_dup 2)]
16013                               UNSPEC_TLS_LD_BASE))
16014               (clobber (match_scratch:SI 3 ""))
16015               (clobber (match_scratch:SI 4 ""))
16016               (clobber (reg:CC FLAGS_REG))])]
16017   ""
16018 {
16019   if (flag_pic)
16020     operands[1] = pic_offset_table_rtx;
16021   else
16022     {
16023       operands[1] = gen_reg_rtx (Pmode);
16024       emit_insn (gen_set_got (operands[1]));
16025     }
16026   if (TARGET_GNU2_TLS)
16027     {
16028        emit_insn (gen_tls_dynamic_gnu2_32
16029                   (operands[0], ix86_tls_module_base (), operands[1]));
16030        DONE;
16031     }
16032   operands[2] = ix86_tls_get_addr ();
16033 })
16034
16035 (define_insn "*tls_local_dynamic_base_64"
16036   [(set (match_operand:DI 0 "register_operand" "=a")
16037         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16038                  (match_operand:DI 2 "" "")))
16039    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16040   "TARGET_64BIT"
16041   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16042   [(set_attr "type" "multi")
16043    (set_attr "length" "12")])
16044
16045 (define_expand "tls_local_dynamic_base_64"
16046   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16047                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16048               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16049   ""
16050 {
16051   if (TARGET_GNU2_TLS)
16052     {
16053        emit_insn (gen_tls_dynamic_gnu2_64
16054                   (operands[0], ix86_tls_module_base ()));
16055        DONE;
16056     }
16057   operands[1] = ix86_tls_get_addr ();
16058 })
16059
16060 ;; Local dynamic of a single variable is a lose.  Show combine how
16061 ;; to convert that back to global dynamic.
16062
16063 (define_insn_and_split "*tls_local_dynamic_32_once"
16064   [(set (match_operand:SI 0 "register_operand" "=a")
16065         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16066                              (match_operand:SI 2 "call_insn_operand" "")]
16067                             UNSPEC_TLS_LD_BASE)
16068                  (const:SI (unspec:SI
16069                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16070                             UNSPEC_DTPOFF))))
16071    (clobber (match_scratch:SI 4 "=d"))
16072    (clobber (match_scratch:SI 5 "=c"))
16073    (clobber (reg:CC FLAGS_REG))]
16074   ""
16075   "#"
16076   ""
16077   [(parallel [(set (match_dup 0)
16078                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16079                               UNSPEC_TLS_GD))
16080               (clobber (match_dup 4))
16081               (clobber (match_dup 5))
16082               (clobber (reg:CC FLAGS_REG))])]
16083   "")
16084
16085 ;; Load and add the thread base pointer from %gs:0.
16086
16087 (define_insn "*load_tp_si"
16088   [(set (match_operand:SI 0 "register_operand" "=r")
16089         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16090   "!TARGET_64BIT"
16091   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16092   [(set_attr "type" "imov")
16093    (set_attr "modrm" "0")
16094    (set_attr "length" "7")
16095    (set_attr "memory" "load")
16096    (set_attr "imm_disp" "false")])
16097
16098 (define_insn "*add_tp_si"
16099   [(set (match_operand:SI 0 "register_operand" "=r")
16100         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16101                  (match_operand:SI 1 "register_operand" "0")))
16102    (clobber (reg:CC FLAGS_REG))]
16103   "!TARGET_64BIT"
16104   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16105   [(set_attr "type" "alu")
16106    (set_attr "modrm" "0")
16107    (set_attr "length" "7")
16108    (set_attr "memory" "load")
16109    (set_attr "imm_disp" "false")])
16110
16111 (define_insn "*load_tp_di"
16112   [(set (match_operand:DI 0 "register_operand" "=r")
16113         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16114   "TARGET_64BIT"
16115   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16116   [(set_attr "type" "imov")
16117    (set_attr "modrm" "0")
16118    (set_attr "length" "7")
16119    (set_attr "memory" "load")
16120    (set_attr "imm_disp" "false")])
16121
16122 (define_insn "*add_tp_di"
16123   [(set (match_operand:DI 0 "register_operand" "=r")
16124         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16125                  (match_operand:DI 1 "register_operand" "0")))
16126    (clobber (reg:CC FLAGS_REG))]
16127   "TARGET_64BIT"
16128   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16129   [(set_attr "type" "alu")
16130    (set_attr "modrm" "0")
16131    (set_attr "length" "7")
16132    (set_attr "memory" "load")
16133    (set_attr "imm_disp" "false")])
16134
16135 ;; GNU2 TLS patterns can be split.
16136
16137 (define_expand "tls_dynamic_gnu2_32"
16138   [(set (match_dup 3)
16139         (plus:SI (match_operand:SI 2 "register_operand" "")
16140                  (const:SI
16141                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16142                              UNSPEC_TLSDESC))))
16143    (parallel
16144     [(set (match_operand:SI 0 "register_operand" "")
16145           (unspec:SI [(match_dup 1) (match_dup 3)
16146                       (match_dup 2) (reg:SI SP_REG)]
16147                       UNSPEC_TLSDESC))
16148      (clobber (reg:CC FLAGS_REG))])]
16149   "!TARGET_64BIT && TARGET_GNU2_TLS"
16150 {
16151   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16152   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16153 })
16154
16155 (define_insn "*tls_dynamic_lea_32"
16156   [(set (match_operand:SI 0 "register_operand" "=r")
16157         (plus:SI (match_operand:SI 1 "register_operand" "b")
16158                  (const:SI
16159                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16160                               UNSPEC_TLSDESC))))]
16161   "!TARGET_64BIT && TARGET_GNU2_TLS"
16162   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16163   [(set_attr "type" "lea")
16164    (set_attr "mode" "SI")
16165    (set_attr "length" "6")
16166    (set_attr "length_address" "4")])
16167
16168 (define_insn "*tls_dynamic_call_32"
16169   [(set (match_operand:SI 0 "register_operand" "=a")
16170         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16171                     (match_operand:SI 2 "register_operand" "0")
16172                     ;; we have to make sure %ebx still points to the GOT
16173                     (match_operand:SI 3 "register_operand" "b")
16174                     (reg:SI SP_REG)]
16175                    UNSPEC_TLSDESC))
16176    (clobber (reg:CC FLAGS_REG))]
16177   "!TARGET_64BIT && TARGET_GNU2_TLS"
16178   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16179   [(set_attr "type" "call")
16180    (set_attr "length" "2")
16181    (set_attr "length_address" "0")])
16182
16183 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16184   [(set (match_operand:SI 0 "register_operand" "=&a")
16185         (plus:SI
16186          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16187                      (match_operand:SI 4 "" "")
16188                      (match_operand:SI 2 "register_operand" "b")
16189                      (reg:SI SP_REG)]
16190                     UNSPEC_TLSDESC)
16191          (const:SI (unspec:SI
16192                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16193                     UNSPEC_DTPOFF))))
16194    (clobber (reg:CC FLAGS_REG))]
16195   "!TARGET_64BIT && TARGET_GNU2_TLS"
16196   "#"
16197   ""
16198   [(set (match_dup 0) (match_dup 5))]
16199 {
16200   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16201   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16202 })
16203
16204 (define_expand "tls_dynamic_gnu2_64"
16205   [(set (match_dup 2)
16206         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16207                    UNSPEC_TLSDESC))
16208    (parallel
16209     [(set (match_operand:DI 0 "register_operand" "")
16210           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16211                      UNSPEC_TLSDESC))
16212      (clobber (reg:CC FLAGS_REG))])]
16213   "TARGET_64BIT && TARGET_GNU2_TLS"
16214 {
16215   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16216   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16217 })
16218
16219 (define_insn "*tls_dynamic_lea_64"
16220   [(set (match_operand:DI 0 "register_operand" "=r")
16221         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16222                    UNSPEC_TLSDESC))]
16223   "TARGET_64BIT && TARGET_GNU2_TLS"
16224   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16225   [(set_attr "type" "lea")
16226    (set_attr "mode" "DI")
16227    (set_attr "length" "7")
16228    (set_attr "length_address" "4")])
16229
16230 (define_insn "*tls_dynamic_call_64"
16231   [(set (match_operand:DI 0 "register_operand" "=a")
16232         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16233                     (match_operand:DI 2 "register_operand" "0")
16234                     (reg:DI SP_REG)]
16235                    UNSPEC_TLSDESC))
16236    (clobber (reg:CC FLAGS_REG))]
16237   "TARGET_64BIT && TARGET_GNU2_TLS"
16238   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16239   [(set_attr "type" "call")
16240    (set_attr "length" "2")
16241    (set_attr "length_address" "0")])
16242
16243 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16244   [(set (match_operand:DI 0 "register_operand" "=&a")
16245         (plus:DI
16246          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16247                      (match_operand:DI 3 "" "")
16248                      (reg:DI SP_REG)]
16249                     UNSPEC_TLSDESC)
16250          (const:DI (unspec:DI
16251                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16252                     UNSPEC_DTPOFF))))
16253    (clobber (reg:CC FLAGS_REG))]
16254   "TARGET_64BIT && TARGET_GNU2_TLS"
16255   "#"
16256   ""
16257   [(set (match_dup 0) (match_dup 4))]
16258 {
16259   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16260   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16261 })
16262
16263 ;;
16264 \f
16265 ;; These patterns match the binary 387 instructions for addM3, subM3,
16266 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16267 ;; SFmode.  The first is the normal insn, the second the same insn but
16268 ;; with one operand a conversion, and the third the same insn but with
16269 ;; the other operand a conversion.  The conversion may be SFmode or
16270 ;; SImode if the target mode DFmode, but only SImode if the target mode
16271 ;; is SFmode.
16272
16273 ;; Gcc is slightly more smart about handling normal two address instructions
16274 ;; so use special patterns for add and mull.
16275
16276 (define_insn "*fop_<mode>_comm_mixed_avx"
16277   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16278         (match_operator:MODEF 3 "binary_fp_operator"
16279           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16280            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16281   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16282    && COMMUTATIVE_ARITH_P (operands[3])
16283    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16284   "* return output_387_binary_op (insn, operands);"
16285   [(set (attr "type")
16286         (if_then_else (eq_attr "alternative" "1")
16287            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16288               (const_string "ssemul")
16289               (const_string "sseadd"))
16290            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16291               (const_string "fmul")
16292               (const_string "fop"))))
16293    (set_attr "prefix" "orig,maybe_vex")
16294    (set_attr "mode" "<MODE>")])
16295
16296 (define_insn "*fop_<mode>_comm_mixed"
16297   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16298         (match_operator:MODEF 3 "binary_fp_operator"
16299           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16300            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16301   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16302    && COMMUTATIVE_ARITH_P (operands[3])
16303    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16304   "* return output_387_binary_op (insn, operands);"
16305   [(set (attr "type")
16306         (if_then_else (eq_attr "alternative" "1")
16307            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16308               (const_string "ssemul")
16309               (const_string "sseadd"))
16310            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16311               (const_string "fmul")
16312               (const_string "fop"))))
16313    (set_attr "mode" "<MODE>")])
16314
16315 (define_insn "*fop_<mode>_comm_avx"
16316   [(set (match_operand:MODEF 0 "register_operand" "=x")
16317         (match_operator:MODEF 3 "binary_fp_operator"
16318           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16319            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16320   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16321    && COMMUTATIVE_ARITH_P (operands[3])
16322    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16323   "* return output_387_binary_op (insn, operands);"
16324   [(set (attr "type")
16325         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16326            (const_string "ssemul")
16327            (const_string "sseadd")))
16328    (set_attr "prefix" "vex")
16329    (set_attr "mode" "<MODE>")])
16330
16331 (define_insn "*fop_<mode>_comm_sse"
16332   [(set (match_operand:MODEF 0 "register_operand" "=x")
16333         (match_operator:MODEF 3 "binary_fp_operator"
16334           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16335            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16336   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16337    && COMMUTATIVE_ARITH_P (operands[3])
16338    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16339   "* return output_387_binary_op (insn, operands);"
16340   [(set (attr "type")
16341         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16342            (const_string "ssemul")
16343            (const_string "sseadd")))
16344    (set_attr "mode" "<MODE>")])
16345
16346 (define_insn "*fop_<mode>_comm_i387"
16347   [(set (match_operand:MODEF 0 "register_operand" "=f")
16348         (match_operator:MODEF 3 "binary_fp_operator"
16349           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16350            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16351   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16352    && COMMUTATIVE_ARITH_P (operands[3])
16353    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16354   "* return output_387_binary_op (insn, operands);"
16355   [(set (attr "type")
16356         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16357            (const_string "fmul")
16358            (const_string "fop")))
16359    (set_attr "mode" "<MODE>")])
16360
16361 (define_insn "*fop_<mode>_1_mixed_avx"
16362   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16363         (match_operator:MODEF 3 "binary_fp_operator"
16364           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16365            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16366   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16367    && !COMMUTATIVE_ARITH_P (operands[3])
16368    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16369   "* return output_387_binary_op (insn, operands);"
16370   [(set (attr "type")
16371         (cond [(and (eq_attr "alternative" "2")
16372                     (match_operand:MODEF 3 "mult_operator" ""))
16373                  (const_string "ssemul")
16374                (and (eq_attr "alternative" "2")
16375                     (match_operand:MODEF 3 "div_operator" ""))
16376                  (const_string "ssediv")
16377                (eq_attr "alternative" "2")
16378                  (const_string "sseadd")
16379                (match_operand:MODEF 3 "mult_operator" "")
16380                  (const_string "fmul")
16381                (match_operand:MODEF 3 "div_operator" "")
16382                  (const_string "fdiv")
16383               ]
16384               (const_string "fop")))
16385    (set_attr "prefix" "orig,orig,maybe_vex")
16386    (set_attr "mode" "<MODE>")])
16387
16388 (define_insn "*fop_<mode>_1_mixed"
16389   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16390         (match_operator:MODEF 3 "binary_fp_operator"
16391           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16392            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16393   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16394    && !COMMUTATIVE_ARITH_P (operands[3])
16395    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16396   "* return output_387_binary_op (insn, operands);"
16397   [(set (attr "type")
16398         (cond [(and (eq_attr "alternative" "2")
16399                     (match_operand:MODEF 3 "mult_operator" ""))
16400                  (const_string "ssemul")
16401                (and (eq_attr "alternative" "2")
16402                     (match_operand:MODEF 3 "div_operator" ""))
16403                  (const_string "ssediv")
16404                (eq_attr "alternative" "2")
16405                  (const_string "sseadd")
16406                (match_operand:MODEF 3 "mult_operator" "")
16407                  (const_string "fmul")
16408                (match_operand:MODEF 3 "div_operator" "")
16409                  (const_string "fdiv")
16410               ]
16411               (const_string "fop")))
16412    (set_attr "mode" "<MODE>")])
16413
16414 (define_insn "*rcpsf2_sse"
16415   [(set (match_operand:SF 0 "register_operand" "=x")
16416         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16417                    UNSPEC_RCP))]
16418   "TARGET_SSE_MATH"
16419   "%vrcpss\t{%1, %d0|%d0, %1}"
16420   [(set_attr "type" "sse")
16421    (set_attr "prefix" "maybe_vex")
16422    (set_attr "mode" "SF")])
16423
16424 (define_insn "*fop_<mode>_1_avx"
16425   [(set (match_operand:MODEF 0 "register_operand" "=x")
16426         (match_operator:MODEF 3 "binary_fp_operator"
16427           [(match_operand:MODEF 1 "register_operand" "x")
16428            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16429   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16430    && !COMMUTATIVE_ARITH_P (operands[3])"
16431   "* return output_387_binary_op (insn, operands);"
16432   [(set (attr "type")
16433         (cond [(match_operand:MODEF 3 "mult_operator" "")
16434                  (const_string "ssemul")
16435                (match_operand:MODEF 3 "div_operator" "")
16436                  (const_string "ssediv")
16437               ]
16438               (const_string "sseadd")))
16439    (set_attr "prefix" "vex")
16440    (set_attr "mode" "<MODE>")])
16441
16442 (define_insn "*fop_<mode>_1_sse"
16443   [(set (match_operand:MODEF 0 "register_operand" "=x")
16444         (match_operator:MODEF 3 "binary_fp_operator"
16445           [(match_operand:MODEF 1 "register_operand" "0")
16446            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16447   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16448    && !COMMUTATIVE_ARITH_P (operands[3])"
16449   "* return output_387_binary_op (insn, operands);"
16450   [(set (attr "type")
16451         (cond [(match_operand:MODEF 3 "mult_operator" "")
16452                  (const_string "ssemul")
16453                (match_operand:MODEF 3 "div_operator" "")
16454                  (const_string "ssediv")
16455               ]
16456               (const_string "sseadd")))
16457    (set_attr "mode" "<MODE>")])
16458
16459 ;; This pattern is not fully shadowed by the pattern above.
16460 (define_insn "*fop_<mode>_1_i387"
16461   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16462         (match_operator:MODEF 3 "binary_fp_operator"
16463           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16464            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16465   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16466    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16467    && !COMMUTATIVE_ARITH_P (operands[3])
16468    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16469   "* return 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 "mode" "<MODE>")])
16478
16479 ;; ??? Add SSE splitters for these!
16480 (define_insn "*fop_<MODEF:mode>_2_i387"
16481   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16482         (match_operator:MODEF 3 "binary_fp_operator"
16483           [(float:MODEF
16484              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16485            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16486   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16487    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16488    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16489   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16490   [(set (attr "type")
16491         (cond [(match_operand:MODEF 3 "mult_operator" "")
16492                  (const_string "fmul")
16493                (match_operand:MODEF 3 "div_operator" "")
16494                  (const_string "fdiv")
16495               ]
16496               (const_string "fop")))
16497    (set_attr "fp_int_src" "true")
16498    (set_attr "mode" "<X87MODEI12:MODE>")])
16499
16500 (define_insn "*fop_<MODEF:mode>_3_i387"
16501   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16502         (match_operator:MODEF 3 "binary_fp_operator"
16503           [(match_operand:MODEF 1 "register_operand" "0,0")
16504            (float:MODEF
16505              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16506   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16507    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16508    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16509   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16510   [(set (attr "type")
16511         (cond [(match_operand:MODEF 3 "mult_operator" "")
16512                  (const_string "fmul")
16513                (match_operand:MODEF 3 "div_operator" "")
16514                  (const_string "fdiv")
16515               ]
16516               (const_string "fop")))
16517    (set_attr "fp_int_src" "true")
16518    (set_attr "mode" "<MODE>")])
16519
16520 (define_insn "*fop_df_4_i387"
16521   [(set (match_operand:DF 0 "register_operand" "=f,f")
16522         (match_operator:DF 3 "binary_fp_operator"
16523            [(float_extend:DF
16524              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16525             (match_operand:DF 2 "register_operand" "0,f")]))]
16526   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16527    && !(TARGET_SSE2 && TARGET_SSE_MATH)
16528    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16529   "* return output_387_binary_op (insn, operands);"
16530   [(set (attr "type")
16531         (cond [(match_operand:DF 3 "mult_operator" "")
16532                  (const_string "fmul")
16533                (match_operand:DF 3 "div_operator" "")
16534                  (const_string "fdiv")
16535               ]
16536               (const_string "fop")))
16537    (set_attr "mode" "SF")])
16538
16539 (define_insn "*fop_df_5_i387"
16540   [(set (match_operand:DF 0 "register_operand" "=f,f")
16541         (match_operator:DF 3 "binary_fp_operator"
16542           [(match_operand:DF 1 "register_operand" "0,f")
16543            (float_extend:DF
16544             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16545   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16546    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16547   "* return output_387_binary_op (insn, operands);"
16548   [(set (attr "type")
16549         (cond [(match_operand:DF 3 "mult_operator" "")
16550                  (const_string "fmul")
16551                (match_operand:DF 3 "div_operator" "")
16552                  (const_string "fdiv")
16553               ]
16554               (const_string "fop")))
16555    (set_attr "mode" "SF")])
16556
16557 (define_insn "*fop_df_6_i387"
16558   [(set (match_operand:DF 0 "register_operand" "=f,f")
16559         (match_operator:DF 3 "binary_fp_operator"
16560           [(float_extend:DF
16561             (match_operand:SF 1 "register_operand" "0,f"))
16562            (float_extend:DF
16563             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16564   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16565    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16566   "* return output_387_binary_op (insn, operands);"
16567   [(set (attr "type")
16568         (cond [(match_operand:DF 3 "mult_operator" "")
16569                  (const_string "fmul")
16570                (match_operand:DF 3 "div_operator" "")
16571                  (const_string "fdiv")
16572               ]
16573               (const_string "fop")))
16574    (set_attr "mode" "SF")])
16575
16576 (define_insn "*fop_xf_comm_i387"
16577   [(set (match_operand:XF 0 "register_operand" "=f")
16578         (match_operator:XF 3 "binary_fp_operator"
16579                         [(match_operand:XF 1 "register_operand" "%0")
16580                          (match_operand:XF 2 "register_operand" "f")]))]
16581   "TARGET_80387
16582    && COMMUTATIVE_ARITH_P (operands[3])"
16583   "* return output_387_binary_op (insn, operands);"
16584   [(set (attr "type")
16585         (if_then_else (match_operand:XF 3 "mult_operator" "")
16586            (const_string "fmul")
16587            (const_string "fop")))
16588    (set_attr "mode" "XF")])
16589
16590 (define_insn "*fop_xf_1_i387"
16591   [(set (match_operand:XF 0 "register_operand" "=f,f")
16592         (match_operator:XF 3 "binary_fp_operator"
16593                         [(match_operand:XF 1 "register_operand" "0,f")
16594                          (match_operand:XF 2 "register_operand" "f,0")]))]
16595   "TARGET_80387
16596    && !COMMUTATIVE_ARITH_P (operands[3])"
16597   "* return output_387_binary_op (insn, operands);"
16598   [(set (attr "type")
16599         (cond [(match_operand:XF 3 "mult_operator" "")
16600                  (const_string "fmul")
16601                (match_operand:XF 3 "div_operator" "")
16602                  (const_string "fdiv")
16603               ]
16604               (const_string "fop")))
16605    (set_attr "mode" "XF")])
16606
16607 (define_insn "*fop_xf_2_i387"
16608   [(set (match_operand:XF 0 "register_operand" "=f,f")
16609         (match_operator:XF 3 "binary_fp_operator"
16610           [(float:XF
16611              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16612            (match_operand:XF 2 "register_operand" "0,0")]))]
16613   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16614   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16615   [(set (attr "type")
16616         (cond [(match_operand:XF 3 "mult_operator" "")
16617                  (const_string "fmul")
16618                (match_operand:XF 3 "div_operator" "")
16619                  (const_string "fdiv")
16620               ]
16621               (const_string "fop")))
16622    (set_attr "fp_int_src" "true")
16623    (set_attr "mode" "<MODE>")])
16624
16625 (define_insn "*fop_xf_3_i387"
16626   [(set (match_operand:XF 0 "register_operand" "=f,f")
16627         (match_operator:XF 3 "binary_fp_operator"
16628           [(match_operand:XF 1 "register_operand" "0,0")
16629            (float:XF
16630              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16631   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16632   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16633   [(set (attr "type")
16634         (cond [(match_operand:XF 3 "mult_operator" "")
16635                  (const_string "fmul")
16636                (match_operand:XF 3 "div_operator" "")
16637                  (const_string "fdiv")
16638               ]
16639               (const_string "fop")))
16640    (set_attr "fp_int_src" "true")
16641    (set_attr "mode" "<MODE>")])
16642
16643 (define_insn "*fop_xf_4_i387"
16644   [(set (match_operand:XF 0 "register_operand" "=f,f")
16645         (match_operator:XF 3 "binary_fp_operator"
16646            [(float_extend:XF
16647               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16648             (match_operand:XF 2 "register_operand" "0,f")]))]
16649   "TARGET_80387"
16650   "* return output_387_binary_op (insn, operands);"
16651   [(set (attr "type")
16652         (cond [(match_operand:XF 3 "mult_operator" "")
16653                  (const_string "fmul")
16654                (match_operand:XF 3 "div_operator" "")
16655                  (const_string "fdiv")
16656               ]
16657               (const_string "fop")))
16658    (set_attr "mode" "<MODE>")])
16659
16660 (define_insn "*fop_xf_5_i387"
16661   [(set (match_operand:XF 0 "register_operand" "=f,f")
16662         (match_operator:XF 3 "binary_fp_operator"
16663           [(match_operand:XF 1 "register_operand" "0,f")
16664            (float_extend:XF
16665              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16666   "TARGET_80387"
16667   "* return output_387_binary_op (insn, operands);"
16668   [(set (attr "type")
16669         (cond [(match_operand:XF 3 "mult_operator" "")
16670                  (const_string "fmul")
16671                (match_operand:XF 3 "div_operator" "")
16672                  (const_string "fdiv")
16673               ]
16674               (const_string "fop")))
16675    (set_attr "mode" "<MODE>")])
16676
16677 (define_insn "*fop_xf_6_i387"
16678   [(set (match_operand:XF 0 "register_operand" "=f,f")
16679         (match_operator:XF 3 "binary_fp_operator"
16680           [(float_extend:XF
16681              (match_operand:MODEF 1 "register_operand" "0,f"))
16682            (float_extend:XF
16683              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16684   "TARGET_80387"
16685   "* return output_387_binary_op (insn, operands);"
16686   [(set (attr "type")
16687         (cond [(match_operand:XF 3 "mult_operator" "")
16688                  (const_string "fmul")
16689                (match_operand:XF 3 "div_operator" "")
16690                  (const_string "fdiv")
16691               ]
16692               (const_string "fop")))
16693    (set_attr "mode" "<MODE>")])
16694
16695 (define_split
16696   [(set (match_operand 0 "register_operand" "")
16697         (match_operator 3 "binary_fp_operator"
16698            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16699             (match_operand 2 "register_operand" "")]))]
16700   "reload_completed
16701    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16702    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16703   [(const_int 0)]
16704 {
16705   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16706   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16707   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16708                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16709                                           GET_MODE (operands[3]),
16710                                           operands[4],
16711                                           operands[2])));
16712   ix86_free_from_memory (GET_MODE (operands[1]));
16713   DONE;
16714 })
16715
16716 (define_split
16717   [(set (match_operand 0 "register_operand" "")
16718         (match_operator 3 "binary_fp_operator"
16719            [(match_operand 1 "register_operand" "")
16720             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16721   "reload_completed
16722    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16723    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16724   [(const_int 0)]
16725 {
16726   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16727   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16728   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16729                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16730                                           GET_MODE (operands[3]),
16731                                           operands[1],
16732                                           operands[4])));
16733   ix86_free_from_memory (GET_MODE (operands[2]));
16734   DONE;
16735 })
16736 \f
16737 ;; FPU special functions.
16738
16739 ;; This pattern implements a no-op XFmode truncation for
16740 ;; all fancy i386 XFmode math functions.
16741
16742 (define_insn "truncxf<mode>2_i387_noop_unspec"
16743   [(set (match_operand:MODEF 0 "register_operand" "=f")
16744         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16745         UNSPEC_TRUNC_NOOP))]
16746   "TARGET_USE_FANCY_MATH_387"
16747   "* return output_387_reg_move (insn, operands);"
16748   [(set_attr "type" "fmov")
16749    (set_attr "mode" "<MODE>")])
16750
16751 (define_insn "sqrtxf2"
16752   [(set (match_operand:XF 0 "register_operand" "=f")
16753         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16754   "TARGET_USE_FANCY_MATH_387"
16755   "fsqrt"
16756   [(set_attr "type" "fpspc")
16757    (set_attr "mode" "XF")
16758    (set_attr "athlon_decode" "direct")
16759    (set_attr "amdfam10_decode" "direct")])
16760
16761 (define_insn "sqrt_extend<mode>xf2_i387"
16762   [(set (match_operand:XF 0 "register_operand" "=f")
16763         (sqrt:XF
16764           (float_extend:XF
16765             (match_operand:MODEF 1 "register_operand" "0"))))]
16766   "TARGET_USE_FANCY_MATH_387"
16767   "fsqrt"
16768   [(set_attr "type" "fpspc")
16769    (set_attr "mode" "XF")
16770    (set_attr "athlon_decode" "direct")
16771    (set_attr "amdfam10_decode" "direct")])
16772
16773 (define_insn "*rsqrtsf2_sse"
16774   [(set (match_operand:SF 0 "register_operand" "=x")
16775         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16776                    UNSPEC_RSQRT))]
16777   "TARGET_SSE_MATH"
16778   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16779   [(set_attr "type" "sse")
16780    (set_attr "prefix" "maybe_vex")
16781    (set_attr "mode" "SF")])
16782
16783 (define_expand "rsqrtsf2"
16784   [(set (match_operand:SF 0 "register_operand" "")
16785         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16786                    UNSPEC_RSQRT))]
16787   "TARGET_SSE_MATH"
16788 {
16789   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16790   DONE;
16791 })
16792
16793 (define_insn "*sqrt<mode>2_sse"
16794   [(set (match_operand:MODEF 0 "register_operand" "=x")
16795         (sqrt:MODEF
16796           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16797   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16798   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16799   [(set_attr "type" "sse")
16800    (set_attr "prefix" "maybe_vex")
16801    (set_attr "mode" "<MODE>")
16802    (set_attr "athlon_decode" "*")
16803    (set_attr "amdfam10_decode" "*")])
16804
16805 (define_expand "sqrt<mode>2"
16806   [(set (match_operand:MODEF 0 "register_operand" "")
16807         (sqrt:MODEF
16808           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16809   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16810    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16811 {
16812   if (<MODE>mode == SFmode
16813       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16814       && flag_finite_math_only && !flag_trapping_math
16815       && flag_unsafe_math_optimizations)
16816     {
16817       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16818       DONE;
16819     }
16820
16821   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16822     {
16823       rtx op0 = gen_reg_rtx (XFmode);
16824       rtx op1 = force_reg (<MODE>mode, operands[1]);
16825
16826       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16827       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16828       DONE;
16829    }
16830 })
16831
16832 (define_insn "fpremxf4_i387"
16833   [(set (match_operand:XF 0 "register_operand" "=f")
16834         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16835                     (match_operand:XF 3 "register_operand" "1")]
16836                    UNSPEC_FPREM_F))
16837    (set (match_operand:XF 1 "register_operand" "=u")
16838         (unspec:XF [(match_dup 2) (match_dup 3)]
16839                    UNSPEC_FPREM_U))
16840    (set (reg:CCFP FPSR_REG)
16841         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16842                      UNSPEC_C2_FLAG))]
16843   "TARGET_USE_FANCY_MATH_387"
16844   "fprem"
16845   [(set_attr "type" "fpspc")
16846    (set_attr "mode" "XF")])
16847
16848 (define_expand "fmodxf3"
16849   [(use (match_operand:XF 0 "register_operand" ""))
16850    (use (match_operand:XF 1 "general_operand" ""))
16851    (use (match_operand:XF 2 "general_operand" ""))]
16852   "TARGET_USE_FANCY_MATH_387"
16853 {
16854   rtx label = gen_label_rtx ();
16855
16856   rtx op1 = gen_reg_rtx (XFmode);
16857   rtx op2 = gen_reg_rtx (XFmode);
16858
16859   emit_move_insn (op2, operands[2]);
16860   emit_move_insn (op1, operands[1]);
16861
16862   emit_label (label);
16863   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16864   ix86_emit_fp_unordered_jump (label);
16865   LABEL_NUSES (label) = 1;
16866
16867   emit_move_insn (operands[0], op1);
16868   DONE;
16869 })
16870
16871 (define_expand "fmod<mode>3"
16872   [(use (match_operand:MODEF 0 "register_operand" ""))
16873    (use (match_operand:MODEF 1 "general_operand" ""))
16874    (use (match_operand:MODEF 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_insn (gen_extend<mode>xf2 (op2, operands[2]));
16883   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16884
16885   emit_label (label);
16886   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16887   ix86_emit_fp_unordered_jump (label);
16888   LABEL_NUSES (label) = 1;
16889
16890   /* Truncate the result properly for strict SSE math.  */
16891   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16892       && !TARGET_MIX_SSE_I387)
16893     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16894   else
16895     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16896
16897   DONE;
16898 })
16899
16900 (define_insn "fprem1xf4_i387"
16901   [(set (match_operand:XF 0 "register_operand" "=f")
16902         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16903                     (match_operand:XF 3 "register_operand" "1")]
16904                    UNSPEC_FPREM1_F))
16905    (set (match_operand:XF 1 "register_operand" "=u")
16906         (unspec:XF [(match_dup 2) (match_dup 3)]
16907                    UNSPEC_FPREM1_U))
16908    (set (reg:CCFP FPSR_REG)
16909         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16910                      UNSPEC_C2_FLAG))]
16911   "TARGET_USE_FANCY_MATH_387"
16912   "fprem1"
16913   [(set_attr "type" "fpspc")
16914    (set_attr "mode" "XF")])
16915
16916 (define_expand "remainderxf3"
16917   [(use (match_operand:XF 0 "register_operand" ""))
16918    (use (match_operand:XF 1 "general_operand" ""))
16919    (use (match_operand:XF 2 "general_operand" ""))]
16920   "TARGET_USE_FANCY_MATH_387"
16921 {
16922   rtx label = gen_label_rtx ();
16923
16924   rtx op1 = gen_reg_rtx (XFmode);
16925   rtx op2 = gen_reg_rtx (XFmode);
16926
16927   emit_move_insn (op2, operands[2]);
16928   emit_move_insn (op1, operands[1]);
16929
16930   emit_label (label);
16931   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16932   ix86_emit_fp_unordered_jump (label);
16933   LABEL_NUSES (label) = 1;
16934
16935   emit_move_insn (operands[0], op1);
16936   DONE;
16937 })
16938
16939 (define_expand "remainder<mode>3"
16940   [(use (match_operand:MODEF 0 "register_operand" ""))
16941    (use (match_operand:MODEF 1 "general_operand" ""))
16942    (use (match_operand:MODEF 2 "general_operand" ""))]
16943   "TARGET_USE_FANCY_MATH_387"
16944 {
16945   rtx label = gen_label_rtx ();
16946
16947   rtx op1 = gen_reg_rtx (XFmode);
16948   rtx op2 = gen_reg_rtx (XFmode);
16949
16950   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16951   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16952
16953   emit_label (label);
16954
16955   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16956   ix86_emit_fp_unordered_jump (label);
16957   LABEL_NUSES (label) = 1;
16958
16959   /* Truncate the result properly for strict SSE math.  */
16960   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16961       && !TARGET_MIX_SSE_I387)
16962     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16963   else
16964     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16965
16966   DONE;
16967 })
16968
16969 (define_insn "*sinxf2_i387"
16970   [(set (match_operand:XF 0 "register_operand" "=f")
16971         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16972   "TARGET_USE_FANCY_MATH_387
16973    && flag_unsafe_math_optimizations"
16974   "fsin"
16975   [(set_attr "type" "fpspc")
16976    (set_attr "mode" "XF")])
16977
16978 (define_insn "*sin_extend<mode>xf2_i387"
16979   [(set (match_operand:XF 0 "register_operand" "=f")
16980         (unspec:XF [(float_extend:XF
16981                       (match_operand:MODEF 1 "register_operand" "0"))]
16982                    UNSPEC_SIN))]
16983   "TARGET_USE_FANCY_MATH_387
16984    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16985        || TARGET_MIX_SSE_I387)
16986    && flag_unsafe_math_optimizations"
16987   "fsin"
16988   [(set_attr "type" "fpspc")
16989    (set_attr "mode" "XF")])
16990
16991 (define_insn "*cosxf2_i387"
16992   [(set (match_operand:XF 0 "register_operand" "=f")
16993         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16994   "TARGET_USE_FANCY_MATH_387
16995    && flag_unsafe_math_optimizations"
16996   "fcos"
16997   [(set_attr "type" "fpspc")
16998    (set_attr "mode" "XF")])
16999
17000 (define_insn "*cos_extend<mode>xf2_i387"
17001   [(set (match_operand:XF 0 "register_operand" "=f")
17002         (unspec:XF [(float_extend:XF
17003                       (match_operand:MODEF 1 "register_operand" "0"))]
17004                    UNSPEC_COS))]
17005   "TARGET_USE_FANCY_MATH_387
17006    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17007        || TARGET_MIX_SSE_I387)
17008    && flag_unsafe_math_optimizations"
17009   "fcos"
17010   [(set_attr "type" "fpspc")
17011    (set_attr "mode" "XF")])
17012
17013 ;; When sincos pattern is defined, sin and cos builtin functions will be
17014 ;; expanded to sincos pattern with one of its outputs left unused.
17015 ;; CSE pass will figure out if two sincos patterns can be combined,
17016 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17017 ;; depending on the unused output.
17018
17019 (define_insn "sincosxf3"
17020   [(set (match_operand:XF 0 "register_operand" "=f")
17021         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17022                    UNSPEC_SINCOS_COS))
17023    (set (match_operand:XF 1 "register_operand" "=u")
17024         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17025   "TARGET_USE_FANCY_MATH_387
17026    && flag_unsafe_math_optimizations"
17027   "fsincos"
17028   [(set_attr "type" "fpspc")
17029    (set_attr "mode" "XF")])
17030
17031 (define_split
17032   [(set (match_operand:XF 0 "register_operand" "")
17033         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17034                    UNSPEC_SINCOS_COS))
17035    (set (match_operand:XF 1 "register_operand" "")
17036         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17037   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17038    && !(reload_completed || reload_in_progress)"
17039   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17040   "")
17041
17042 (define_split
17043   [(set (match_operand:XF 0 "register_operand" "")
17044         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17045                    UNSPEC_SINCOS_COS))
17046    (set (match_operand:XF 1 "register_operand" "")
17047         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17048   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17049    && !(reload_completed || reload_in_progress)"
17050   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17051   "")
17052
17053 (define_insn "sincos_extend<mode>xf3_i387"
17054   [(set (match_operand:XF 0 "register_operand" "=f")
17055         (unspec:XF [(float_extend:XF
17056                       (match_operand:MODEF 2 "register_operand" "0"))]
17057                    UNSPEC_SINCOS_COS))
17058    (set (match_operand:XF 1 "register_operand" "=u")
17059         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17060   "TARGET_USE_FANCY_MATH_387
17061    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17062        || TARGET_MIX_SSE_I387)
17063    && flag_unsafe_math_optimizations"
17064   "fsincos"
17065   [(set_attr "type" "fpspc")
17066    (set_attr "mode" "XF")])
17067
17068 (define_split
17069   [(set (match_operand:XF 0 "register_operand" "")
17070         (unspec:XF [(float_extend:XF
17071                       (match_operand:MODEF 2 "register_operand" ""))]
17072                    UNSPEC_SINCOS_COS))
17073    (set (match_operand:XF 1 "register_operand" "")
17074         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17075   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17076    && !(reload_completed || reload_in_progress)"
17077   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17078   "")
17079
17080 (define_split
17081   [(set (match_operand:XF 0 "register_operand" "")
17082         (unspec:XF [(float_extend:XF
17083                       (match_operand:MODEF 2 "register_operand" ""))]
17084                    UNSPEC_SINCOS_COS))
17085    (set (match_operand:XF 1 "register_operand" "")
17086         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17087   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17088    && !(reload_completed || reload_in_progress)"
17089   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17090   "")
17091
17092 (define_expand "sincos<mode>3"
17093   [(use (match_operand:MODEF 0 "register_operand" ""))
17094    (use (match_operand:MODEF 1 "register_operand" ""))
17095    (use (match_operand:MODEF 2 "register_operand" ""))]
17096   "TARGET_USE_FANCY_MATH_387
17097    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17098        || TARGET_MIX_SSE_I387)
17099    && flag_unsafe_math_optimizations"
17100 {
17101   rtx op0 = gen_reg_rtx (XFmode);
17102   rtx op1 = gen_reg_rtx (XFmode);
17103
17104   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17105   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17106   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17107   DONE;
17108 })
17109
17110 (define_insn "fptanxf4_i387"
17111   [(set (match_operand:XF 0 "register_operand" "=f")
17112         (match_operand:XF 3 "const_double_operand" "F"))
17113    (set (match_operand:XF 1 "register_operand" "=u")
17114         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17115                    UNSPEC_TAN))]
17116   "TARGET_USE_FANCY_MATH_387
17117    && flag_unsafe_math_optimizations
17118    && standard_80387_constant_p (operands[3]) == 2"
17119   "fptan"
17120   [(set_attr "type" "fpspc")
17121    (set_attr "mode" "XF")])
17122
17123 (define_insn "fptan_extend<mode>xf4_i387"
17124   [(set (match_operand:MODEF 0 "register_operand" "=f")
17125         (match_operand:MODEF 3 "const_double_operand" "F"))
17126    (set (match_operand:XF 1 "register_operand" "=u")
17127         (unspec:XF [(float_extend:XF
17128                       (match_operand:MODEF 2 "register_operand" "0"))]
17129                    UNSPEC_TAN))]
17130   "TARGET_USE_FANCY_MATH_387
17131    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17132        || TARGET_MIX_SSE_I387)
17133    && flag_unsafe_math_optimizations
17134    && standard_80387_constant_p (operands[3]) == 2"
17135   "fptan"
17136   [(set_attr "type" "fpspc")
17137    (set_attr "mode" "XF")])
17138
17139 (define_expand "tanxf2"
17140   [(use (match_operand:XF 0 "register_operand" ""))
17141    (use (match_operand:XF 1 "register_operand" ""))]
17142   "TARGET_USE_FANCY_MATH_387
17143    && flag_unsafe_math_optimizations"
17144 {
17145   rtx one = gen_reg_rtx (XFmode);
17146   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17147
17148   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17149   DONE;
17150 })
17151
17152 (define_expand "tan<mode>2"
17153   [(use (match_operand:MODEF 0 "register_operand" ""))
17154    (use (match_operand:MODEF 1 "register_operand" ""))]
17155   "TARGET_USE_FANCY_MATH_387
17156    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17157        || TARGET_MIX_SSE_I387)
17158    && flag_unsafe_math_optimizations"
17159 {
17160   rtx op0 = gen_reg_rtx (XFmode);
17161
17162   rtx one = gen_reg_rtx (<MODE>mode);
17163   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17164
17165   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17166                                              operands[1], op2));
17167   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17168   DONE;
17169 })
17170
17171 (define_insn "*fpatanxf3_i387"
17172   [(set (match_operand:XF 0 "register_operand" "=f")
17173         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17174                     (match_operand:XF 2 "register_operand" "u")]
17175                    UNSPEC_FPATAN))
17176    (clobber (match_scratch:XF 3 "=2"))]
17177   "TARGET_USE_FANCY_MATH_387
17178    && flag_unsafe_math_optimizations"
17179   "fpatan"
17180   [(set_attr "type" "fpspc")
17181    (set_attr "mode" "XF")])
17182
17183 (define_insn "fpatan_extend<mode>xf3_i387"
17184   [(set (match_operand:XF 0 "register_operand" "=f")
17185         (unspec:XF [(float_extend:XF
17186                       (match_operand:MODEF 1 "register_operand" "0"))
17187                     (float_extend:XF
17188                       (match_operand:MODEF 2 "register_operand" "u"))]
17189                    UNSPEC_FPATAN))
17190    (clobber (match_scratch:XF 3 "=2"))]
17191   "TARGET_USE_FANCY_MATH_387
17192    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17193        || TARGET_MIX_SSE_I387)
17194    && flag_unsafe_math_optimizations"
17195   "fpatan"
17196   [(set_attr "type" "fpspc")
17197    (set_attr "mode" "XF")])
17198
17199 (define_expand "atan2xf3"
17200   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17201                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17202                                (match_operand:XF 1 "register_operand" "")]
17203                               UNSPEC_FPATAN))
17204               (clobber (match_scratch:XF 3 ""))])]
17205   "TARGET_USE_FANCY_MATH_387
17206    && flag_unsafe_math_optimizations"
17207   "")
17208
17209 (define_expand "atan2<mode>3"
17210   [(use (match_operand:MODEF 0 "register_operand" ""))
17211    (use (match_operand:MODEF 1 "register_operand" ""))
17212    (use (match_operand:MODEF 2 "register_operand" ""))]
17213   "TARGET_USE_FANCY_MATH_387
17214    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17215        || TARGET_MIX_SSE_I387)
17216    && flag_unsafe_math_optimizations"
17217 {
17218   rtx op0 = gen_reg_rtx (XFmode);
17219
17220   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17221   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17222   DONE;
17223 })
17224
17225 (define_expand "atanxf2"
17226   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17227                    (unspec:XF [(match_dup 2)
17228                                (match_operand:XF 1 "register_operand" "")]
17229                               UNSPEC_FPATAN))
17230               (clobber (match_scratch:XF 3 ""))])]
17231   "TARGET_USE_FANCY_MATH_387
17232    && flag_unsafe_math_optimizations"
17233 {
17234   operands[2] = gen_reg_rtx (XFmode);
17235   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17236 })
17237
17238 (define_expand "atan<mode>2"
17239   [(use (match_operand:MODEF 0 "register_operand" ""))
17240    (use (match_operand:MODEF 1 "register_operand" ""))]
17241   "TARGET_USE_FANCY_MATH_387
17242    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17243        || TARGET_MIX_SSE_I387)
17244    && flag_unsafe_math_optimizations"
17245 {
17246   rtx op0 = gen_reg_rtx (XFmode);
17247
17248   rtx op2 = gen_reg_rtx (<MODE>mode);
17249   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17250
17251   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17252   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17253   DONE;
17254 })
17255
17256 (define_expand "asinxf2"
17257   [(set (match_dup 2)
17258         (mult:XF (match_operand:XF 1 "register_operand" "")
17259                  (match_dup 1)))
17260    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17261    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17262    (parallel [(set (match_operand:XF 0 "register_operand" "")
17263                    (unspec:XF [(match_dup 5) (match_dup 1)]
17264                               UNSPEC_FPATAN))
17265               (clobber (match_scratch:XF 6 ""))])]
17266   "TARGET_USE_FANCY_MATH_387
17267    && flag_unsafe_math_optimizations"
17268 {
17269   int i;
17270
17271   if (optimize_insn_for_size_p ())
17272     FAIL;
17273
17274   for (i = 2; i < 6; i++)
17275     operands[i] = gen_reg_rtx (XFmode);
17276
17277   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17278 })
17279
17280 (define_expand "asin<mode>2"
17281   [(use (match_operand:MODEF 0 "register_operand" ""))
17282    (use (match_operand:MODEF 1 "general_operand" ""))]
17283  "TARGET_USE_FANCY_MATH_387
17284    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17285        || TARGET_MIX_SSE_I387)
17286    && flag_unsafe_math_optimizations"
17287 {
17288   rtx op0 = gen_reg_rtx (XFmode);
17289   rtx op1 = gen_reg_rtx (XFmode);
17290
17291   if (optimize_insn_for_size_p ())
17292     FAIL;
17293
17294   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17295   emit_insn (gen_asinxf2 (op0, op1));
17296   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17297   DONE;
17298 })
17299
17300 (define_expand "acosxf2"
17301   [(set (match_dup 2)
17302         (mult:XF (match_operand:XF 1 "register_operand" "")
17303                  (match_dup 1)))
17304    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17305    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17306    (parallel [(set (match_operand:XF 0 "register_operand" "")
17307                    (unspec:XF [(match_dup 1) (match_dup 5)]
17308                               UNSPEC_FPATAN))
17309               (clobber (match_scratch:XF 6 ""))])]
17310   "TARGET_USE_FANCY_MATH_387
17311    && flag_unsafe_math_optimizations"
17312 {
17313   int i;
17314
17315   if (optimize_insn_for_size_p ())
17316     FAIL;
17317
17318   for (i = 2; i < 6; i++)
17319     operands[i] = gen_reg_rtx (XFmode);
17320
17321   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17322 })
17323
17324 (define_expand "acos<mode>2"
17325   [(use (match_operand:MODEF 0 "register_operand" ""))
17326    (use (match_operand:MODEF 1 "general_operand" ""))]
17327  "TARGET_USE_FANCY_MATH_387
17328    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17329        || TARGET_MIX_SSE_I387)
17330    && flag_unsafe_math_optimizations"
17331 {
17332   rtx op0 = gen_reg_rtx (XFmode);
17333   rtx op1 = gen_reg_rtx (XFmode);
17334
17335   if (optimize_insn_for_size_p ())
17336     FAIL;
17337
17338   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17339   emit_insn (gen_acosxf2 (op0, op1));
17340   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17341   DONE;
17342 })
17343
17344 (define_insn "fyl2xxf3_i387"
17345   [(set (match_operand:XF 0 "register_operand" "=f")
17346         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17347                     (match_operand:XF 2 "register_operand" "u")]
17348                    UNSPEC_FYL2X))
17349    (clobber (match_scratch:XF 3 "=2"))]
17350   "TARGET_USE_FANCY_MATH_387
17351    && flag_unsafe_math_optimizations"
17352   "fyl2x"
17353   [(set_attr "type" "fpspc")
17354    (set_attr "mode" "XF")])
17355
17356 (define_insn "fyl2x_extend<mode>xf3_i387"
17357   [(set (match_operand:XF 0 "register_operand" "=f")
17358         (unspec:XF [(float_extend:XF
17359                       (match_operand:MODEF 1 "register_operand" "0"))
17360                     (match_operand:XF 2 "register_operand" "u")]
17361                    UNSPEC_FYL2X))
17362    (clobber (match_scratch:XF 3 "=2"))]
17363   "TARGET_USE_FANCY_MATH_387
17364    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17365        || TARGET_MIX_SSE_I387)
17366    && flag_unsafe_math_optimizations"
17367   "fyl2x"
17368   [(set_attr "type" "fpspc")
17369    (set_attr "mode" "XF")])
17370
17371 (define_expand "logxf2"
17372   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17373                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17374                                (match_dup 2)] UNSPEC_FYL2X))
17375               (clobber (match_scratch:XF 3 ""))])]
17376   "TARGET_USE_FANCY_MATH_387
17377    && flag_unsafe_math_optimizations"
17378 {
17379   operands[2] = gen_reg_rtx (XFmode);
17380   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17381 })
17382
17383 (define_expand "log<mode>2"
17384   [(use (match_operand:MODEF 0 "register_operand" ""))
17385    (use (match_operand:MODEF 1 "register_operand" ""))]
17386   "TARGET_USE_FANCY_MATH_387
17387    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17388        || TARGET_MIX_SSE_I387)
17389    && flag_unsafe_math_optimizations"
17390 {
17391   rtx op0 = gen_reg_rtx (XFmode);
17392
17393   rtx op2 = gen_reg_rtx (XFmode);
17394   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17395
17396   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17397   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17398   DONE;
17399 })
17400
17401 (define_expand "log10xf2"
17402   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17403                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17404                                (match_dup 2)] UNSPEC_FYL2X))
17405               (clobber (match_scratch:XF 3 ""))])]
17406   "TARGET_USE_FANCY_MATH_387
17407    && flag_unsafe_math_optimizations"
17408 {
17409   operands[2] = gen_reg_rtx (XFmode);
17410   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17411 })
17412
17413 (define_expand "log10<mode>2"
17414   [(use (match_operand:MODEF 0 "register_operand" ""))
17415    (use (match_operand:MODEF 1 "register_operand" ""))]
17416   "TARGET_USE_FANCY_MATH_387
17417    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17418        || TARGET_MIX_SSE_I387)
17419    && flag_unsafe_math_optimizations"
17420 {
17421   rtx op0 = gen_reg_rtx (XFmode);
17422
17423   rtx op2 = gen_reg_rtx (XFmode);
17424   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17425
17426   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17427   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17428   DONE;
17429 })
17430
17431 (define_expand "log2xf2"
17432   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17433                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17434                                (match_dup 2)] UNSPEC_FYL2X))
17435               (clobber (match_scratch:XF 3 ""))])]
17436   "TARGET_USE_FANCY_MATH_387
17437    && flag_unsafe_math_optimizations"
17438 {
17439   operands[2] = gen_reg_rtx (XFmode);
17440   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17441 })
17442
17443 (define_expand "log2<mode>2"
17444   [(use (match_operand:MODEF 0 "register_operand" ""))
17445    (use (match_operand:MODEF 1 "register_operand" ""))]
17446   "TARGET_USE_FANCY_MATH_387
17447    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17448        || TARGET_MIX_SSE_I387)
17449    && flag_unsafe_math_optimizations"
17450 {
17451   rtx op0 = gen_reg_rtx (XFmode);
17452
17453   rtx op2 = gen_reg_rtx (XFmode);
17454   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17455
17456   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17457   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17458   DONE;
17459 })
17460
17461 (define_insn "fyl2xp1xf3_i387"
17462   [(set (match_operand:XF 0 "register_operand" "=f")
17463         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17464                     (match_operand:XF 2 "register_operand" "u")]
17465                    UNSPEC_FYL2XP1))
17466    (clobber (match_scratch:XF 3 "=2"))]
17467   "TARGET_USE_FANCY_MATH_387
17468    && flag_unsafe_math_optimizations"
17469   "fyl2xp1"
17470   [(set_attr "type" "fpspc")
17471    (set_attr "mode" "XF")])
17472
17473 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17474   [(set (match_operand:XF 0 "register_operand" "=f")
17475         (unspec:XF [(float_extend:XF
17476                       (match_operand:MODEF 1 "register_operand" "0"))
17477                     (match_operand:XF 2 "register_operand" "u")]
17478                    UNSPEC_FYL2XP1))
17479    (clobber (match_scratch:XF 3 "=2"))]
17480   "TARGET_USE_FANCY_MATH_387
17481    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17482        || TARGET_MIX_SSE_I387)
17483    && flag_unsafe_math_optimizations"
17484   "fyl2xp1"
17485   [(set_attr "type" "fpspc")
17486    (set_attr "mode" "XF")])
17487
17488 (define_expand "log1pxf2"
17489   [(use (match_operand:XF 0 "register_operand" ""))
17490    (use (match_operand:XF 1 "register_operand" ""))]
17491   "TARGET_USE_FANCY_MATH_387
17492    && flag_unsafe_math_optimizations"
17493 {
17494   if (optimize_insn_for_size_p ())
17495     FAIL;
17496
17497   ix86_emit_i387_log1p (operands[0], operands[1]);
17498   DONE;
17499 })
17500
17501 (define_expand "log1p<mode>2"
17502   [(use (match_operand:MODEF 0 "register_operand" ""))
17503    (use (match_operand:MODEF 1 "register_operand" ""))]
17504   "TARGET_USE_FANCY_MATH_387
17505    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17506        || TARGET_MIX_SSE_I387)
17507    && flag_unsafe_math_optimizations"
17508 {
17509   rtx op0;
17510
17511   if (optimize_insn_for_size_p ())
17512     FAIL;
17513
17514   op0 = gen_reg_rtx (XFmode);
17515
17516   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17517
17518   ix86_emit_i387_log1p (op0, operands[1]);
17519   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17520   DONE;
17521 })
17522
17523 (define_insn "fxtractxf3_i387"
17524   [(set (match_operand:XF 0 "register_operand" "=f")
17525         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17526                    UNSPEC_XTRACT_FRACT))
17527    (set (match_operand:XF 1 "register_operand" "=u")
17528         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17529   "TARGET_USE_FANCY_MATH_387
17530    && flag_unsafe_math_optimizations"
17531   "fxtract"
17532   [(set_attr "type" "fpspc")
17533    (set_attr "mode" "XF")])
17534
17535 (define_insn "fxtract_extend<mode>xf3_i387"
17536   [(set (match_operand:XF 0 "register_operand" "=f")
17537         (unspec:XF [(float_extend:XF
17538                       (match_operand:MODEF 2 "register_operand" "0"))]
17539                    UNSPEC_XTRACT_FRACT))
17540    (set (match_operand:XF 1 "register_operand" "=u")
17541         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17542   "TARGET_USE_FANCY_MATH_387
17543    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17544        || TARGET_MIX_SSE_I387)
17545    && flag_unsafe_math_optimizations"
17546   "fxtract"
17547   [(set_attr "type" "fpspc")
17548    (set_attr "mode" "XF")])
17549
17550 (define_expand "logbxf2"
17551   [(parallel [(set (match_dup 2)
17552                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17553                               UNSPEC_XTRACT_FRACT))
17554               (set (match_operand:XF 0 "register_operand" "")
17555                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17556   "TARGET_USE_FANCY_MATH_387
17557    && flag_unsafe_math_optimizations"
17558 {
17559   operands[2] = gen_reg_rtx (XFmode);
17560 })
17561
17562 (define_expand "logb<mode>2"
17563   [(use (match_operand:MODEF 0 "register_operand" ""))
17564    (use (match_operand:MODEF 1 "register_operand" ""))]
17565   "TARGET_USE_FANCY_MATH_387
17566    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17567        || TARGET_MIX_SSE_I387)
17568    && flag_unsafe_math_optimizations"
17569 {
17570   rtx op0 = gen_reg_rtx (XFmode);
17571   rtx op1 = gen_reg_rtx (XFmode);
17572
17573   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17574   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17575   DONE;
17576 })
17577
17578 (define_expand "ilogbxf2"
17579   [(use (match_operand:SI 0 "register_operand" ""))
17580    (use (match_operand:XF 1 "register_operand" ""))]
17581   "TARGET_USE_FANCY_MATH_387
17582    && flag_unsafe_math_optimizations"
17583 {
17584   rtx op0, op1;
17585
17586   if (optimize_insn_for_size_p ())
17587     FAIL;
17588
17589   op0 = gen_reg_rtx (XFmode);
17590   op1 = gen_reg_rtx (XFmode);
17591
17592   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17593   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17594   DONE;
17595 })
17596
17597 (define_expand "ilogb<mode>2"
17598   [(use (match_operand:SI 0 "register_operand" ""))
17599    (use (match_operand:MODEF 1 "register_operand" ""))]
17600   "TARGET_USE_FANCY_MATH_387
17601    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17602        || TARGET_MIX_SSE_I387)
17603    && flag_unsafe_math_optimizations"
17604 {
17605   rtx op0, op1;
17606
17607   if (optimize_insn_for_size_p ())
17608     FAIL;
17609
17610   op0 = gen_reg_rtx (XFmode);
17611   op1 = gen_reg_rtx (XFmode);
17612
17613   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17614   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17615   DONE;
17616 })
17617
17618 (define_insn "*f2xm1xf2_i387"
17619   [(set (match_operand:XF 0 "register_operand" "=f")
17620         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17621                    UNSPEC_F2XM1))]
17622   "TARGET_USE_FANCY_MATH_387
17623    && flag_unsafe_math_optimizations"
17624   "f2xm1"
17625   [(set_attr "type" "fpspc")
17626    (set_attr "mode" "XF")])
17627
17628 (define_insn "*fscalexf4_i387"
17629   [(set (match_operand:XF 0 "register_operand" "=f")
17630         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17631                     (match_operand:XF 3 "register_operand" "1")]
17632                    UNSPEC_FSCALE_FRACT))
17633    (set (match_operand:XF 1 "register_operand" "=u")
17634         (unspec:XF [(match_dup 2) (match_dup 3)]
17635                    UNSPEC_FSCALE_EXP))]
17636   "TARGET_USE_FANCY_MATH_387
17637    && flag_unsafe_math_optimizations"
17638   "fscale"
17639   [(set_attr "type" "fpspc")
17640    (set_attr "mode" "XF")])
17641
17642 (define_expand "expNcorexf3"
17643   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17644                                (match_operand:XF 2 "register_operand" "")))
17645    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17646    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17647    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17648    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17649    (parallel [(set (match_operand:XF 0 "register_operand" "")
17650                    (unspec:XF [(match_dup 8) (match_dup 4)]
17651                               UNSPEC_FSCALE_FRACT))
17652               (set (match_dup 9)
17653                    (unspec:XF [(match_dup 8) (match_dup 4)]
17654                               UNSPEC_FSCALE_EXP))])]
17655   "TARGET_USE_FANCY_MATH_387
17656    && flag_unsafe_math_optimizations"
17657 {
17658   int i;
17659
17660   if (optimize_insn_for_size_p ())
17661     FAIL;
17662
17663   for (i = 3; i < 10; i++)
17664     operands[i] = gen_reg_rtx (XFmode);
17665
17666   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17667 })
17668
17669 (define_expand "expxf2"
17670   [(use (match_operand:XF 0 "register_operand" ""))
17671    (use (match_operand:XF 1 "register_operand" ""))]
17672   "TARGET_USE_FANCY_MATH_387
17673    && flag_unsafe_math_optimizations"
17674 {
17675   rtx op2;
17676
17677   if (optimize_insn_for_size_p ())
17678     FAIL;
17679
17680   op2 = gen_reg_rtx (XFmode);
17681   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17682
17683   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17684   DONE;
17685 })
17686
17687 (define_expand "exp<mode>2"
17688   [(use (match_operand:MODEF 0 "register_operand" ""))
17689    (use (match_operand:MODEF 1 "general_operand" ""))]
17690  "TARGET_USE_FANCY_MATH_387
17691    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17692        || TARGET_MIX_SSE_I387)
17693    && flag_unsafe_math_optimizations"
17694 {
17695   rtx op0, op1;
17696
17697   if (optimize_insn_for_size_p ())
17698     FAIL;
17699
17700   op0 = gen_reg_rtx (XFmode);
17701   op1 = gen_reg_rtx (XFmode);
17702
17703   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17704   emit_insn (gen_expxf2 (op0, op1));
17705   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17706   DONE;
17707 })
17708
17709 (define_expand "exp10xf2"
17710   [(use (match_operand:XF 0 "register_operand" ""))
17711    (use (match_operand:XF 1 "register_operand" ""))]
17712   "TARGET_USE_FANCY_MATH_387
17713    && flag_unsafe_math_optimizations"
17714 {
17715   rtx op2;
17716
17717   if (optimize_insn_for_size_p ())
17718     FAIL;
17719
17720   op2 = gen_reg_rtx (XFmode);
17721   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17722
17723   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17724   DONE;
17725 })
17726
17727 (define_expand "exp10<mode>2"
17728   [(use (match_operand:MODEF 0 "register_operand" ""))
17729    (use (match_operand:MODEF 1 "general_operand" ""))]
17730  "TARGET_USE_FANCY_MATH_387
17731    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17732        || TARGET_MIX_SSE_I387)
17733    && flag_unsafe_math_optimizations"
17734 {
17735   rtx op0, op1;
17736
17737   if (optimize_insn_for_size_p ())
17738     FAIL;
17739
17740   op0 = gen_reg_rtx (XFmode);
17741   op1 = gen_reg_rtx (XFmode);
17742
17743   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17744   emit_insn (gen_exp10xf2 (op0, op1));
17745   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17746   DONE;
17747 })
17748
17749 (define_expand "exp2xf2"
17750   [(use (match_operand:XF 0 "register_operand" ""))
17751    (use (match_operand:XF 1 "register_operand" ""))]
17752   "TARGET_USE_FANCY_MATH_387
17753    && flag_unsafe_math_optimizations"
17754 {
17755   rtx op2;
17756
17757   if (optimize_insn_for_size_p ())
17758     FAIL;
17759
17760   op2 = gen_reg_rtx (XFmode);
17761   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17762
17763   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17764   DONE;
17765 })
17766
17767 (define_expand "exp2<mode>2"
17768   [(use (match_operand:MODEF 0 "register_operand" ""))
17769    (use (match_operand:MODEF 1 "general_operand" ""))]
17770  "TARGET_USE_FANCY_MATH_387
17771    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17772        || TARGET_MIX_SSE_I387)
17773    && flag_unsafe_math_optimizations"
17774 {
17775   rtx op0, op1;
17776
17777   if (optimize_insn_for_size_p ())
17778     FAIL;
17779
17780   op0 = gen_reg_rtx (XFmode);
17781   op1 = gen_reg_rtx (XFmode);
17782
17783   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17784   emit_insn (gen_exp2xf2 (op0, op1));
17785   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17786   DONE;
17787 })
17788
17789 (define_expand "expm1xf2"
17790   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17791                                (match_dup 2)))
17792    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17793    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17794    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17795    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17796    (parallel [(set (match_dup 7)
17797                    (unspec:XF [(match_dup 6) (match_dup 4)]
17798                               UNSPEC_FSCALE_FRACT))
17799               (set (match_dup 8)
17800                    (unspec:XF [(match_dup 6) (match_dup 4)]
17801                               UNSPEC_FSCALE_EXP))])
17802    (parallel [(set (match_dup 10)
17803                    (unspec:XF [(match_dup 9) (match_dup 8)]
17804                               UNSPEC_FSCALE_FRACT))
17805               (set (match_dup 11)
17806                    (unspec:XF [(match_dup 9) (match_dup 8)]
17807                               UNSPEC_FSCALE_EXP))])
17808    (set (match_dup 12) (minus:XF (match_dup 10)
17809                                  (float_extend:XF (match_dup 13))))
17810    (set (match_operand:XF 0 "register_operand" "")
17811         (plus:XF (match_dup 12) (match_dup 7)))]
17812   "TARGET_USE_FANCY_MATH_387
17813    && flag_unsafe_math_optimizations"
17814 {
17815   int i;
17816
17817   if (optimize_insn_for_size_p ())
17818     FAIL;
17819
17820   for (i = 2; i < 13; i++)
17821     operands[i] = gen_reg_rtx (XFmode);
17822
17823   operands[13]
17824     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17825
17826   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17827 })
17828
17829 (define_expand "expm1<mode>2"
17830   [(use (match_operand:MODEF 0 "register_operand" ""))
17831    (use (match_operand:MODEF 1 "general_operand" ""))]
17832  "TARGET_USE_FANCY_MATH_387
17833    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17834        || TARGET_MIX_SSE_I387)
17835    && flag_unsafe_math_optimizations"
17836 {
17837   rtx op0, op1;
17838
17839   if (optimize_insn_for_size_p ())
17840     FAIL;
17841
17842   op0 = gen_reg_rtx (XFmode);
17843   op1 = gen_reg_rtx (XFmode);
17844
17845   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17846   emit_insn (gen_expm1xf2 (op0, op1));
17847   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17848   DONE;
17849 })
17850
17851 (define_expand "ldexpxf3"
17852   [(set (match_dup 3)
17853         (float:XF (match_operand:SI 2 "register_operand" "")))
17854    (parallel [(set (match_operand:XF 0 " register_operand" "")
17855                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17856                                (match_dup 3)]
17857                               UNSPEC_FSCALE_FRACT))
17858               (set (match_dup 4)
17859                    (unspec:XF [(match_dup 1) (match_dup 3)]
17860                               UNSPEC_FSCALE_EXP))])]
17861   "TARGET_USE_FANCY_MATH_387
17862    && flag_unsafe_math_optimizations"
17863 {
17864   if (optimize_insn_for_size_p ())
17865     FAIL;
17866
17867   operands[3] = gen_reg_rtx (XFmode);
17868   operands[4] = gen_reg_rtx (XFmode);
17869 })
17870
17871 (define_expand "ldexp<mode>3"
17872   [(use (match_operand:MODEF 0 "register_operand" ""))
17873    (use (match_operand:MODEF 1 "general_operand" ""))
17874    (use (match_operand:SI 2 "register_operand" ""))]
17875  "TARGET_USE_FANCY_MATH_387
17876    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17877        || TARGET_MIX_SSE_I387)
17878    && flag_unsafe_math_optimizations"
17879 {
17880   rtx op0, op1;
17881
17882   if (optimize_insn_for_size_p ())
17883     FAIL;
17884
17885   op0 = gen_reg_rtx (XFmode);
17886   op1 = gen_reg_rtx (XFmode);
17887
17888   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17889   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17890   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17891   DONE;
17892 })
17893
17894 (define_expand "scalbxf3"
17895   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17896                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17897                                (match_operand:XF 2 "register_operand" "")]
17898                               UNSPEC_FSCALE_FRACT))
17899               (set (match_dup 3)
17900                    (unspec:XF [(match_dup 1) (match_dup 2)]
17901                               UNSPEC_FSCALE_EXP))])]
17902   "TARGET_USE_FANCY_MATH_387
17903    && flag_unsafe_math_optimizations"
17904 {
17905   if (optimize_insn_for_size_p ())
17906     FAIL;
17907
17908   operands[3] = gen_reg_rtx (XFmode);
17909 })
17910
17911 (define_expand "scalb<mode>3"
17912   [(use (match_operand:MODEF 0 "register_operand" ""))
17913    (use (match_operand:MODEF 1 "general_operand" ""))
17914    (use (match_operand:MODEF 2 "register_operand" ""))]
17915  "TARGET_USE_FANCY_MATH_387
17916    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17917        || TARGET_MIX_SSE_I387)
17918    && flag_unsafe_math_optimizations"
17919 {
17920   rtx op0, op1, op2;
17921
17922   if (optimize_insn_for_size_p ())
17923     FAIL;
17924
17925   op0 = gen_reg_rtx (XFmode);
17926   op1 = gen_reg_rtx (XFmode);
17927   op2 = gen_reg_rtx (XFmode);
17928
17929   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17930   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17931   emit_insn (gen_scalbxf3 (op0, op1, op2));
17932   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17933   DONE;
17934 })
17935 \f
17936
17937 (define_insn "sse4_1_round<mode>2"
17938   [(set (match_operand:MODEF 0 "register_operand" "=x")
17939         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17940                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17941                       UNSPEC_ROUND))]
17942   "TARGET_ROUND"
17943   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17944   [(set_attr "type" "ssecvt")
17945    (set_attr "prefix_extra" "1")
17946    (set_attr "prefix" "maybe_vex")
17947    (set_attr "mode" "<MODE>")])
17948
17949 (define_insn "rintxf2"
17950   [(set (match_operand:XF 0 "register_operand" "=f")
17951         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17952                    UNSPEC_FRNDINT))]
17953   "TARGET_USE_FANCY_MATH_387
17954    && flag_unsafe_math_optimizations"
17955   "frndint"
17956   [(set_attr "type" "fpspc")
17957    (set_attr "mode" "XF")])
17958
17959 (define_expand "rint<mode>2"
17960   [(use (match_operand:MODEF 0 "register_operand" ""))
17961    (use (match_operand:MODEF 1 "register_operand" ""))]
17962   "(TARGET_USE_FANCY_MATH_387
17963     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17964         || TARGET_MIX_SSE_I387)
17965     && flag_unsafe_math_optimizations)
17966    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17967        && !flag_trapping_math)"
17968 {
17969   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17970       && !flag_trapping_math)
17971     {
17972       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17973         FAIL;
17974       if (TARGET_ROUND)
17975         emit_insn (gen_sse4_1_round<mode>2
17976                    (operands[0], operands[1], GEN_INT (0x04)));
17977       else
17978         ix86_expand_rint (operand0, operand1);
17979     }
17980   else
17981     {
17982       rtx op0 = gen_reg_rtx (XFmode);
17983       rtx op1 = gen_reg_rtx (XFmode);
17984
17985       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17986       emit_insn (gen_rintxf2 (op0, op1));
17987
17988       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17989     }
17990   DONE;
17991 })
17992
17993 (define_expand "round<mode>2"
17994   [(match_operand:MODEF 0 "register_operand" "")
17995    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17996   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17997    && !flag_trapping_math && !flag_rounding_math"
17998 {
17999   if (optimize_insn_for_size_p ())
18000     FAIL;
18001   if (TARGET_64BIT || (<MODE>mode != DFmode))
18002     ix86_expand_round (operand0, operand1);
18003   else
18004     ix86_expand_rounddf_32 (operand0, operand1);
18005   DONE;
18006 })
18007
18008 (define_insn_and_split "*fistdi2_1"
18009   [(set (match_operand:DI 0 "nonimmediate_operand" "")
18010         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18011                    UNSPEC_FIST))]
18012   "TARGET_USE_FANCY_MATH_387
18013    && !(reload_completed || reload_in_progress)"
18014   "#"
18015   "&& 1"
18016   [(const_int 0)]
18017 {
18018   if (memory_operand (operands[0], VOIDmode))
18019     emit_insn (gen_fistdi2 (operands[0], operands[1]));
18020   else
18021     {
18022       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18023       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18024                                          operands[2]));
18025     }
18026   DONE;
18027 }
18028   [(set_attr "type" "fpspc")
18029    (set_attr "mode" "DI")])
18030
18031 (define_insn "fistdi2"
18032   [(set (match_operand:DI 0 "memory_operand" "=m")
18033         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18034                    UNSPEC_FIST))
18035    (clobber (match_scratch:XF 2 "=&1f"))]
18036   "TARGET_USE_FANCY_MATH_387"
18037   "* return output_fix_trunc (insn, operands, 0);"
18038   [(set_attr "type" "fpspc")
18039    (set_attr "mode" "DI")])
18040
18041 (define_insn "fistdi2_with_temp"
18042   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18043         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18044                    UNSPEC_FIST))
18045    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18046    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18047   "TARGET_USE_FANCY_MATH_387"
18048   "#"
18049   [(set_attr "type" "fpspc")
18050    (set_attr "mode" "DI")])
18051
18052 (define_split
18053   [(set (match_operand:DI 0 "register_operand" "")
18054         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18055                    UNSPEC_FIST))
18056    (clobber (match_operand:DI 2 "memory_operand" ""))
18057    (clobber (match_scratch 3 ""))]
18058   "reload_completed"
18059   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18060               (clobber (match_dup 3))])
18061    (set (match_dup 0) (match_dup 2))]
18062   "")
18063
18064 (define_split
18065   [(set (match_operand:DI 0 "memory_operand" "")
18066         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18067                    UNSPEC_FIST))
18068    (clobber (match_operand:DI 2 "memory_operand" ""))
18069    (clobber (match_scratch 3 ""))]
18070   "reload_completed"
18071   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18072               (clobber (match_dup 3))])]
18073   "")
18074
18075 (define_insn_and_split "*fist<mode>2_1"
18076   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18077         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18078                            UNSPEC_FIST))]
18079   "TARGET_USE_FANCY_MATH_387
18080    && !(reload_completed || reload_in_progress)"
18081   "#"
18082   "&& 1"
18083   [(const_int 0)]
18084 {
18085   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18086   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18087                                         operands[2]));
18088   DONE;
18089 }
18090   [(set_attr "type" "fpspc")
18091    (set_attr "mode" "<MODE>")])
18092
18093 (define_insn "fist<mode>2"
18094   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18095         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18096                            UNSPEC_FIST))]
18097   "TARGET_USE_FANCY_MATH_387"
18098   "* return output_fix_trunc (insn, operands, 0);"
18099   [(set_attr "type" "fpspc")
18100    (set_attr "mode" "<MODE>")])
18101
18102 (define_insn "fist<mode>2_with_temp"
18103   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18104         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18105                            UNSPEC_FIST))
18106    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18107   "TARGET_USE_FANCY_MATH_387"
18108   "#"
18109   [(set_attr "type" "fpspc")
18110    (set_attr "mode" "<MODE>")])
18111
18112 (define_split
18113   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18114         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18115                            UNSPEC_FIST))
18116    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18117   "reload_completed"
18118   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18119    (set (match_dup 0) (match_dup 2))]
18120   "")
18121
18122 (define_split
18123   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18124         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18125                            UNSPEC_FIST))
18126    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18127   "reload_completed"
18128   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18129   "")
18130
18131 (define_expand "lrintxf<mode>2"
18132   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18133      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18134                       UNSPEC_FIST))]
18135   "TARGET_USE_FANCY_MATH_387"
18136   "")
18137
18138 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18139   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18140      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18141                         UNSPEC_FIX_NOTRUNC))]
18142   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18143    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18144   "")
18145
18146 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18147   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18148    (match_operand:MODEF 1 "register_operand" "")]
18149   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18150    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18151    && !flag_trapping_math && !flag_rounding_math"
18152 {
18153   if (optimize_insn_for_size_p ())
18154     FAIL;
18155   ix86_expand_lround (operand0, operand1);
18156   DONE;
18157 })
18158
18159 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18160 (define_insn_and_split "frndintxf2_floor"
18161   [(set (match_operand:XF 0 "register_operand" "")
18162         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18163          UNSPEC_FRNDINT_FLOOR))
18164    (clobber (reg:CC FLAGS_REG))]
18165   "TARGET_USE_FANCY_MATH_387
18166    && flag_unsafe_math_optimizations
18167    && !(reload_completed || reload_in_progress)"
18168   "#"
18169   "&& 1"
18170   [(const_int 0)]
18171 {
18172   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18173
18174   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18175   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18176
18177   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18178                                         operands[2], operands[3]));
18179   DONE;
18180 }
18181   [(set_attr "type" "frndint")
18182    (set_attr "i387_cw" "floor")
18183    (set_attr "mode" "XF")])
18184
18185 (define_insn "frndintxf2_floor_i387"
18186   [(set (match_operand:XF 0 "register_operand" "=f")
18187         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18188          UNSPEC_FRNDINT_FLOOR))
18189    (use (match_operand:HI 2 "memory_operand" "m"))
18190    (use (match_operand:HI 3 "memory_operand" "m"))]
18191   "TARGET_USE_FANCY_MATH_387
18192    && flag_unsafe_math_optimizations"
18193   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18194   [(set_attr "type" "frndint")
18195    (set_attr "i387_cw" "floor")
18196    (set_attr "mode" "XF")])
18197
18198 (define_expand "floorxf2"
18199   [(use (match_operand:XF 0 "register_operand" ""))
18200    (use (match_operand:XF 1 "register_operand" ""))]
18201   "TARGET_USE_FANCY_MATH_387
18202    && flag_unsafe_math_optimizations"
18203 {
18204   if (optimize_insn_for_size_p ())
18205     FAIL;
18206   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18207   DONE;
18208 })
18209
18210 (define_expand "floor<mode>2"
18211   [(use (match_operand:MODEF 0 "register_operand" ""))
18212    (use (match_operand:MODEF 1 "register_operand" ""))]
18213   "(TARGET_USE_FANCY_MATH_387
18214     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18215         || TARGET_MIX_SSE_I387)
18216     && flag_unsafe_math_optimizations)
18217    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18218        && !flag_trapping_math)"
18219 {
18220   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18221       && !flag_trapping_math
18222       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18223     {
18224       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18225         FAIL;
18226       if (TARGET_ROUND)
18227         emit_insn (gen_sse4_1_round<mode>2
18228                    (operands[0], operands[1], GEN_INT (0x01)));
18229       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18230         ix86_expand_floorceil (operand0, operand1, true);
18231       else
18232         ix86_expand_floorceildf_32 (operand0, operand1, true);
18233     }
18234   else
18235     {
18236       rtx op0, op1;
18237
18238       if (optimize_insn_for_size_p ())
18239         FAIL;
18240
18241       op0 = gen_reg_rtx (XFmode);
18242       op1 = gen_reg_rtx (XFmode);
18243       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18244       emit_insn (gen_frndintxf2_floor (op0, op1));
18245
18246       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18247     }
18248   DONE;
18249 })
18250
18251 (define_insn_and_split "*fist<mode>2_floor_1"
18252   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18253         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18254          UNSPEC_FIST_FLOOR))
18255    (clobber (reg:CC FLAGS_REG))]
18256   "TARGET_USE_FANCY_MATH_387
18257    && flag_unsafe_math_optimizations
18258    && !(reload_completed || reload_in_progress)"
18259   "#"
18260   "&& 1"
18261   [(const_int 0)]
18262 {
18263   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18264
18265   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18266   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18267   if (memory_operand (operands[0], VOIDmode))
18268     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18269                                       operands[2], operands[3]));
18270   else
18271     {
18272       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18273       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18274                                                   operands[2], operands[3],
18275                                                   operands[4]));
18276     }
18277   DONE;
18278 }
18279   [(set_attr "type" "fistp")
18280    (set_attr "i387_cw" "floor")
18281    (set_attr "mode" "<MODE>")])
18282
18283 (define_insn "fistdi2_floor"
18284   [(set (match_operand:DI 0 "memory_operand" "=m")
18285         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18286          UNSPEC_FIST_FLOOR))
18287    (use (match_operand:HI 2 "memory_operand" "m"))
18288    (use (match_operand:HI 3 "memory_operand" "m"))
18289    (clobber (match_scratch:XF 4 "=&1f"))]
18290   "TARGET_USE_FANCY_MATH_387
18291    && flag_unsafe_math_optimizations"
18292   "* return output_fix_trunc (insn, operands, 0);"
18293   [(set_attr "type" "fistp")
18294    (set_attr "i387_cw" "floor")
18295    (set_attr "mode" "DI")])
18296
18297 (define_insn "fistdi2_floor_with_temp"
18298   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18299         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18300          UNSPEC_FIST_FLOOR))
18301    (use (match_operand:HI 2 "memory_operand" "m,m"))
18302    (use (match_operand:HI 3 "memory_operand" "m,m"))
18303    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18304    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18305   "TARGET_USE_FANCY_MATH_387
18306    && flag_unsafe_math_optimizations"
18307   "#"
18308   [(set_attr "type" "fistp")
18309    (set_attr "i387_cw" "floor")
18310    (set_attr "mode" "DI")])
18311
18312 (define_split
18313   [(set (match_operand:DI 0 "register_operand" "")
18314         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18315          UNSPEC_FIST_FLOOR))
18316    (use (match_operand:HI 2 "memory_operand" ""))
18317    (use (match_operand:HI 3 "memory_operand" ""))
18318    (clobber (match_operand:DI 4 "memory_operand" ""))
18319    (clobber (match_scratch 5 ""))]
18320   "reload_completed"
18321   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18322               (use (match_dup 2))
18323               (use (match_dup 3))
18324               (clobber (match_dup 5))])
18325    (set (match_dup 0) (match_dup 4))]
18326   "")
18327
18328 (define_split
18329   [(set (match_operand:DI 0 "memory_operand" "")
18330         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18331          UNSPEC_FIST_FLOOR))
18332    (use (match_operand:HI 2 "memory_operand" ""))
18333    (use (match_operand:HI 3 "memory_operand" ""))
18334    (clobber (match_operand:DI 4 "memory_operand" ""))
18335    (clobber (match_scratch 5 ""))]
18336   "reload_completed"
18337   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18338               (use (match_dup 2))
18339               (use (match_dup 3))
18340               (clobber (match_dup 5))])]
18341   "")
18342
18343 (define_insn "fist<mode>2_floor"
18344   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18345         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18346          UNSPEC_FIST_FLOOR))
18347    (use (match_operand:HI 2 "memory_operand" "m"))
18348    (use (match_operand:HI 3 "memory_operand" "m"))]
18349   "TARGET_USE_FANCY_MATH_387
18350    && flag_unsafe_math_optimizations"
18351   "* return output_fix_trunc (insn, operands, 0);"
18352   [(set_attr "type" "fistp")
18353    (set_attr "i387_cw" "floor")
18354    (set_attr "mode" "<MODE>")])
18355
18356 (define_insn "fist<mode>2_floor_with_temp"
18357   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18358         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18359          UNSPEC_FIST_FLOOR))
18360    (use (match_operand:HI 2 "memory_operand" "m,m"))
18361    (use (match_operand:HI 3 "memory_operand" "m,m"))
18362    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18363   "TARGET_USE_FANCY_MATH_387
18364    && flag_unsafe_math_optimizations"
18365   "#"
18366   [(set_attr "type" "fistp")
18367    (set_attr "i387_cw" "floor")
18368    (set_attr "mode" "<MODE>")])
18369
18370 (define_split
18371   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18372         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18373          UNSPEC_FIST_FLOOR))
18374    (use (match_operand:HI 2 "memory_operand" ""))
18375    (use (match_operand:HI 3 "memory_operand" ""))
18376    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18377   "reload_completed"
18378   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18379                                   UNSPEC_FIST_FLOOR))
18380               (use (match_dup 2))
18381               (use (match_dup 3))])
18382    (set (match_dup 0) (match_dup 4))]
18383   "")
18384
18385 (define_split
18386   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18387         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18388          UNSPEC_FIST_FLOOR))
18389    (use (match_operand:HI 2 "memory_operand" ""))
18390    (use (match_operand:HI 3 "memory_operand" ""))
18391    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18392   "reload_completed"
18393   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18394                                   UNSPEC_FIST_FLOOR))
18395               (use (match_dup 2))
18396               (use (match_dup 3))])]
18397   "")
18398
18399 (define_expand "lfloorxf<mode>2"
18400   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18401                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18402                     UNSPEC_FIST_FLOOR))
18403               (clobber (reg:CC FLAGS_REG))])]
18404   "TARGET_USE_FANCY_MATH_387
18405    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18406    && flag_unsafe_math_optimizations"
18407   "")
18408
18409 (define_expand "lfloor<mode>di2"
18410   [(match_operand:DI 0 "nonimmediate_operand" "")
18411    (match_operand:MODEF 1 "register_operand" "")]
18412   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18413    && !flag_trapping_math"
18414 {
18415   if (optimize_insn_for_size_p ())
18416     FAIL;
18417   ix86_expand_lfloorceil (operand0, operand1, true);
18418   DONE;
18419 })
18420
18421 (define_expand "lfloor<mode>si2"
18422   [(match_operand:SI 0 "nonimmediate_operand" "")
18423    (match_operand:MODEF 1 "register_operand" "")]
18424   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18425    && !flag_trapping_math"
18426 {
18427   if (optimize_insn_for_size_p () && TARGET_64BIT)
18428     FAIL;
18429   ix86_expand_lfloorceil (operand0, operand1, true);
18430   DONE;
18431 })
18432
18433 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18434 (define_insn_and_split "frndintxf2_ceil"
18435   [(set (match_operand:XF 0 "register_operand" "")
18436         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18437          UNSPEC_FRNDINT_CEIL))
18438    (clobber (reg:CC FLAGS_REG))]
18439   "TARGET_USE_FANCY_MATH_387
18440    && flag_unsafe_math_optimizations
18441    && !(reload_completed || reload_in_progress)"
18442   "#"
18443   "&& 1"
18444   [(const_int 0)]
18445 {
18446   ix86_optimize_mode_switching[I387_CEIL] = 1;
18447
18448   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18449   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18450
18451   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18452                                        operands[2], operands[3]));
18453   DONE;
18454 }
18455   [(set_attr "type" "frndint")
18456    (set_attr "i387_cw" "ceil")
18457    (set_attr "mode" "XF")])
18458
18459 (define_insn "frndintxf2_ceil_i387"
18460   [(set (match_operand:XF 0 "register_operand" "=f")
18461         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18462          UNSPEC_FRNDINT_CEIL))
18463    (use (match_operand:HI 2 "memory_operand" "m"))
18464    (use (match_operand:HI 3 "memory_operand" "m"))]
18465   "TARGET_USE_FANCY_MATH_387
18466    && flag_unsafe_math_optimizations"
18467   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18468   [(set_attr "type" "frndint")
18469    (set_attr "i387_cw" "ceil")
18470    (set_attr "mode" "XF")])
18471
18472 (define_expand "ceilxf2"
18473   [(use (match_operand:XF 0 "register_operand" ""))
18474    (use (match_operand:XF 1 "register_operand" ""))]
18475   "TARGET_USE_FANCY_MATH_387
18476    && flag_unsafe_math_optimizations"
18477 {
18478   if (optimize_insn_for_size_p ())
18479     FAIL;
18480   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18481   DONE;
18482 })
18483
18484 (define_expand "ceil<mode>2"
18485   [(use (match_operand:MODEF 0 "register_operand" ""))
18486    (use (match_operand:MODEF 1 "register_operand" ""))]
18487   "(TARGET_USE_FANCY_MATH_387
18488     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18489         || TARGET_MIX_SSE_I387)
18490     && flag_unsafe_math_optimizations)
18491    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18492        && !flag_trapping_math)"
18493 {
18494   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18495       && !flag_trapping_math
18496       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18497     {
18498       if (TARGET_ROUND)
18499         emit_insn (gen_sse4_1_round<mode>2
18500                    (operands[0], operands[1], GEN_INT (0x02)));
18501       else if (optimize_insn_for_size_p ())
18502         FAIL;
18503       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18504         ix86_expand_floorceil (operand0, operand1, false);
18505       else
18506         ix86_expand_floorceildf_32 (operand0, operand1, false);
18507     }
18508   else
18509     {
18510       rtx op0, op1;
18511
18512       if (optimize_insn_for_size_p ())
18513         FAIL;
18514
18515       op0 = gen_reg_rtx (XFmode);
18516       op1 = gen_reg_rtx (XFmode);
18517       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18518       emit_insn (gen_frndintxf2_ceil (op0, op1));
18519
18520       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18521     }
18522   DONE;
18523 })
18524
18525 (define_insn_and_split "*fist<mode>2_ceil_1"
18526   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18527         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18528          UNSPEC_FIST_CEIL))
18529    (clobber (reg:CC FLAGS_REG))]
18530   "TARGET_USE_FANCY_MATH_387
18531    && flag_unsafe_math_optimizations
18532    && !(reload_completed || reload_in_progress)"
18533   "#"
18534   "&& 1"
18535   [(const_int 0)]
18536 {
18537   ix86_optimize_mode_switching[I387_CEIL] = 1;
18538
18539   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18540   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18541   if (memory_operand (operands[0], VOIDmode))
18542     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18543                                      operands[2], operands[3]));
18544   else
18545     {
18546       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18547       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18548                                                  operands[2], operands[3],
18549                                                  operands[4]));
18550     }
18551   DONE;
18552 }
18553   [(set_attr "type" "fistp")
18554    (set_attr "i387_cw" "ceil")
18555    (set_attr "mode" "<MODE>")])
18556
18557 (define_insn "fistdi2_ceil"
18558   [(set (match_operand:DI 0 "memory_operand" "=m")
18559         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18560          UNSPEC_FIST_CEIL))
18561    (use (match_operand:HI 2 "memory_operand" "m"))
18562    (use (match_operand:HI 3 "memory_operand" "m"))
18563    (clobber (match_scratch:XF 4 "=&1f"))]
18564   "TARGET_USE_FANCY_MATH_387
18565    && flag_unsafe_math_optimizations"
18566   "* return output_fix_trunc (insn, operands, 0);"
18567   [(set_attr "type" "fistp")
18568    (set_attr "i387_cw" "ceil")
18569    (set_attr "mode" "DI")])
18570
18571 (define_insn "fistdi2_ceil_with_temp"
18572   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18573         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18574          UNSPEC_FIST_CEIL))
18575    (use (match_operand:HI 2 "memory_operand" "m,m"))
18576    (use (match_operand:HI 3 "memory_operand" "m,m"))
18577    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18578    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18579   "TARGET_USE_FANCY_MATH_387
18580    && flag_unsafe_math_optimizations"
18581   "#"
18582   [(set_attr "type" "fistp")
18583    (set_attr "i387_cw" "ceil")
18584    (set_attr "mode" "DI")])
18585
18586 (define_split
18587   [(set (match_operand:DI 0 "register_operand" "")
18588         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18589          UNSPEC_FIST_CEIL))
18590    (use (match_operand:HI 2 "memory_operand" ""))
18591    (use (match_operand:HI 3 "memory_operand" ""))
18592    (clobber (match_operand:DI 4 "memory_operand" ""))
18593    (clobber (match_scratch 5 ""))]
18594   "reload_completed"
18595   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18596               (use (match_dup 2))
18597               (use (match_dup 3))
18598               (clobber (match_dup 5))])
18599    (set (match_dup 0) (match_dup 4))]
18600   "")
18601
18602 (define_split
18603   [(set (match_operand:DI 0 "memory_operand" "")
18604         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18605          UNSPEC_FIST_CEIL))
18606    (use (match_operand:HI 2 "memory_operand" ""))
18607    (use (match_operand:HI 3 "memory_operand" ""))
18608    (clobber (match_operand:DI 4 "memory_operand" ""))
18609    (clobber (match_scratch 5 ""))]
18610   "reload_completed"
18611   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18612               (use (match_dup 2))
18613               (use (match_dup 3))
18614               (clobber (match_dup 5))])]
18615   "")
18616
18617 (define_insn "fist<mode>2_ceil"
18618   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18619         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18620          UNSPEC_FIST_CEIL))
18621    (use (match_operand:HI 2 "memory_operand" "m"))
18622    (use (match_operand:HI 3 "memory_operand" "m"))]
18623   "TARGET_USE_FANCY_MATH_387
18624    && flag_unsafe_math_optimizations"
18625   "* return output_fix_trunc (insn, operands, 0);"
18626   [(set_attr "type" "fistp")
18627    (set_attr "i387_cw" "ceil")
18628    (set_attr "mode" "<MODE>")])
18629
18630 (define_insn "fist<mode>2_ceil_with_temp"
18631   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18632         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18633          UNSPEC_FIST_CEIL))
18634    (use (match_operand:HI 2 "memory_operand" "m,m"))
18635    (use (match_operand:HI 3 "memory_operand" "m,m"))
18636    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18637   "TARGET_USE_FANCY_MATH_387
18638    && flag_unsafe_math_optimizations"
18639   "#"
18640   [(set_attr "type" "fistp")
18641    (set_attr "i387_cw" "ceil")
18642    (set_attr "mode" "<MODE>")])
18643
18644 (define_split
18645   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18646         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18647          UNSPEC_FIST_CEIL))
18648    (use (match_operand:HI 2 "memory_operand" ""))
18649    (use (match_operand:HI 3 "memory_operand" ""))
18650    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18651   "reload_completed"
18652   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18653                                   UNSPEC_FIST_CEIL))
18654               (use (match_dup 2))
18655               (use (match_dup 3))])
18656    (set (match_dup 0) (match_dup 4))]
18657   "")
18658
18659 (define_split
18660   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18661         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18662          UNSPEC_FIST_CEIL))
18663    (use (match_operand:HI 2 "memory_operand" ""))
18664    (use (match_operand:HI 3 "memory_operand" ""))
18665    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18666   "reload_completed"
18667   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18668                                   UNSPEC_FIST_CEIL))
18669               (use (match_dup 2))
18670               (use (match_dup 3))])]
18671   "")
18672
18673 (define_expand "lceilxf<mode>2"
18674   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18675                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18676                     UNSPEC_FIST_CEIL))
18677               (clobber (reg:CC FLAGS_REG))])]
18678   "TARGET_USE_FANCY_MATH_387
18679    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18680    && flag_unsafe_math_optimizations"
18681   "")
18682
18683 (define_expand "lceil<mode>di2"
18684   [(match_operand:DI 0 "nonimmediate_operand" "")
18685    (match_operand:MODEF 1 "register_operand" "")]
18686   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18687    && !flag_trapping_math"
18688 {
18689   ix86_expand_lfloorceil (operand0, operand1, false);
18690   DONE;
18691 })
18692
18693 (define_expand "lceil<mode>si2"
18694   [(match_operand:SI 0 "nonimmediate_operand" "")
18695    (match_operand:MODEF 1 "register_operand" "")]
18696   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18697    && !flag_trapping_math"
18698 {
18699   ix86_expand_lfloorceil (operand0, operand1, false);
18700   DONE;
18701 })
18702
18703 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18704 (define_insn_and_split "frndintxf2_trunc"
18705   [(set (match_operand:XF 0 "register_operand" "")
18706         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18707          UNSPEC_FRNDINT_TRUNC))
18708    (clobber (reg:CC FLAGS_REG))]
18709   "TARGET_USE_FANCY_MATH_387
18710    && flag_unsafe_math_optimizations
18711    && !(reload_completed || reload_in_progress)"
18712   "#"
18713   "&& 1"
18714   [(const_int 0)]
18715 {
18716   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18717
18718   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18719   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18720
18721   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18722                                         operands[2], operands[3]));
18723   DONE;
18724 }
18725   [(set_attr "type" "frndint")
18726    (set_attr "i387_cw" "trunc")
18727    (set_attr "mode" "XF")])
18728
18729 (define_insn "frndintxf2_trunc_i387"
18730   [(set (match_operand:XF 0 "register_operand" "=f")
18731         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18732          UNSPEC_FRNDINT_TRUNC))
18733    (use (match_operand:HI 2 "memory_operand" "m"))
18734    (use (match_operand:HI 3 "memory_operand" "m"))]
18735   "TARGET_USE_FANCY_MATH_387
18736    && flag_unsafe_math_optimizations"
18737   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18738   [(set_attr "type" "frndint")
18739    (set_attr "i387_cw" "trunc")
18740    (set_attr "mode" "XF")])
18741
18742 (define_expand "btruncxf2"
18743   [(use (match_operand:XF 0 "register_operand" ""))
18744    (use (match_operand:XF 1 "register_operand" ""))]
18745   "TARGET_USE_FANCY_MATH_387
18746    && flag_unsafe_math_optimizations"
18747 {
18748   if (optimize_insn_for_size_p ())
18749     FAIL;
18750   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18751   DONE;
18752 })
18753
18754 (define_expand "btrunc<mode>2"
18755   [(use (match_operand:MODEF 0 "register_operand" ""))
18756    (use (match_operand:MODEF 1 "register_operand" ""))]
18757   "(TARGET_USE_FANCY_MATH_387
18758     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18759         || TARGET_MIX_SSE_I387)
18760     && flag_unsafe_math_optimizations)
18761    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18762        && !flag_trapping_math)"
18763 {
18764   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18765       && !flag_trapping_math
18766       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18767     {
18768       if (TARGET_ROUND)
18769         emit_insn (gen_sse4_1_round<mode>2
18770                    (operands[0], operands[1], GEN_INT (0x03)));
18771       else if (optimize_insn_for_size_p ())
18772         FAIL;
18773       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18774         ix86_expand_trunc (operand0, operand1);
18775       else
18776         ix86_expand_truncdf_32 (operand0, operand1);
18777     }
18778   else
18779     {
18780       rtx op0, op1;
18781
18782       if (optimize_insn_for_size_p ())
18783         FAIL;
18784
18785       op0 = gen_reg_rtx (XFmode);
18786       op1 = gen_reg_rtx (XFmode);
18787       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18788       emit_insn (gen_frndintxf2_trunc (op0, op1));
18789
18790       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18791     }
18792   DONE;
18793 })
18794
18795 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18796 (define_insn_and_split "frndintxf2_mask_pm"
18797   [(set (match_operand:XF 0 "register_operand" "")
18798         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18799          UNSPEC_FRNDINT_MASK_PM))
18800    (clobber (reg:CC FLAGS_REG))]
18801   "TARGET_USE_FANCY_MATH_387
18802    && flag_unsafe_math_optimizations
18803    && !(reload_completed || reload_in_progress)"
18804   "#"
18805   "&& 1"
18806   [(const_int 0)]
18807 {
18808   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18809
18810   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18811   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18812
18813   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18814                                           operands[2], operands[3]));
18815   DONE;
18816 }
18817   [(set_attr "type" "frndint")
18818    (set_attr "i387_cw" "mask_pm")
18819    (set_attr "mode" "XF")])
18820
18821 (define_insn "frndintxf2_mask_pm_i387"
18822   [(set (match_operand:XF 0 "register_operand" "=f")
18823         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18824          UNSPEC_FRNDINT_MASK_PM))
18825    (use (match_operand:HI 2 "memory_operand" "m"))
18826    (use (match_operand:HI 3 "memory_operand" "m"))]
18827   "TARGET_USE_FANCY_MATH_387
18828    && flag_unsafe_math_optimizations"
18829   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18830   [(set_attr "type" "frndint")
18831    (set_attr "i387_cw" "mask_pm")
18832    (set_attr "mode" "XF")])
18833
18834 (define_expand "nearbyintxf2"
18835   [(use (match_operand:XF 0 "register_operand" ""))
18836    (use (match_operand:XF 1 "register_operand" ""))]
18837   "TARGET_USE_FANCY_MATH_387
18838    && flag_unsafe_math_optimizations"
18839 {
18840   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18841
18842   DONE;
18843 })
18844
18845 (define_expand "nearbyint<mode>2"
18846   [(use (match_operand:MODEF 0 "register_operand" ""))
18847    (use (match_operand:MODEF 1 "register_operand" ""))]
18848   "TARGET_USE_FANCY_MATH_387
18849    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18850        || TARGET_MIX_SSE_I387)
18851    && flag_unsafe_math_optimizations"
18852 {
18853   rtx op0 = gen_reg_rtx (XFmode);
18854   rtx op1 = gen_reg_rtx (XFmode);
18855
18856   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18857   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18858
18859   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18860   DONE;
18861 })
18862
18863 (define_insn "fxam<mode>2_i387"
18864   [(set (match_operand:HI 0 "register_operand" "=a")
18865         (unspec:HI
18866           [(match_operand:X87MODEF 1 "register_operand" "f")]
18867           UNSPEC_FXAM))]
18868   "TARGET_USE_FANCY_MATH_387"
18869   "fxam\n\tfnstsw\t%0"
18870   [(set_attr "type" "multi")
18871    (set_attr "unit" "i387")
18872    (set_attr "mode" "<MODE>")])
18873
18874 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18875   [(set (match_operand:HI 0 "register_operand" "")
18876         (unspec:HI
18877           [(match_operand:MODEF 1 "memory_operand" "")]
18878           UNSPEC_FXAM_MEM))]
18879   "TARGET_USE_FANCY_MATH_387
18880    && !(reload_completed || reload_in_progress)"
18881   "#"
18882   "&& 1"
18883   [(set (match_dup 2)(match_dup 1))
18884    (set (match_dup 0)
18885         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18886 {
18887   operands[2] = gen_reg_rtx (<MODE>mode);
18888
18889   MEM_VOLATILE_P (operands[1]) = 1;
18890 }
18891   [(set_attr "type" "multi")
18892    (set_attr "unit" "i387")
18893    (set_attr "mode" "<MODE>")])
18894
18895 (define_expand "isinfxf2"
18896   [(use (match_operand:SI 0 "register_operand" ""))
18897    (use (match_operand:XF 1 "register_operand" ""))]
18898   "TARGET_USE_FANCY_MATH_387
18899    && TARGET_C99_FUNCTIONS"
18900 {
18901   rtx mask = GEN_INT (0x45);
18902   rtx val = GEN_INT (0x05);
18903
18904   rtx cond;
18905
18906   rtx scratch = gen_reg_rtx (HImode);
18907   rtx res = gen_reg_rtx (QImode);
18908
18909   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18910
18911   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18912   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18913   cond = gen_rtx_fmt_ee (EQ, QImode,
18914                          gen_rtx_REG (CCmode, FLAGS_REG),
18915                          const0_rtx);
18916   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18917   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18918   DONE;
18919 })
18920
18921 (define_expand "isinf<mode>2"
18922   [(use (match_operand:SI 0 "register_operand" ""))
18923    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18924   "TARGET_USE_FANCY_MATH_387
18925    && TARGET_C99_FUNCTIONS
18926    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18927 {
18928   rtx mask = GEN_INT (0x45);
18929   rtx val = GEN_INT (0x05);
18930
18931   rtx cond;
18932
18933   rtx scratch = gen_reg_rtx (HImode);
18934   rtx res = gen_reg_rtx (QImode);
18935
18936   /* Remove excess precision by forcing value through memory. */
18937   if (memory_operand (operands[1], VOIDmode))
18938     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18939   else
18940     {
18941       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18942       rtx temp = assign_386_stack_local (<MODE>mode, slot);
18943
18944       emit_move_insn (temp, operands[1]);
18945       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18946     }
18947
18948   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18949   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18950   cond = gen_rtx_fmt_ee (EQ, QImode,
18951                          gen_rtx_REG (CCmode, FLAGS_REG),
18952                          const0_rtx);
18953   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18954   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18955   DONE;
18956 })
18957
18958 (define_expand "signbit<mode>2"
18959   [(use (match_operand:SI 0 "register_operand" ""))
18960    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18961   "TARGET_USE_FANCY_MATH_387
18962    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18963 {
18964   rtx mask = GEN_INT (0x0200);
18965
18966   rtx scratch = gen_reg_rtx (HImode);
18967
18968   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18969   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18970   DONE;
18971 })
18972 \f
18973 ;; Block operation instructions
18974
18975 (define_insn "cld"
18976   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18977   ""
18978   "cld"
18979   [(set_attr "length" "1")
18980    (set_attr "length_immediate" "0")
18981    (set_attr "modrm" "0")])
18982
18983 (define_expand "movmemsi"
18984   [(use (match_operand:BLK 0 "memory_operand" ""))
18985    (use (match_operand:BLK 1 "memory_operand" ""))
18986    (use (match_operand:SI 2 "nonmemory_operand" ""))
18987    (use (match_operand:SI 3 "const_int_operand" ""))
18988    (use (match_operand:SI 4 "const_int_operand" ""))
18989    (use (match_operand:SI 5 "const_int_operand" ""))]
18990   ""
18991 {
18992  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18993                          operands[4], operands[5]))
18994    DONE;
18995  else
18996    FAIL;
18997 })
18998
18999 (define_expand "movmemdi"
19000   [(use (match_operand:BLK 0 "memory_operand" ""))
19001    (use (match_operand:BLK 1 "memory_operand" ""))
19002    (use (match_operand:DI 2 "nonmemory_operand" ""))
19003    (use (match_operand:DI 3 "const_int_operand" ""))
19004    (use (match_operand:SI 4 "const_int_operand" ""))
19005    (use (match_operand:SI 5 "const_int_operand" ""))]
19006   "TARGET_64BIT"
19007 {
19008  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19009                          operands[4], operands[5]))
19010    DONE;
19011  else
19012    FAIL;
19013 })
19014
19015 ;; Most CPUs don't like single string operations
19016 ;; Handle this case here to simplify previous expander.
19017
19018 (define_expand "strmov"
19019   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19020    (set (match_operand 1 "memory_operand" "") (match_dup 4))
19021    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19022               (clobber (reg:CC FLAGS_REG))])
19023    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19024               (clobber (reg:CC FLAGS_REG))])]
19025   ""
19026 {
19027   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19028
19029   /* If .md ever supports :P for Pmode, these can be directly
19030      in the pattern above.  */
19031   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19032   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19033
19034   /* Can't use this if the user has appropriated esi or edi.  */
19035   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19036       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19037     {
19038       emit_insn (gen_strmov_singleop (operands[0], operands[1],
19039                                       operands[2], operands[3],
19040                                       operands[5], operands[6]));
19041       DONE;
19042     }
19043
19044   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19045 })
19046
19047 (define_expand "strmov_singleop"
19048   [(parallel [(set (match_operand 1 "memory_operand" "")
19049                    (match_operand 3 "memory_operand" ""))
19050               (set (match_operand 0 "register_operand" "")
19051                    (match_operand 4 "" ""))
19052               (set (match_operand 2 "register_operand" "")
19053                    (match_operand 5 "" ""))])]
19054   ""
19055   "ix86_current_function_needs_cld = 1;")
19056
19057 (define_insn "*strmovdi_rex_1"
19058   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19059         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19060    (set (match_operand:DI 0 "register_operand" "=D")
19061         (plus:DI (match_dup 2)
19062                  (const_int 8)))
19063    (set (match_operand:DI 1 "register_operand" "=S")
19064         (plus:DI (match_dup 3)
19065                  (const_int 8)))]
19066   "TARGET_64BIT"
19067   "movsq"
19068   [(set_attr "type" "str")
19069    (set_attr "mode" "DI")
19070    (set_attr "memory" "both")])
19071
19072 (define_insn "*strmovsi_1"
19073   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19074         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19075    (set (match_operand:SI 0 "register_operand" "=D")
19076         (plus:SI (match_dup 2)
19077                  (const_int 4)))
19078    (set (match_operand:SI 1 "register_operand" "=S")
19079         (plus:SI (match_dup 3)
19080                  (const_int 4)))]
19081   "!TARGET_64BIT"
19082   "movs{l|d}"
19083   [(set_attr "type" "str")
19084    (set_attr "mode" "SI")
19085    (set_attr "memory" "both")])
19086
19087 (define_insn "*strmovsi_rex_1"
19088   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19089         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19090    (set (match_operand:DI 0 "register_operand" "=D")
19091         (plus:DI (match_dup 2)
19092                  (const_int 4)))
19093    (set (match_operand:DI 1 "register_operand" "=S")
19094         (plus:DI (match_dup 3)
19095                  (const_int 4)))]
19096   "TARGET_64BIT"
19097   "movs{l|d}"
19098   [(set_attr "type" "str")
19099    (set_attr "mode" "SI")
19100    (set_attr "memory" "both")])
19101
19102 (define_insn "*strmovhi_1"
19103   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19104         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19105    (set (match_operand:SI 0 "register_operand" "=D")
19106         (plus:SI (match_dup 2)
19107                  (const_int 2)))
19108    (set (match_operand:SI 1 "register_operand" "=S")
19109         (plus:SI (match_dup 3)
19110                  (const_int 2)))]
19111   "!TARGET_64BIT"
19112   "movsw"
19113   [(set_attr "type" "str")
19114    (set_attr "memory" "both")
19115    (set_attr "mode" "HI")])
19116
19117 (define_insn "*strmovhi_rex_1"
19118   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19119         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19120    (set (match_operand:DI 0 "register_operand" "=D")
19121         (plus:DI (match_dup 2)
19122                  (const_int 2)))
19123    (set (match_operand:DI 1 "register_operand" "=S")
19124         (plus:DI (match_dup 3)
19125                  (const_int 2)))]
19126   "TARGET_64BIT"
19127   "movsw"
19128   [(set_attr "type" "str")
19129    (set_attr "memory" "both")
19130    (set_attr "mode" "HI")])
19131
19132 (define_insn "*strmovqi_1"
19133   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19134         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19135    (set (match_operand:SI 0 "register_operand" "=D")
19136         (plus:SI (match_dup 2)
19137                  (const_int 1)))
19138    (set (match_operand:SI 1 "register_operand" "=S")
19139         (plus:SI (match_dup 3)
19140                  (const_int 1)))]
19141   "!TARGET_64BIT"
19142   "movsb"
19143   [(set_attr "type" "str")
19144    (set_attr "memory" "both")
19145    (set_attr "mode" "QI")])
19146
19147 (define_insn "*strmovqi_rex_1"
19148   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19149         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19150    (set (match_operand:DI 0 "register_operand" "=D")
19151         (plus:DI (match_dup 2)
19152                  (const_int 1)))
19153    (set (match_operand:DI 1 "register_operand" "=S")
19154         (plus:DI (match_dup 3)
19155                  (const_int 1)))]
19156   "TARGET_64BIT"
19157   "movsb"
19158   [(set_attr "type" "str")
19159    (set_attr "memory" "both")
19160    (set_attr "mode" "QI")])
19161
19162 (define_expand "rep_mov"
19163   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19164               (set (match_operand 0 "register_operand" "")
19165                    (match_operand 5 "" ""))
19166               (set (match_operand 2 "register_operand" "")
19167                    (match_operand 6 "" ""))
19168               (set (match_operand 1 "memory_operand" "")
19169                    (match_operand 3 "memory_operand" ""))
19170               (use (match_dup 4))])]
19171   ""
19172   "ix86_current_function_needs_cld = 1;")
19173
19174 (define_insn "*rep_movdi_rex64"
19175   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19176    (set (match_operand:DI 0 "register_operand" "=D")
19177         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19178                             (const_int 3))
19179                  (match_operand:DI 3 "register_operand" "0")))
19180    (set (match_operand:DI 1 "register_operand" "=S")
19181         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19182                  (match_operand:DI 4 "register_operand" "1")))
19183    (set (mem:BLK (match_dup 3))
19184         (mem:BLK (match_dup 4)))
19185    (use (match_dup 5))]
19186   "TARGET_64BIT"
19187   "rep movsq"
19188   [(set_attr "type" "str")
19189    (set_attr "prefix_rep" "1")
19190    (set_attr "memory" "both")
19191    (set_attr "mode" "DI")])
19192
19193 (define_insn "*rep_movsi"
19194   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19195    (set (match_operand:SI 0 "register_operand" "=D")
19196         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19197                             (const_int 2))
19198                  (match_operand:SI 3 "register_operand" "0")))
19199    (set (match_operand:SI 1 "register_operand" "=S")
19200         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19201                  (match_operand:SI 4 "register_operand" "1")))
19202    (set (mem:BLK (match_dup 3))
19203         (mem:BLK (match_dup 4)))
19204    (use (match_dup 5))]
19205   "!TARGET_64BIT"
19206   "rep movs{l|d}"
19207   [(set_attr "type" "str")
19208    (set_attr "prefix_rep" "1")
19209    (set_attr "memory" "both")
19210    (set_attr "mode" "SI")])
19211
19212 (define_insn "*rep_movsi_rex64"
19213   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19214    (set (match_operand:DI 0 "register_operand" "=D")
19215         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19216                             (const_int 2))
19217                  (match_operand:DI 3 "register_operand" "0")))
19218    (set (match_operand:DI 1 "register_operand" "=S")
19219         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19220                  (match_operand:DI 4 "register_operand" "1")))
19221    (set (mem:BLK (match_dup 3))
19222         (mem:BLK (match_dup 4)))
19223    (use (match_dup 5))]
19224   "TARGET_64BIT"
19225   "rep movs{l|d}"
19226   [(set_attr "type" "str")
19227    (set_attr "prefix_rep" "1")
19228    (set_attr "memory" "both")
19229    (set_attr "mode" "SI")])
19230
19231 (define_insn "*rep_movqi"
19232   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19233    (set (match_operand:SI 0 "register_operand" "=D")
19234         (plus:SI (match_operand:SI 3 "register_operand" "0")
19235                  (match_operand:SI 5 "register_operand" "2")))
19236    (set (match_operand:SI 1 "register_operand" "=S")
19237         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19238    (set (mem:BLK (match_dup 3))
19239         (mem:BLK (match_dup 4)))
19240    (use (match_dup 5))]
19241   "!TARGET_64BIT"
19242   "rep movsb"
19243   [(set_attr "type" "str")
19244    (set_attr "prefix_rep" "1")
19245    (set_attr "memory" "both")
19246    (set_attr "mode" "SI")])
19247
19248 (define_insn "*rep_movqi_rex64"
19249   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19250    (set (match_operand:DI 0 "register_operand" "=D")
19251         (plus:DI (match_operand:DI 3 "register_operand" "0")
19252                  (match_operand:DI 5 "register_operand" "2")))
19253    (set (match_operand:DI 1 "register_operand" "=S")
19254         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19255    (set (mem:BLK (match_dup 3))
19256         (mem:BLK (match_dup 4)))
19257    (use (match_dup 5))]
19258   "TARGET_64BIT"
19259   "rep movsb"
19260   [(set_attr "type" "str")
19261    (set_attr "prefix_rep" "1")
19262    (set_attr "memory" "both")
19263    (set_attr "mode" "SI")])
19264
19265 (define_expand "setmemsi"
19266    [(use (match_operand:BLK 0 "memory_operand" ""))
19267     (use (match_operand:SI 1 "nonmemory_operand" ""))
19268     (use (match_operand 2 "const_int_operand" ""))
19269     (use (match_operand 3 "const_int_operand" ""))
19270     (use (match_operand:SI 4 "const_int_operand" ""))
19271     (use (match_operand:SI 5 "const_int_operand" ""))]
19272   ""
19273 {
19274  if (ix86_expand_setmem (operands[0], operands[1],
19275                          operands[2], operands[3],
19276                          operands[4], operands[5]))
19277    DONE;
19278  else
19279    FAIL;
19280 })
19281
19282 (define_expand "setmemdi"
19283    [(use (match_operand:BLK 0 "memory_operand" ""))
19284     (use (match_operand:DI 1 "nonmemory_operand" ""))
19285     (use (match_operand 2 "const_int_operand" ""))
19286     (use (match_operand 3 "const_int_operand" ""))
19287     (use (match_operand 4 "const_int_operand" ""))
19288     (use (match_operand 5 "const_int_operand" ""))]
19289   "TARGET_64BIT"
19290 {
19291  if (ix86_expand_setmem (operands[0], operands[1],
19292                          operands[2], operands[3],
19293                          operands[4], operands[5]))
19294    DONE;
19295  else
19296    FAIL;
19297 })
19298
19299 ;; Most CPUs don't like single string operations
19300 ;; Handle this case here to simplify previous expander.
19301
19302 (define_expand "strset"
19303   [(set (match_operand 1 "memory_operand" "")
19304         (match_operand 2 "register_operand" ""))
19305    (parallel [(set (match_operand 0 "register_operand" "")
19306                    (match_dup 3))
19307               (clobber (reg:CC FLAGS_REG))])]
19308   ""
19309 {
19310   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19311     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19312
19313   /* If .md ever supports :P for Pmode, this can be directly
19314      in the pattern above.  */
19315   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19316                               GEN_INT (GET_MODE_SIZE (GET_MODE
19317                                                       (operands[2]))));
19318   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19319     {
19320       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19321                                       operands[3]));
19322       DONE;
19323     }
19324 })
19325
19326 (define_expand "strset_singleop"
19327   [(parallel [(set (match_operand 1 "memory_operand" "")
19328                    (match_operand 2 "register_operand" ""))
19329               (set (match_operand 0 "register_operand" "")
19330                    (match_operand 3 "" ""))])]
19331   ""
19332   "ix86_current_function_needs_cld = 1;")
19333
19334 (define_insn "*strsetdi_rex_1"
19335   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19336         (match_operand:DI 2 "register_operand" "a"))
19337    (set (match_operand:DI 0 "register_operand" "=D")
19338         (plus:DI (match_dup 1)
19339                  (const_int 8)))]
19340   "TARGET_64BIT"
19341   "stosq"
19342   [(set_attr "type" "str")
19343    (set_attr "memory" "store")
19344    (set_attr "mode" "DI")])
19345
19346 (define_insn "*strsetsi_1"
19347   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19348         (match_operand:SI 2 "register_operand" "a"))
19349    (set (match_operand:SI 0 "register_operand" "=D")
19350         (plus:SI (match_dup 1)
19351                  (const_int 4)))]
19352   "!TARGET_64BIT"
19353   "stos{l|d}"
19354   [(set_attr "type" "str")
19355    (set_attr "memory" "store")
19356    (set_attr "mode" "SI")])
19357
19358 (define_insn "*strsetsi_rex_1"
19359   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19360         (match_operand:SI 2 "register_operand" "a"))
19361    (set (match_operand:DI 0 "register_operand" "=D")
19362         (plus:DI (match_dup 1)
19363                  (const_int 4)))]
19364   "TARGET_64BIT"
19365   "stos{l|d}"
19366   [(set_attr "type" "str")
19367    (set_attr "memory" "store")
19368    (set_attr "mode" "SI")])
19369
19370 (define_insn "*strsethi_1"
19371   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19372         (match_operand:HI 2 "register_operand" "a"))
19373    (set (match_operand:SI 0 "register_operand" "=D")
19374         (plus:SI (match_dup 1)
19375                  (const_int 2)))]
19376   "!TARGET_64BIT"
19377   "stosw"
19378   [(set_attr "type" "str")
19379    (set_attr "memory" "store")
19380    (set_attr "mode" "HI")])
19381
19382 (define_insn "*strsethi_rex_1"
19383   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19384         (match_operand:HI 2 "register_operand" "a"))
19385    (set (match_operand:DI 0 "register_operand" "=D")
19386         (plus:DI (match_dup 1)
19387                  (const_int 2)))]
19388   "TARGET_64BIT"
19389   "stosw"
19390   [(set_attr "type" "str")
19391    (set_attr "memory" "store")
19392    (set_attr "mode" "HI")])
19393
19394 (define_insn "*strsetqi_1"
19395   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19396         (match_operand:QI 2 "register_operand" "a"))
19397    (set (match_operand:SI 0 "register_operand" "=D")
19398         (plus:SI (match_dup 1)
19399                  (const_int 1)))]
19400   "!TARGET_64BIT"
19401   "stosb"
19402   [(set_attr "type" "str")
19403    (set_attr "memory" "store")
19404    (set_attr "mode" "QI")])
19405
19406 (define_insn "*strsetqi_rex_1"
19407   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19408         (match_operand:QI 2 "register_operand" "a"))
19409    (set (match_operand:DI 0 "register_operand" "=D")
19410         (plus:DI (match_dup 1)
19411                  (const_int 1)))]
19412   "TARGET_64BIT"
19413   "stosb"
19414   [(set_attr "type" "str")
19415    (set_attr "memory" "store")
19416    (set_attr "mode" "QI")])
19417
19418 (define_expand "rep_stos"
19419   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19420               (set (match_operand 0 "register_operand" "")
19421                    (match_operand 4 "" ""))
19422               (set (match_operand 2 "memory_operand" "") (const_int 0))
19423               (use (match_operand 3 "register_operand" ""))
19424               (use (match_dup 1))])]
19425   ""
19426   "ix86_current_function_needs_cld = 1;")
19427
19428 (define_insn "*rep_stosdi_rex64"
19429   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19430    (set (match_operand:DI 0 "register_operand" "=D")
19431         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19432                             (const_int 3))
19433                  (match_operand:DI 3 "register_operand" "0")))
19434    (set (mem:BLK (match_dup 3))
19435         (const_int 0))
19436    (use (match_operand:DI 2 "register_operand" "a"))
19437    (use (match_dup 4))]
19438   "TARGET_64BIT"
19439   "rep stosq"
19440   [(set_attr "type" "str")
19441    (set_attr "prefix_rep" "1")
19442    (set_attr "memory" "store")
19443    (set_attr "mode" "DI")])
19444
19445 (define_insn "*rep_stossi"
19446   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19447    (set (match_operand:SI 0 "register_operand" "=D")
19448         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19449                             (const_int 2))
19450                  (match_operand:SI 3 "register_operand" "0")))
19451    (set (mem:BLK (match_dup 3))
19452         (const_int 0))
19453    (use (match_operand:SI 2 "register_operand" "a"))
19454    (use (match_dup 4))]
19455   "!TARGET_64BIT"
19456   "rep stos{l|d}"
19457   [(set_attr "type" "str")
19458    (set_attr "prefix_rep" "1")
19459    (set_attr "memory" "store")
19460    (set_attr "mode" "SI")])
19461
19462 (define_insn "*rep_stossi_rex64"
19463   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19464    (set (match_operand:DI 0 "register_operand" "=D")
19465         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19466                             (const_int 2))
19467                  (match_operand:DI 3 "register_operand" "0")))
19468    (set (mem:BLK (match_dup 3))
19469         (const_int 0))
19470    (use (match_operand:SI 2 "register_operand" "a"))
19471    (use (match_dup 4))]
19472   "TARGET_64BIT"
19473   "rep stos{l|d}"
19474   [(set_attr "type" "str")
19475    (set_attr "prefix_rep" "1")
19476    (set_attr "memory" "store")
19477    (set_attr "mode" "SI")])
19478
19479 (define_insn "*rep_stosqi"
19480   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19481    (set (match_operand:SI 0 "register_operand" "=D")
19482         (plus:SI (match_operand:SI 3 "register_operand" "0")
19483                  (match_operand:SI 4 "register_operand" "1")))
19484    (set (mem:BLK (match_dup 3))
19485         (const_int 0))
19486    (use (match_operand:QI 2 "register_operand" "a"))
19487    (use (match_dup 4))]
19488   "!TARGET_64BIT"
19489   "rep stosb"
19490   [(set_attr "type" "str")
19491    (set_attr "prefix_rep" "1")
19492    (set_attr "memory" "store")
19493    (set_attr "mode" "QI")])
19494
19495 (define_insn "*rep_stosqi_rex64"
19496   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19497    (set (match_operand:DI 0 "register_operand" "=D")
19498         (plus:DI (match_operand:DI 3 "register_operand" "0")
19499                  (match_operand:DI 4 "register_operand" "1")))
19500    (set (mem:BLK (match_dup 3))
19501         (const_int 0))
19502    (use (match_operand:QI 2 "register_operand" "a"))
19503    (use (match_dup 4))]
19504   "TARGET_64BIT"
19505   "rep stosb"
19506   [(set_attr "type" "str")
19507    (set_attr "prefix_rep" "1")
19508    (set_attr "memory" "store")
19509    (set_attr "mode" "QI")])
19510
19511 (define_expand "cmpstrnsi"
19512   [(set (match_operand:SI 0 "register_operand" "")
19513         (compare:SI (match_operand:BLK 1 "general_operand" "")
19514                     (match_operand:BLK 2 "general_operand" "")))
19515    (use (match_operand 3 "general_operand" ""))
19516    (use (match_operand 4 "immediate_operand" ""))]
19517   ""
19518 {
19519   rtx addr1, addr2, out, outlow, count, countreg, align;
19520
19521   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19522     FAIL;
19523
19524   /* Can't use this if the user has appropriated esi or edi.  */
19525   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19526     FAIL;
19527
19528   out = operands[0];
19529   if (!REG_P (out))
19530     out = gen_reg_rtx (SImode);
19531
19532   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19533   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19534   if (addr1 != XEXP (operands[1], 0))
19535     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19536   if (addr2 != XEXP (operands[2], 0))
19537     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19538
19539   count = operands[3];
19540   countreg = ix86_zero_extend_to_Pmode (count);
19541
19542   /* %%% Iff we are testing strict equality, we can use known alignment
19543      to good advantage.  This may be possible with combine, particularly
19544      once cc0 is dead.  */
19545   align = operands[4];
19546
19547   if (CONST_INT_P (count))
19548     {
19549       if (INTVAL (count) == 0)
19550         {
19551           emit_move_insn (operands[0], const0_rtx);
19552           DONE;
19553         }
19554       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19555                                      operands[1], operands[2]));
19556     }
19557   else
19558     {
19559       if (TARGET_64BIT)
19560         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19561       else
19562         emit_insn (gen_cmpsi_1 (countreg, countreg));
19563       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19564                                   operands[1], operands[2]));
19565     }
19566
19567   outlow = gen_lowpart (QImode, out);
19568   emit_insn (gen_cmpintqi (outlow));
19569   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19570
19571   if (operands[0] != out)
19572     emit_move_insn (operands[0], out);
19573
19574   DONE;
19575 })
19576
19577 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19578
19579 (define_expand "cmpintqi"
19580   [(set (match_dup 1)
19581         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19582    (set (match_dup 2)
19583         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19584    (parallel [(set (match_operand:QI 0 "register_operand" "")
19585                    (minus:QI (match_dup 1)
19586                              (match_dup 2)))
19587               (clobber (reg:CC FLAGS_REG))])]
19588   ""
19589   "operands[1] = gen_reg_rtx (QImode);
19590    operands[2] = gen_reg_rtx (QImode);")
19591
19592 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19593 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19594
19595 (define_expand "cmpstrnqi_nz_1"
19596   [(parallel [(set (reg:CC FLAGS_REG)
19597                    (compare:CC (match_operand 4 "memory_operand" "")
19598                                (match_operand 5 "memory_operand" "")))
19599               (use (match_operand 2 "register_operand" ""))
19600               (use (match_operand:SI 3 "immediate_operand" ""))
19601               (clobber (match_operand 0 "register_operand" ""))
19602               (clobber (match_operand 1 "register_operand" ""))
19603               (clobber (match_dup 2))])]
19604   ""
19605   "ix86_current_function_needs_cld = 1;")
19606
19607 (define_insn "*cmpstrnqi_nz_1"
19608   [(set (reg:CC FLAGS_REG)
19609         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19610                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19611    (use (match_operand:SI 6 "register_operand" "2"))
19612    (use (match_operand:SI 3 "immediate_operand" "i"))
19613    (clobber (match_operand:SI 0 "register_operand" "=S"))
19614    (clobber (match_operand:SI 1 "register_operand" "=D"))
19615    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19616   "!TARGET_64BIT"
19617   "repz cmpsb"
19618   [(set_attr "type" "str")
19619    (set_attr "mode" "QI")
19620    (set_attr "prefix_rep" "1")])
19621
19622 (define_insn "*cmpstrnqi_nz_rex_1"
19623   [(set (reg:CC FLAGS_REG)
19624         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19625                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19626    (use (match_operand:DI 6 "register_operand" "2"))
19627    (use (match_operand:SI 3 "immediate_operand" "i"))
19628    (clobber (match_operand:DI 0 "register_operand" "=S"))
19629    (clobber (match_operand:DI 1 "register_operand" "=D"))
19630    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19631   "TARGET_64BIT"
19632   "repz cmpsb"
19633   [(set_attr "type" "str")
19634    (set_attr "mode" "QI")
19635    (set_attr "prefix_rep" "1")])
19636
19637 ;; The same, but the count is not known to not be zero.
19638
19639 (define_expand "cmpstrnqi_1"
19640   [(parallel [(set (reg:CC FLAGS_REG)
19641                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19642                                      (const_int 0))
19643                   (compare:CC (match_operand 4 "memory_operand" "")
19644                               (match_operand 5 "memory_operand" ""))
19645                   (const_int 0)))
19646               (use (match_operand:SI 3 "immediate_operand" ""))
19647               (use (reg:CC FLAGS_REG))
19648               (clobber (match_operand 0 "register_operand" ""))
19649               (clobber (match_operand 1 "register_operand" ""))
19650               (clobber (match_dup 2))])]
19651   ""
19652   "ix86_current_function_needs_cld = 1;")
19653
19654 (define_insn "*cmpstrnqi_1"
19655   [(set (reg:CC FLAGS_REG)
19656         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19657                              (const_int 0))
19658           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19659                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19660           (const_int 0)))
19661    (use (match_operand:SI 3 "immediate_operand" "i"))
19662    (use (reg:CC FLAGS_REG))
19663    (clobber (match_operand:SI 0 "register_operand" "=S"))
19664    (clobber (match_operand:SI 1 "register_operand" "=D"))
19665    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19666   "!TARGET_64BIT"
19667   "repz cmpsb"
19668   [(set_attr "type" "str")
19669    (set_attr "mode" "QI")
19670    (set_attr "prefix_rep" "1")])
19671
19672 (define_insn "*cmpstrnqi_rex_1"
19673   [(set (reg:CC FLAGS_REG)
19674         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19675                              (const_int 0))
19676           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19677                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19678           (const_int 0)))
19679    (use (match_operand:SI 3 "immediate_operand" "i"))
19680    (use (reg:CC FLAGS_REG))
19681    (clobber (match_operand:DI 0 "register_operand" "=S"))
19682    (clobber (match_operand:DI 1 "register_operand" "=D"))
19683    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19684   "TARGET_64BIT"
19685   "repz cmpsb"
19686   [(set_attr "type" "str")
19687    (set_attr "mode" "QI")
19688    (set_attr "prefix_rep" "1")])
19689
19690 (define_expand "strlensi"
19691   [(set (match_operand:SI 0 "register_operand" "")
19692         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19693                     (match_operand:QI 2 "immediate_operand" "")
19694                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19695   ""
19696 {
19697  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19698    DONE;
19699  else
19700    FAIL;
19701 })
19702
19703 (define_expand "strlendi"
19704   [(set (match_operand:DI 0 "register_operand" "")
19705         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19706                     (match_operand:QI 2 "immediate_operand" "")
19707                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19708   ""
19709 {
19710  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19711    DONE;
19712  else
19713    FAIL;
19714 })
19715
19716 (define_expand "strlenqi_1"
19717   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19718               (clobber (match_operand 1 "register_operand" ""))
19719               (clobber (reg:CC FLAGS_REG))])]
19720   ""
19721   "ix86_current_function_needs_cld = 1;")
19722
19723 (define_insn "*strlenqi_1"
19724   [(set (match_operand:SI 0 "register_operand" "=&c")
19725         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19726                     (match_operand:QI 2 "register_operand" "a")
19727                     (match_operand:SI 3 "immediate_operand" "i")
19728                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19729    (clobber (match_operand:SI 1 "register_operand" "=D"))
19730    (clobber (reg:CC FLAGS_REG))]
19731   "!TARGET_64BIT"
19732   "repnz scasb"
19733   [(set_attr "type" "str")
19734    (set_attr "mode" "QI")
19735    (set_attr "prefix_rep" "1")])
19736
19737 (define_insn "*strlenqi_rex_1"
19738   [(set (match_operand:DI 0 "register_operand" "=&c")
19739         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19740                     (match_operand:QI 2 "register_operand" "a")
19741                     (match_operand:DI 3 "immediate_operand" "i")
19742                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19743    (clobber (match_operand:DI 1 "register_operand" "=D"))
19744    (clobber (reg:CC FLAGS_REG))]
19745   "TARGET_64BIT"
19746   "repnz scasb"
19747   [(set_attr "type" "str")
19748    (set_attr "mode" "QI")
19749    (set_attr "prefix_rep" "1")])
19750
19751 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19752 ;; handled in combine, but it is not currently up to the task.
19753 ;; When used for their truth value, the cmpstrn* expanders generate
19754 ;; code like this:
19755 ;;
19756 ;;   repz cmpsb
19757 ;;   seta       %al
19758 ;;   setb       %dl
19759 ;;   cmpb       %al, %dl
19760 ;;   jcc        label
19761 ;;
19762 ;; The intermediate three instructions are unnecessary.
19763
19764 ;; This one handles cmpstrn*_nz_1...
19765 (define_peephole2
19766   [(parallel[
19767      (set (reg:CC FLAGS_REG)
19768           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19769                       (mem:BLK (match_operand 5 "register_operand" ""))))
19770      (use (match_operand 6 "register_operand" ""))
19771      (use (match_operand:SI 3 "immediate_operand" ""))
19772      (clobber (match_operand 0 "register_operand" ""))
19773      (clobber (match_operand 1 "register_operand" ""))
19774      (clobber (match_operand 2 "register_operand" ""))])
19775    (set (match_operand:QI 7 "register_operand" "")
19776         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19777    (set (match_operand:QI 8 "register_operand" "")
19778         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19779    (set (reg FLAGS_REG)
19780         (compare (match_dup 7) (match_dup 8)))
19781   ]
19782   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19783   [(parallel[
19784      (set (reg:CC FLAGS_REG)
19785           (compare:CC (mem:BLK (match_dup 4))
19786                       (mem:BLK (match_dup 5))))
19787      (use (match_dup 6))
19788      (use (match_dup 3))
19789      (clobber (match_dup 0))
19790      (clobber (match_dup 1))
19791      (clobber (match_dup 2))])]
19792   "")
19793
19794 ;; ...and this one handles cmpstrn*_1.
19795 (define_peephole2
19796   [(parallel[
19797      (set (reg:CC FLAGS_REG)
19798           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19799                                (const_int 0))
19800             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19801                         (mem:BLK (match_operand 5 "register_operand" "")))
19802             (const_int 0)))
19803      (use (match_operand:SI 3 "immediate_operand" ""))
19804      (use (reg:CC FLAGS_REG))
19805      (clobber (match_operand 0 "register_operand" ""))
19806      (clobber (match_operand 1 "register_operand" ""))
19807      (clobber (match_operand 2 "register_operand" ""))])
19808    (set (match_operand:QI 7 "register_operand" "")
19809         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19810    (set (match_operand:QI 8 "register_operand" "")
19811         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19812    (set (reg FLAGS_REG)
19813         (compare (match_dup 7) (match_dup 8)))
19814   ]
19815   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19816   [(parallel[
19817      (set (reg:CC FLAGS_REG)
19818           (if_then_else:CC (ne (match_dup 6)
19819                                (const_int 0))
19820             (compare:CC (mem:BLK (match_dup 4))
19821                         (mem:BLK (match_dup 5)))
19822             (const_int 0)))
19823      (use (match_dup 3))
19824      (use (reg:CC FLAGS_REG))
19825      (clobber (match_dup 0))
19826      (clobber (match_dup 1))
19827      (clobber (match_dup 2))])]
19828   "")
19829
19830
19831 \f
19832 ;; Conditional move instructions.
19833
19834 (define_expand "movdicc"
19835   [(set (match_operand:DI 0 "register_operand" "")
19836         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19837                          (match_operand:DI 2 "general_operand" "")
19838                          (match_operand:DI 3 "general_operand" "")))]
19839   "TARGET_64BIT"
19840   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19841
19842 (define_insn "x86_movdicc_0_m1_rex64"
19843   [(set (match_operand:DI 0 "register_operand" "=r")
19844         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19845           (const_int -1)
19846           (const_int 0)))
19847    (clobber (reg:CC FLAGS_REG))]
19848   "TARGET_64BIT"
19849   "sbb{q}\t%0, %0"
19850   ; Since we don't have the proper number of operands for an alu insn,
19851   ; fill in all the blanks.
19852   [(set_attr "type" "alu")
19853    (set_attr "pent_pair" "pu")
19854    (set_attr "memory" "none")
19855    (set_attr "imm_disp" "false")
19856    (set_attr "mode" "DI")
19857    (set_attr "length_immediate" "0")])
19858
19859 (define_insn "*x86_movdicc_0_m1_se"
19860   [(set (match_operand:DI 0 "register_operand" "=r")
19861         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19862                          (const_int 1)
19863                          (const_int 0)))
19864    (clobber (reg:CC FLAGS_REG))]
19865   ""
19866   "sbb{q}\t%0, %0"
19867   [(set_attr "type" "alu")
19868    (set_attr "pent_pair" "pu")
19869    (set_attr "memory" "none")
19870    (set_attr "imm_disp" "false")
19871    (set_attr "mode" "DI")
19872    (set_attr "length_immediate" "0")])
19873
19874 (define_insn "*movdicc_c_rex64"
19875   [(set (match_operand:DI 0 "register_operand" "=r,r")
19876         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19877                                 [(reg FLAGS_REG) (const_int 0)])
19878                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19879                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19880   "TARGET_64BIT && TARGET_CMOVE
19881    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19882   "@
19883    cmov%O2%C1\t{%2, %0|%0, %2}
19884    cmov%O2%c1\t{%3, %0|%0, %3}"
19885   [(set_attr "type" "icmov")
19886    (set_attr "mode" "DI")])
19887
19888 (define_expand "movsicc"
19889   [(set (match_operand:SI 0 "register_operand" "")
19890         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19891                          (match_operand:SI 2 "general_operand" "")
19892                          (match_operand:SI 3 "general_operand" "")))]
19893   ""
19894   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19895
19896 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19897 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19898 ;; So just document what we're doing explicitly.
19899
19900 (define_insn "x86_movsicc_0_m1"
19901   [(set (match_operand:SI 0 "register_operand" "=r")
19902         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19903           (const_int -1)
19904           (const_int 0)))
19905    (clobber (reg:CC FLAGS_REG))]
19906   ""
19907   "sbb{l}\t%0, %0"
19908   ; Since we don't have the proper number of operands for an alu insn,
19909   ; fill in all the blanks.
19910   [(set_attr "type" "alu")
19911    (set_attr "pent_pair" "pu")
19912    (set_attr "memory" "none")
19913    (set_attr "imm_disp" "false")
19914    (set_attr "mode" "SI")
19915    (set_attr "length_immediate" "0")])
19916
19917 (define_insn "*x86_movsicc_0_m1_se"
19918   [(set (match_operand:SI 0 "register_operand" "=r")
19919         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19920                          (const_int 1)
19921                          (const_int 0)))
19922    (clobber (reg:CC FLAGS_REG))]
19923   ""
19924   "sbb{l}\t%0, %0"
19925   [(set_attr "type" "alu")
19926    (set_attr "pent_pair" "pu")
19927    (set_attr "memory" "none")
19928    (set_attr "imm_disp" "false")
19929    (set_attr "mode" "SI")
19930    (set_attr "length_immediate" "0")])
19931
19932 (define_insn "*movsicc_noc"
19933   [(set (match_operand:SI 0 "register_operand" "=r,r")
19934         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19935                                 [(reg FLAGS_REG) (const_int 0)])
19936                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19937                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19938   "TARGET_CMOVE
19939    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19940   "@
19941    cmov%O2%C1\t{%2, %0|%0, %2}
19942    cmov%O2%c1\t{%3, %0|%0, %3}"
19943   [(set_attr "type" "icmov")
19944    (set_attr "mode" "SI")])
19945
19946 (define_expand "movhicc"
19947   [(set (match_operand:HI 0 "register_operand" "")
19948         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19949                          (match_operand:HI 2 "general_operand" "")
19950                          (match_operand:HI 3 "general_operand" "")))]
19951   "TARGET_HIMODE_MATH"
19952   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19953
19954 (define_insn "*movhicc_noc"
19955   [(set (match_operand:HI 0 "register_operand" "=r,r")
19956         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19957                                 [(reg FLAGS_REG) (const_int 0)])
19958                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19959                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19960   "TARGET_CMOVE
19961    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19962   "@
19963    cmov%O2%C1\t{%2, %0|%0, %2}
19964    cmov%O2%c1\t{%3, %0|%0, %3}"
19965   [(set_attr "type" "icmov")
19966    (set_attr "mode" "HI")])
19967
19968 (define_expand "movqicc"
19969   [(set (match_operand:QI 0 "register_operand" "")
19970         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19971                          (match_operand:QI 2 "general_operand" "")
19972                          (match_operand:QI 3 "general_operand" "")))]
19973   "TARGET_QIMODE_MATH"
19974   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19975
19976 (define_insn_and_split "*movqicc_noc"
19977   [(set (match_operand:QI 0 "register_operand" "=r,r")
19978         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19979                                 [(match_operand 4 "flags_reg_operand" "")
19980                                  (const_int 0)])
19981                       (match_operand:QI 2 "register_operand" "r,0")
19982                       (match_operand:QI 3 "register_operand" "0,r")))]
19983   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19984   "#"
19985   "&& reload_completed"
19986   [(set (match_dup 0)
19987         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19988                       (match_dup 2)
19989                       (match_dup 3)))]
19990   "operands[0] = gen_lowpart (SImode, operands[0]);
19991    operands[2] = gen_lowpart (SImode, operands[2]);
19992    operands[3] = gen_lowpart (SImode, operands[3]);"
19993   [(set_attr "type" "icmov")
19994    (set_attr "mode" "SI")])
19995
19996 (define_expand "mov<mode>cc"
19997   [(set (match_operand:X87MODEF 0 "register_operand" "")
19998         (if_then_else:X87MODEF
19999           (match_operand 1 "comparison_operator" "")
20000           (match_operand:X87MODEF 2 "register_operand" "")
20001           (match_operand:X87MODEF 3 "register_operand" "")))]
20002   "(TARGET_80387 && TARGET_CMOVE)
20003    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20004   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20005
20006 (define_insn "*movsfcc_1_387"
20007   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20008         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20009                                 [(reg FLAGS_REG) (const_int 0)])
20010                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20011                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20012   "TARGET_80387 && TARGET_CMOVE
20013    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20014   "@
20015    fcmov%F1\t{%2, %0|%0, %2}
20016    fcmov%f1\t{%3, %0|%0, %3}
20017    cmov%O2%C1\t{%2, %0|%0, %2}
20018    cmov%O2%c1\t{%3, %0|%0, %3}"
20019   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20020    (set_attr "mode" "SF,SF,SI,SI")])
20021
20022 (define_insn "*movdfcc_1"
20023   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20024         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20025                                 [(reg FLAGS_REG) (const_int 0)])
20026                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20027                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20028   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20029    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20030   "@
20031    fcmov%F1\t{%2, %0|%0, %2}
20032    fcmov%f1\t{%3, %0|%0, %3}
20033    #
20034    #"
20035   [(set_attr "type" "fcmov,fcmov,multi,multi")
20036    (set_attr "mode" "DF")])
20037
20038 (define_insn "*movdfcc_1_rex64"
20039   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20040         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20041                                 [(reg FLAGS_REG) (const_int 0)])
20042                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20043                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20044   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20045    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20046   "@
20047    fcmov%F1\t{%2, %0|%0, %2}
20048    fcmov%f1\t{%3, %0|%0, %3}
20049    cmov%O2%C1\t{%2, %0|%0, %2}
20050    cmov%O2%c1\t{%3, %0|%0, %3}"
20051   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20052    (set_attr "mode" "DF")])
20053
20054 (define_split
20055   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20056         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20057                                 [(match_operand 4 "flags_reg_operand" "")
20058                                  (const_int 0)])
20059                       (match_operand:DF 2 "nonimmediate_operand" "")
20060                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20061   "!TARGET_64BIT && reload_completed"
20062   [(set (match_dup 2)
20063         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20064                       (match_dup 5)
20065                       (match_dup 6)))
20066    (set (match_dup 3)
20067         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20068                       (match_dup 7)
20069                       (match_dup 8)))]
20070   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20071    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20072
20073 (define_insn "*movxfcc_1"
20074   [(set (match_operand:XF 0 "register_operand" "=f,f")
20075         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20076                                 [(reg FLAGS_REG) (const_int 0)])
20077                       (match_operand:XF 2 "register_operand" "f,0")
20078                       (match_operand:XF 3 "register_operand" "0,f")))]
20079   "TARGET_80387 && TARGET_CMOVE"
20080   "@
20081    fcmov%F1\t{%2, %0|%0, %2}
20082    fcmov%f1\t{%3, %0|%0, %3}"
20083   [(set_attr "type" "fcmov")
20084    (set_attr "mode" "XF")])
20085
20086 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20087 ;; the scalar versions to have only XMM registers as operands.
20088
20089 ;; SSE5 conditional move
20090 (define_insn "*sse5_pcmov_<mode>"
20091   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20092         (if_then_else:MODEF
20093           (match_operand:MODEF 1 "register_operand" "x,0")
20094           (match_operand:MODEF 2 "register_operand" "0,x")
20095           (match_operand:MODEF 3 "register_operand" "x,x")))]
20096   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20097   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20098   [(set_attr "type" "sse4arg")])
20099
20100 ;; These versions of the min/max patterns are intentionally ignorant of
20101 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20102 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20103 ;; are undefined in this condition, we're certain this is correct.
20104
20105 (define_insn "*avx_<code><mode>3"
20106   [(set (match_operand:MODEF 0 "register_operand" "=x")
20107         (smaxmin:MODEF
20108           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20109           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20110   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20111   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20112   [(set_attr "type" "sseadd")
20113    (set_attr "prefix" "vex")
20114    (set_attr "mode" "<MODE>")])
20115
20116 (define_insn "<code><mode>3"
20117   [(set (match_operand:MODEF 0 "register_operand" "=x")
20118         (smaxmin:MODEF
20119           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20120           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20121   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20122   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20123   [(set_attr "type" "sseadd")
20124    (set_attr "mode" "<MODE>")])
20125
20126 ;; These versions of the min/max patterns implement exactly the operations
20127 ;;   min = (op1 < op2 ? op1 : op2)
20128 ;;   max = (!(op1 < op2) ? op1 : op2)
20129 ;; Their operands are not commutative, and thus they may be used in the
20130 ;; presence of -0.0 and NaN.
20131
20132 (define_insn "*avx_ieee_smin<mode>3"
20133   [(set (match_operand:MODEF 0 "register_operand" "=x")
20134         (unspec:MODEF
20135           [(match_operand:MODEF 1 "register_operand" "x")
20136            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20137          UNSPEC_IEEE_MIN))]
20138   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20139   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20140   [(set_attr "type" "sseadd")
20141    (set_attr "prefix" "vex")
20142    (set_attr "mode" "<MODE>")])
20143
20144 (define_insn "*ieee_smin<mode>3"
20145   [(set (match_operand:MODEF 0 "register_operand" "=x")
20146         (unspec:MODEF
20147           [(match_operand:MODEF 1 "register_operand" "0")
20148            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20149          UNSPEC_IEEE_MIN))]
20150   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20151   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20152   [(set_attr "type" "sseadd")
20153    (set_attr "mode" "<MODE>")])
20154
20155 (define_insn "*avx_ieee_smax<mode>3"
20156   [(set (match_operand:MODEF 0 "register_operand" "=x")
20157         (unspec:MODEF
20158           [(match_operand:MODEF 1 "register_operand" "0")
20159            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20160          UNSPEC_IEEE_MAX))]
20161   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20162   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20163   [(set_attr "type" "sseadd")
20164    (set_attr "prefix" "vex")
20165    (set_attr "mode" "<MODE>")])
20166
20167 (define_insn "*ieee_smax<mode>3"
20168   [(set (match_operand:MODEF 0 "register_operand" "=x")
20169         (unspec:MODEF
20170           [(match_operand:MODEF 1 "register_operand" "0")
20171            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20172          UNSPEC_IEEE_MAX))]
20173   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20174   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20175   [(set_attr "type" "sseadd")
20176    (set_attr "mode" "<MODE>")])
20177
20178 ;; Make two stack loads independent:
20179 ;;   fld aa              fld aa
20180 ;;   fld %st(0)     ->   fld bb
20181 ;;   fmul bb             fmul %st(1), %st
20182 ;;
20183 ;; Actually we only match the last two instructions for simplicity.
20184 (define_peephole2
20185   [(set (match_operand 0 "fp_register_operand" "")
20186         (match_operand 1 "fp_register_operand" ""))
20187    (set (match_dup 0)
20188         (match_operator 2 "binary_fp_operator"
20189            [(match_dup 0)
20190             (match_operand 3 "memory_operand" "")]))]
20191   "REGNO (operands[0]) != REGNO (operands[1])"
20192   [(set (match_dup 0) (match_dup 3))
20193    (set (match_dup 0) (match_dup 4))]
20194
20195   ;; The % modifier is not operational anymore in peephole2's, so we have to
20196   ;; swap the operands manually in the case of addition and multiplication.
20197   "if (COMMUTATIVE_ARITH_P (operands[2]))
20198      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20199                                  operands[0], operands[1]);
20200    else
20201      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20202                                  operands[1], operands[0]);")
20203
20204 ;; Conditional addition patterns
20205 (define_expand "add<mode>cc"
20206   [(match_operand:SWI 0 "register_operand" "")
20207    (match_operand 1 "comparison_operator" "")
20208    (match_operand:SWI 2 "register_operand" "")
20209    (match_operand:SWI 3 "const_int_operand" "")]
20210   ""
20211   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20212
20213 \f
20214 ;; Misc patterns (?)
20215
20216 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20217 ;; Otherwise there will be nothing to keep
20218 ;;
20219 ;; [(set (reg ebp) (reg esp))]
20220 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20221 ;;  (clobber (eflags)]
20222 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20223 ;;
20224 ;; in proper program order.
20225 (define_insn "pro_epilogue_adjust_stack_1"
20226   [(set (match_operand:SI 0 "register_operand" "=r,r")
20227         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20228                  (match_operand:SI 2 "immediate_operand" "i,i")))
20229    (clobber (reg:CC FLAGS_REG))
20230    (clobber (mem:BLK (scratch)))]
20231   "!TARGET_64BIT"
20232 {
20233   switch (get_attr_type (insn))
20234     {
20235     case TYPE_IMOV:
20236       return "mov{l}\t{%1, %0|%0, %1}";
20237
20238     case TYPE_ALU:
20239       if (CONST_INT_P (operands[2])
20240           && (INTVAL (operands[2]) == 128
20241               || (INTVAL (operands[2]) < 0
20242                   && INTVAL (operands[2]) != -128)))
20243         {
20244           operands[2] = GEN_INT (-INTVAL (operands[2]));
20245           return "sub{l}\t{%2, %0|%0, %2}";
20246         }
20247       return "add{l}\t{%2, %0|%0, %2}";
20248
20249     case TYPE_LEA:
20250       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20251       return "lea{l}\t{%a2, %0|%0, %a2}";
20252
20253     default:
20254       gcc_unreachable ();
20255     }
20256 }
20257   [(set (attr "type")
20258         (cond [(eq_attr "alternative" "0")
20259                  (const_string "alu")
20260                (match_operand:SI 2 "const0_operand" "")
20261                  (const_string "imov")
20262               ]
20263               (const_string "lea")))
20264    (set_attr "mode" "SI")])
20265
20266 (define_insn "pro_epilogue_adjust_stack_rex64"
20267   [(set (match_operand:DI 0 "register_operand" "=r,r")
20268         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20269                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20270    (clobber (reg:CC FLAGS_REG))
20271    (clobber (mem:BLK (scratch)))]
20272   "TARGET_64BIT"
20273 {
20274   switch (get_attr_type (insn))
20275     {
20276     case TYPE_IMOV:
20277       return "mov{q}\t{%1, %0|%0, %1}";
20278
20279     case TYPE_ALU:
20280       if (CONST_INT_P (operands[2])
20281           /* Avoid overflows.  */
20282           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20283           && (INTVAL (operands[2]) == 128
20284               || (INTVAL (operands[2]) < 0
20285                   && INTVAL (operands[2]) != -128)))
20286         {
20287           operands[2] = GEN_INT (-INTVAL (operands[2]));
20288           return "sub{q}\t{%2, %0|%0, %2}";
20289         }
20290       return "add{q}\t{%2, %0|%0, %2}";
20291
20292     case TYPE_LEA:
20293       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20294       return "lea{q}\t{%a2, %0|%0, %a2}";
20295
20296     default:
20297       gcc_unreachable ();
20298     }
20299 }
20300   [(set (attr "type")
20301         (cond [(eq_attr "alternative" "0")
20302                  (const_string "alu")
20303                (match_operand:DI 2 "const0_operand" "")
20304                  (const_string "imov")
20305               ]
20306               (const_string "lea")))
20307    (set_attr "mode" "DI")])
20308
20309 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20310   [(set (match_operand:DI 0 "register_operand" "=r,r")
20311         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20312                  (match_operand:DI 3 "immediate_operand" "i,i")))
20313    (use (match_operand:DI 2 "register_operand" "r,r"))
20314    (clobber (reg:CC FLAGS_REG))
20315    (clobber (mem:BLK (scratch)))]
20316   "TARGET_64BIT"
20317 {
20318   switch (get_attr_type (insn))
20319     {
20320     case TYPE_ALU:
20321       return "add{q}\t{%2, %0|%0, %2}";
20322
20323     case TYPE_LEA:
20324       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20325       return "lea{q}\t{%a2, %0|%0, %a2}";
20326
20327     default:
20328       gcc_unreachable ();
20329     }
20330 }
20331   [(set_attr "type" "alu,lea")
20332    (set_attr "mode" "DI")])
20333
20334 (define_insn "allocate_stack_worker_32"
20335   [(set (match_operand:SI 0 "register_operand" "=a")
20336         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20337                             UNSPECV_STACK_PROBE))
20338    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
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_insn "allocate_stack_worker_64"
20346   [(set (match_operand:DI 0 "register_operand" "=a")
20347         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20348                             UNSPECV_STACK_PROBE))
20349    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20350    (clobber (reg:DI R10_REG))
20351    (clobber (reg:DI R11_REG))
20352    (clobber (reg:CC FLAGS_REG))]
20353   "TARGET_64BIT && TARGET_STACK_PROBE"
20354   "call\t___chkstk"
20355   [(set_attr "type" "multi")
20356    (set_attr "length" "5")])
20357
20358 (define_expand "allocate_stack"
20359   [(match_operand 0 "register_operand" "")
20360    (match_operand 1 "general_operand" "")]
20361   "TARGET_STACK_PROBE"
20362 {
20363   rtx x;
20364
20365 #ifndef CHECK_STACK_LIMIT
20366 #define CHECK_STACK_LIMIT 0
20367 #endif
20368
20369   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20370       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20371     {
20372       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20373                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20374       if (x != stack_pointer_rtx)
20375         emit_move_insn (stack_pointer_rtx, x);
20376     }
20377   else
20378     {
20379       x = copy_to_mode_reg (Pmode, operands[1]);
20380       if (TARGET_64BIT)
20381         x = gen_allocate_stack_worker_64 (x, x);
20382       else
20383         x = gen_allocate_stack_worker_32 (x, x);
20384       emit_insn (x);
20385     }
20386
20387   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20388   DONE;
20389 })
20390
20391 (define_expand "builtin_setjmp_receiver"
20392   [(label_ref (match_operand 0 "" ""))]
20393   "!TARGET_64BIT && flag_pic"
20394 {
20395 #if TARGET_MACHO
20396   if (TARGET_MACHO)
20397     {
20398       rtx xops[3];
20399       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20400       rtx label_rtx = gen_label_rtx ();
20401       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20402       xops[0] = xops[1] = picreg;
20403       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20404       ix86_expand_binary_operator (MINUS, SImode, xops);
20405     }
20406   else
20407 #endif
20408     emit_insn (gen_set_got (pic_offset_table_rtx));
20409   DONE;
20410 })
20411 \f
20412 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20413
20414 (define_split
20415   [(set (match_operand 0 "register_operand" "")
20416         (match_operator 3 "promotable_binary_operator"
20417            [(match_operand 1 "register_operand" "")
20418             (match_operand 2 "aligned_operand" "")]))
20419    (clobber (reg:CC FLAGS_REG))]
20420   "! TARGET_PARTIAL_REG_STALL && reload_completed
20421    && ((GET_MODE (operands[0]) == HImode
20422         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20423             /* ??? next two lines just !satisfies_constraint_K (...) */
20424             || !CONST_INT_P (operands[2])
20425             || satisfies_constraint_K (operands[2])))
20426        || (GET_MODE (operands[0]) == QImode
20427            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20428   [(parallel [(set (match_dup 0)
20429                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20430               (clobber (reg:CC FLAGS_REG))])]
20431   "operands[0] = gen_lowpart (SImode, operands[0]);
20432    operands[1] = gen_lowpart (SImode, operands[1]);
20433    if (GET_CODE (operands[3]) != ASHIFT)
20434      operands[2] = gen_lowpart (SImode, operands[2]);
20435    PUT_MODE (operands[3], SImode);")
20436
20437 ; Promote the QImode tests, as i386 has encoding of the AND
20438 ; instruction with 32-bit sign-extended immediate and thus the
20439 ; instruction size is unchanged, except in the %eax case for
20440 ; which it is increased by one byte, hence the ! optimize_size.
20441 (define_split
20442   [(set (match_operand 0 "flags_reg_operand" "")
20443         (match_operator 2 "compare_operator"
20444           [(and (match_operand 3 "aligned_operand" "")
20445                 (match_operand 4 "const_int_operand" ""))
20446            (const_int 0)]))
20447    (set (match_operand 1 "register_operand" "")
20448         (and (match_dup 3) (match_dup 4)))]
20449   "! TARGET_PARTIAL_REG_STALL && reload_completed
20450    && optimize_insn_for_speed_p ()
20451    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20452        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20453    /* Ensure that the operand will remain sign-extended immediate.  */
20454    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20455   [(parallel [(set (match_dup 0)
20456                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20457                                     (const_int 0)]))
20458               (set (match_dup 1)
20459                    (and:SI (match_dup 3) (match_dup 4)))])]
20460 {
20461   operands[4]
20462     = gen_int_mode (INTVAL (operands[4])
20463                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20464   operands[1] = gen_lowpart (SImode, operands[1]);
20465   operands[3] = gen_lowpart (SImode, operands[3]);
20466 })
20467
20468 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20469 ; the TEST instruction with 32-bit sign-extended immediate and thus
20470 ; the instruction size would at least double, which is not what we
20471 ; want even with ! optimize_size.
20472 (define_split
20473   [(set (match_operand 0 "flags_reg_operand" "")
20474         (match_operator 1 "compare_operator"
20475           [(and (match_operand:HI 2 "aligned_operand" "")
20476                 (match_operand:HI 3 "const_int_operand" ""))
20477            (const_int 0)]))]
20478   "! TARGET_PARTIAL_REG_STALL && reload_completed
20479    && ! TARGET_FAST_PREFIX
20480    && optimize_insn_for_speed_p ()
20481    /* Ensure that the operand will remain sign-extended immediate.  */
20482    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20483   [(set (match_dup 0)
20484         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20485                          (const_int 0)]))]
20486 {
20487   operands[3]
20488     = gen_int_mode (INTVAL (operands[3])
20489                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20490   operands[2] = gen_lowpart (SImode, operands[2]);
20491 })
20492
20493 (define_split
20494   [(set (match_operand 0 "register_operand" "")
20495         (neg (match_operand 1 "register_operand" "")))
20496    (clobber (reg:CC FLAGS_REG))]
20497   "! TARGET_PARTIAL_REG_STALL && reload_completed
20498    && (GET_MODE (operands[0]) == HImode
20499        || (GET_MODE (operands[0]) == QImode
20500            && (TARGET_PROMOTE_QImode
20501                || optimize_insn_for_size_p ())))"
20502   [(parallel [(set (match_dup 0)
20503                    (neg:SI (match_dup 1)))
20504               (clobber (reg:CC FLAGS_REG))])]
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         (not (match_operand 1 "register_operand" "")))]
20511   "! TARGET_PARTIAL_REG_STALL && reload_completed
20512    && (GET_MODE (operands[0]) == HImode
20513        || (GET_MODE (operands[0]) == QImode
20514            && (TARGET_PROMOTE_QImode
20515                || optimize_insn_for_size_p ())))"
20516   [(set (match_dup 0)
20517         (not:SI (match_dup 1)))]
20518   "operands[0] = gen_lowpart (SImode, operands[0]);
20519    operands[1] = gen_lowpart (SImode, operands[1]);")
20520
20521 (define_split
20522   [(set (match_operand 0 "register_operand" "")
20523         (if_then_else (match_operator 1 "comparison_operator"
20524                                 [(reg FLAGS_REG) (const_int 0)])
20525                       (match_operand 2 "register_operand" "")
20526                       (match_operand 3 "register_operand" "")))]
20527   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20528    && (GET_MODE (operands[0]) == HImode
20529        || (GET_MODE (operands[0]) == QImode
20530            && (TARGET_PROMOTE_QImode
20531                || optimize_insn_for_size_p ())))"
20532   [(set (match_dup 0)
20533         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20534   "operands[0] = gen_lowpart (SImode, operands[0]);
20535    operands[2] = gen_lowpart (SImode, operands[2]);
20536    operands[3] = gen_lowpart (SImode, operands[3]);")
20537
20538 \f
20539 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20540 ;; transform a complex memory operation into two memory to register operations.
20541
20542 ;; Don't push memory operands
20543 (define_peephole2
20544   [(set (match_operand:SI 0 "push_operand" "")
20545         (match_operand:SI 1 "memory_operand" ""))
20546    (match_scratch:SI 2 "r")]
20547   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20548    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20549   [(set (match_dup 2) (match_dup 1))
20550    (set (match_dup 0) (match_dup 2))]
20551   "")
20552
20553 (define_peephole2
20554   [(set (match_operand:DI 0 "push_operand" "")
20555         (match_operand:DI 1 "memory_operand" ""))
20556    (match_scratch:DI 2 "r")]
20557   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20558    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20559   [(set (match_dup 2) (match_dup 1))
20560    (set (match_dup 0) (match_dup 2))]
20561   "")
20562
20563 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20564 ;; SImode pushes.
20565 (define_peephole2
20566   [(set (match_operand:SF 0 "push_operand" "")
20567         (match_operand:SF 1 "memory_operand" ""))
20568    (match_scratch:SF 2 "r")]
20569   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20570    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20571   [(set (match_dup 2) (match_dup 1))
20572    (set (match_dup 0) (match_dup 2))]
20573   "")
20574
20575 (define_peephole2
20576   [(set (match_operand:HI 0 "push_operand" "")
20577         (match_operand:HI 1 "memory_operand" ""))
20578    (match_scratch:HI 2 "r")]
20579   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20580    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20581   [(set (match_dup 2) (match_dup 1))
20582    (set (match_dup 0) (match_dup 2))]
20583   "")
20584
20585 (define_peephole2
20586   [(set (match_operand:QI 0 "push_operand" "")
20587         (match_operand:QI 1 "memory_operand" ""))
20588    (match_scratch:QI 2 "q")]
20589   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20590    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20591   [(set (match_dup 2) (match_dup 1))
20592    (set (match_dup 0) (match_dup 2))]
20593   "")
20594
20595 ;; Don't move an immediate directly to memory when the instruction
20596 ;; gets too big.
20597 (define_peephole2
20598   [(match_scratch:SI 1 "r")
20599    (set (match_operand:SI 0 "memory_operand" "")
20600         (const_int 0))]
20601   "optimize_insn_for_speed_p ()
20602    && ! TARGET_USE_MOV0
20603    && TARGET_SPLIT_LONG_MOVES
20604    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20605    && peep2_regno_dead_p (0, FLAGS_REG)"
20606   [(parallel [(set (match_dup 1) (const_int 0))
20607               (clobber (reg:CC FLAGS_REG))])
20608    (set (match_dup 0) (match_dup 1))]
20609   "")
20610
20611 (define_peephole2
20612   [(match_scratch:HI 1 "r")
20613    (set (match_operand:HI 0 "memory_operand" "")
20614         (const_int 0))]
20615   "optimize_insn_for_speed_p ()
20616    && ! TARGET_USE_MOV0
20617    && TARGET_SPLIT_LONG_MOVES
20618    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20619    && peep2_regno_dead_p (0, FLAGS_REG)"
20620   [(parallel [(set (match_dup 2) (const_int 0))
20621               (clobber (reg:CC FLAGS_REG))])
20622    (set (match_dup 0) (match_dup 1))]
20623   "operands[2] = gen_lowpart (SImode, operands[1]);")
20624
20625 (define_peephole2
20626   [(match_scratch:QI 1 "q")
20627    (set (match_operand:QI 0 "memory_operand" "")
20628         (const_int 0))]
20629   "optimize_insn_for_speed_p ()
20630    && ! TARGET_USE_MOV0
20631    && TARGET_SPLIT_LONG_MOVES
20632    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20633    && peep2_regno_dead_p (0, FLAGS_REG)"
20634   [(parallel [(set (match_dup 2) (const_int 0))
20635               (clobber (reg:CC FLAGS_REG))])
20636    (set (match_dup 0) (match_dup 1))]
20637   "operands[2] = gen_lowpart (SImode, operands[1]);")
20638
20639 (define_peephole2
20640   [(match_scratch:SI 2 "r")
20641    (set (match_operand:SI 0 "memory_operand" "")
20642         (match_operand:SI 1 "immediate_operand" ""))]
20643   "optimize_insn_for_speed_p ()
20644    && TARGET_SPLIT_LONG_MOVES
20645    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20646   [(set (match_dup 2) (match_dup 1))
20647    (set (match_dup 0) (match_dup 2))]
20648   "")
20649
20650 (define_peephole2
20651   [(match_scratch:HI 2 "r")
20652    (set (match_operand:HI 0 "memory_operand" "")
20653         (match_operand:HI 1 "immediate_operand" ""))]
20654   "optimize_insn_for_speed_p ()
20655    && TARGET_SPLIT_LONG_MOVES
20656    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20657   [(set (match_dup 2) (match_dup 1))
20658    (set (match_dup 0) (match_dup 2))]
20659   "")
20660
20661 (define_peephole2
20662   [(match_scratch:QI 2 "q")
20663    (set (match_operand:QI 0 "memory_operand" "")
20664         (match_operand:QI 1 "immediate_operand" ""))]
20665   "optimize_insn_for_speed_p ()
20666    && TARGET_SPLIT_LONG_MOVES
20667    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20668   [(set (match_dup 2) (match_dup 1))
20669    (set (match_dup 0) (match_dup 2))]
20670   "")
20671
20672 ;; Don't compare memory with zero, load and use a test instead.
20673 (define_peephole2
20674   [(set (match_operand 0 "flags_reg_operand" "")
20675         (match_operator 1 "compare_operator"
20676           [(match_operand:SI 2 "memory_operand" "")
20677            (const_int 0)]))
20678    (match_scratch:SI 3 "r")]
20679   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20680   [(set (match_dup 3) (match_dup 2))
20681    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20682   "")
20683
20684 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20685 ;; Don't split NOTs with a displacement operand, because resulting XOR
20686 ;; will not be pairable anyway.
20687 ;;
20688 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20689 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20690 ;; so this split helps here as well.
20691 ;;
20692 ;; Note: Can't do this as a regular split because we can't get proper
20693 ;; lifetime information then.
20694
20695 (define_peephole2
20696   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20697         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20698   "optimize_insn_for_speed_p ()
20699    && ((TARGET_NOT_UNPAIRABLE
20700         && (!MEM_P (operands[0])
20701             || !memory_displacement_operand (operands[0], SImode)))
20702        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20703    && peep2_regno_dead_p (0, FLAGS_REG)"
20704   [(parallel [(set (match_dup 0)
20705                    (xor:SI (match_dup 1) (const_int -1)))
20706               (clobber (reg:CC FLAGS_REG))])]
20707   "")
20708
20709 (define_peephole2
20710   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20711         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20712   "optimize_insn_for_speed_p ()
20713    && ((TARGET_NOT_UNPAIRABLE
20714         && (!MEM_P (operands[0])
20715             || !memory_displacement_operand (operands[0], HImode)))
20716        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20717    && peep2_regno_dead_p (0, FLAGS_REG)"
20718   [(parallel [(set (match_dup 0)
20719                    (xor:HI (match_dup 1) (const_int -1)))
20720               (clobber (reg:CC FLAGS_REG))])]
20721   "")
20722
20723 (define_peephole2
20724   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20725         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20726   "optimize_insn_for_speed_p ()
20727    && ((TARGET_NOT_UNPAIRABLE
20728         && (!MEM_P (operands[0])
20729             || !memory_displacement_operand (operands[0], QImode)))
20730        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20731    && peep2_regno_dead_p (0, FLAGS_REG)"
20732   [(parallel [(set (match_dup 0)
20733                    (xor:QI (match_dup 1) (const_int -1)))
20734               (clobber (reg:CC FLAGS_REG))])]
20735   "")
20736
20737 ;; Non pairable "test imm, reg" instructions can be translated to
20738 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20739 ;; byte opcode instead of two, have a short form for byte operands),
20740 ;; so do it for other CPUs as well.  Given that the value was dead,
20741 ;; this should not create any new dependencies.  Pass on the sub-word
20742 ;; versions if we're concerned about partial register stalls.
20743
20744 (define_peephole2
20745   [(set (match_operand 0 "flags_reg_operand" "")
20746         (match_operator 1 "compare_operator"
20747           [(and:SI (match_operand:SI 2 "register_operand" "")
20748                    (match_operand:SI 3 "immediate_operand" ""))
20749            (const_int 0)]))]
20750   "ix86_match_ccmode (insn, CCNOmode)
20751    && (true_regnum (operands[2]) != AX_REG
20752        || satisfies_constraint_K (operands[3]))
20753    && peep2_reg_dead_p (1, operands[2])"
20754   [(parallel
20755      [(set (match_dup 0)
20756            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20757                             (const_int 0)]))
20758       (set (match_dup 2)
20759            (and:SI (match_dup 2) (match_dup 3)))])]
20760   "")
20761
20762 ;; We don't need to handle HImode case, because it will be promoted to SImode
20763 ;; on ! TARGET_PARTIAL_REG_STALL
20764
20765 (define_peephole2
20766   [(set (match_operand 0 "flags_reg_operand" "")
20767         (match_operator 1 "compare_operator"
20768           [(and:QI (match_operand:QI 2 "register_operand" "")
20769                    (match_operand:QI 3 "immediate_operand" ""))
20770            (const_int 0)]))]
20771   "! TARGET_PARTIAL_REG_STALL
20772    && ix86_match_ccmode (insn, CCNOmode)
20773    && true_regnum (operands[2]) != AX_REG
20774    && peep2_reg_dead_p (1, operands[2])"
20775   [(parallel
20776      [(set (match_dup 0)
20777            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20778                             (const_int 0)]))
20779       (set (match_dup 2)
20780            (and:QI (match_dup 2) (match_dup 3)))])]
20781   "")
20782
20783 (define_peephole2
20784   [(set (match_operand 0 "flags_reg_operand" "")
20785         (match_operator 1 "compare_operator"
20786           [(and:SI
20787              (zero_extract:SI
20788                (match_operand 2 "ext_register_operand" "")
20789                (const_int 8)
20790                (const_int 8))
20791              (match_operand 3 "const_int_operand" ""))
20792            (const_int 0)]))]
20793   "! TARGET_PARTIAL_REG_STALL
20794    && ix86_match_ccmode (insn, CCNOmode)
20795    && true_regnum (operands[2]) != AX_REG
20796    && peep2_reg_dead_p (1, operands[2])"
20797   [(parallel [(set (match_dup 0)
20798                    (match_op_dup 1
20799                      [(and:SI
20800                         (zero_extract:SI
20801                           (match_dup 2)
20802                           (const_int 8)
20803                           (const_int 8))
20804                         (match_dup 3))
20805                       (const_int 0)]))
20806               (set (zero_extract:SI (match_dup 2)
20807                                     (const_int 8)
20808                                     (const_int 8))
20809                    (and:SI
20810                      (zero_extract:SI
20811                        (match_dup 2)
20812                        (const_int 8)
20813                        (const_int 8))
20814                      (match_dup 3)))])]
20815   "")
20816
20817 ;; Don't do logical operations with memory inputs.
20818 (define_peephole2
20819   [(match_scratch:SI 2 "r")
20820    (parallel [(set (match_operand:SI 0 "register_operand" "")
20821                    (match_operator:SI 3 "arith_or_logical_operator"
20822                      [(match_dup 0)
20823                       (match_operand:SI 1 "memory_operand" "")]))
20824               (clobber (reg:CC FLAGS_REG))])]
20825   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20826   [(set (match_dup 2) (match_dup 1))
20827    (parallel [(set (match_dup 0)
20828                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20829               (clobber (reg:CC FLAGS_REG))])]
20830   "")
20831
20832 (define_peephole2
20833   [(match_scratch:SI 2 "r")
20834    (parallel [(set (match_operand:SI 0 "register_operand" "")
20835                    (match_operator:SI 3 "arith_or_logical_operator"
20836                      [(match_operand:SI 1 "memory_operand" "")
20837                       (match_dup 0)]))
20838               (clobber (reg:CC FLAGS_REG))])]
20839   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20840   [(set (match_dup 2) (match_dup 1))
20841    (parallel [(set (match_dup 0)
20842                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20843               (clobber (reg:CC FLAGS_REG))])]
20844   "")
20845
20846 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20847 ;; refers to the destination of the load!
20848
20849 (define_peephole2
20850   [(set (match_operand:SI 0 "register_operand" "")
20851         (match_operand:SI 1 "register_operand" ""))
20852    (parallel [(set (match_dup 0)
20853                    (match_operator:SI 3 "commutative_operator"
20854                      [(match_dup 0)
20855                       (match_operand:SI 2 "memory_operand" "")]))
20856               (clobber (reg:CC FLAGS_REG))])]
20857   "REGNO (operands[0]) != REGNO (operands[1])
20858    && GENERAL_REGNO_P (REGNO (operands[0]))
20859    && GENERAL_REGNO_P (REGNO (operands[1]))"
20860   [(set (match_dup 0) (match_dup 4))
20861    (parallel [(set (match_dup 0)
20862                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20863               (clobber (reg:CC FLAGS_REG))])]
20864   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20865
20866 (define_peephole2
20867   [(set (match_operand 0 "register_operand" "")
20868         (match_operand 1 "register_operand" ""))
20869    (set (match_dup 0)
20870                    (match_operator 3 "commutative_operator"
20871                      [(match_dup 0)
20872                       (match_operand 2 "memory_operand" "")]))]
20873   "REGNO (operands[0]) != REGNO (operands[1])
20874    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
20875        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20876   [(set (match_dup 0) (match_dup 2))
20877    (set (match_dup 0)
20878         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20879   "")
20880
20881 ; Don't do logical operations with memory outputs
20882 ;
20883 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20884 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20885 ; the same decoder scheduling characteristics as the original.
20886
20887 (define_peephole2
20888   [(match_scratch:SI 2 "r")
20889    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20890                    (match_operator:SI 3 "arith_or_logical_operator"
20891                      [(match_dup 0)
20892                       (match_operand:SI 1 "nonmemory_operand" "")]))
20893               (clobber (reg:CC FLAGS_REG))])]
20894   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20895   [(set (match_dup 2) (match_dup 0))
20896    (parallel [(set (match_dup 2)
20897                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20898               (clobber (reg:CC FLAGS_REG))])
20899    (set (match_dup 0) (match_dup 2))]
20900   "")
20901
20902 (define_peephole2
20903   [(match_scratch:SI 2 "r")
20904    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20905                    (match_operator:SI 3 "arith_or_logical_operator"
20906                      [(match_operand:SI 1 "nonmemory_operand" "")
20907                       (match_dup 0)]))
20908               (clobber (reg:CC FLAGS_REG))])]
20909   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20910   [(set (match_dup 2) (match_dup 0))
20911    (parallel [(set (match_dup 2)
20912                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20913               (clobber (reg:CC FLAGS_REG))])
20914    (set (match_dup 0) (match_dup 2))]
20915   "")
20916
20917 ;; Attempt to always use XOR for zeroing registers.
20918 (define_peephole2
20919   [(set (match_operand 0 "register_operand" "")
20920         (match_operand 1 "const0_operand" ""))]
20921   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20922    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20923    && GENERAL_REG_P (operands[0])
20924    && peep2_regno_dead_p (0, FLAGS_REG)"
20925   [(parallel [(set (match_dup 0) (const_int 0))
20926               (clobber (reg:CC FLAGS_REG))])]
20927 {
20928   operands[0] = gen_lowpart (word_mode, operands[0]);
20929 })
20930
20931 (define_peephole2
20932   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20933         (const_int 0))]
20934   "(GET_MODE (operands[0]) == QImode
20935     || GET_MODE (operands[0]) == HImode)
20936    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20937    && peep2_regno_dead_p (0, FLAGS_REG)"
20938   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20939               (clobber (reg:CC FLAGS_REG))])])
20940
20941 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20942 (define_peephole2
20943   [(set (match_operand 0 "register_operand" "")
20944         (const_int -1))]
20945   "(GET_MODE (operands[0]) == HImode
20946     || GET_MODE (operands[0]) == SImode
20947     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20948    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20949    && peep2_regno_dead_p (0, FLAGS_REG)"
20950   [(parallel [(set (match_dup 0) (const_int -1))
20951               (clobber (reg:CC FLAGS_REG))])]
20952   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20953                               operands[0]);")
20954
20955 ;; Attempt to convert simple leas to adds. These can be created by
20956 ;; move expanders.
20957 (define_peephole2
20958   [(set (match_operand:SI 0 "register_operand" "")
20959         (plus:SI (match_dup 0)
20960                  (match_operand:SI 1 "nonmemory_operand" "")))]
20961   "peep2_regno_dead_p (0, FLAGS_REG)"
20962   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20963               (clobber (reg:CC FLAGS_REG))])]
20964   "")
20965
20966 (define_peephole2
20967   [(set (match_operand:SI 0 "register_operand" "")
20968         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20969                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20970   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20971   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20972               (clobber (reg:CC FLAGS_REG))])]
20973   "operands[2] = gen_lowpart (SImode, operands[2]);")
20974
20975 (define_peephole2
20976   [(set (match_operand:DI 0 "register_operand" "")
20977         (plus:DI (match_dup 0)
20978                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20979   "peep2_regno_dead_p (0, FLAGS_REG)"
20980   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20981               (clobber (reg:CC FLAGS_REG))])]
20982   "")
20983
20984 (define_peephole2
20985   [(set (match_operand:SI 0 "register_operand" "")
20986         (mult:SI (match_dup 0)
20987                  (match_operand:SI 1 "const_int_operand" "")))]
20988   "exact_log2 (INTVAL (operands[1])) >= 0
20989    && peep2_regno_dead_p (0, FLAGS_REG)"
20990   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20991               (clobber (reg:CC FLAGS_REG))])]
20992   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20993
20994 (define_peephole2
20995   [(set (match_operand:DI 0 "register_operand" "")
20996         (mult:DI (match_dup 0)
20997                  (match_operand:DI 1 "const_int_operand" "")))]
20998   "exact_log2 (INTVAL (operands[1])) >= 0
20999    && peep2_regno_dead_p (0, FLAGS_REG)"
21000   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21001               (clobber (reg:CC FLAGS_REG))])]
21002   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21003
21004 (define_peephole2
21005   [(set (match_operand:SI 0 "register_operand" "")
21006         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21007                    (match_operand:DI 2 "const_int_operand" "")) 0))]
21008   "exact_log2 (INTVAL (operands[2])) >= 0
21009    && REGNO (operands[0]) == REGNO (operands[1])
21010    && peep2_regno_dead_p (0, FLAGS_REG)"
21011   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21012               (clobber (reg:CC FLAGS_REG))])]
21013   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21014
21015 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
21016 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
21017 ;; many CPUs it is also faster, since special hardware to avoid esp
21018 ;; dependencies is present.
21019
21020 ;; While some of these conversions may be done using splitters, we use peepholes
21021 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21022
21023 ;; Convert prologue esp subtractions to push.
21024 ;; We need register to push.  In order to keep verify_flow_info happy we have
21025 ;; two choices
21026 ;; - use scratch and clobber it in order to avoid dependencies
21027 ;; - use already live register
21028 ;; We can't use the second way right now, since there is no reliable way how to
21029 ;; verify that given register is live.  First choice will also most likely in
21030 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
21031 ;; call clobbered registers are dead.  We may want to use base pointer as an
21032 ;; alternative when no register is available later.
21033
21034 (define_peephole2
21035   [(match_scratch:SI 0 "r")
21036    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21037               (clobber (reg:CC FLAGS_REG))
21038               (clobber (mem:BLK (scratch)))])]
21039   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21040   [(clobber (match_dup 0))
21041    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21042               (clobber (mem:BLK (scratch)))])])
21043
21044 (define_peephole2
21045   [(match_scratch:SI 0 "r")
21046    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21047               (clobber (reg:CC FLAGS_REG))
21048               (clobber (mem:BLK (scratch)))])]
21049   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21050   [(clobber (match_dup 0))
21051    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21052    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21053               (clobber (mem:BLK (scratch)))])])
21054
21055 ;; Convert esp subtractions to push.
21056 (define_peephole2
21057   [(match_scratch:SI 0 "r")
21058    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21059               (clobber (reg:CC FLAGS_REG))])]
21060   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21061   [(clobber (match_dup 0))
21062    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21063
21064 (define_peephole2
21065   [(match_scratch:SI 0 "r")
21066    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21067               (clobber (reg:CC FLAGS_REG))])]
21068   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21069   [(clobber (match_dup 0))
21070    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21071    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21072
21073 ;; Convert epilogue deallocator to pop.
21074 (define_peephole2
21075   [(match_scratch:SI 0 "r")
21076    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21077               (clobber (reg:CC FLAGS_REG))
21078               (clobber (mem:BLK (scratch)))])]
21079   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21080   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21081               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21082               (clobber (mem:BLK (scratch)))])]
21083   "")
21084
21085 ;; Two pops case is tricky, since pop causes dependency on destination register.
21086 ;; We use two registers if available.
21087 (define_peephole2
21088   [(match_scratch:SI 0 "r")
21089    (match_scratch:SI 1 "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 () || !TARGET_ADD_ESP_8"
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 1) (mem:SI (reg:SI SP_REG)))
21098               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21099   "")
21100
21101 (define_peephole2
21102   [(match_scratch:SI 0 "r")
21103    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21104               (clobber (reg:CC FLAGS_REG))
21105               (clobber (mem:BLK (scratch)))])]
21106   "optimize_insn_for_size_p ()"
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               (clobber (mem:BLK (scratch)))])
21110    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21111               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21112   "")
21113
21114 ;; Convert esp additions to pop.
21115 (define_peephole2
21116   [(match_scratch:SI 0 "r")
21117    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21118               (clobber (reg:CC FLAGS_REG))])]
21119   ""
21120   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21121               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21122   "")
21123
21124 ;; Two pops case is tricky, since pop causes dependency on destination register.
21125 ;; We use two registers if available.
21126 (define_peephole2
21127   [(match_scratch:SI 0 "r")
21128    (match_scratch:SI 1 "r")
21129    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21130               (clobber (reg:CC FLAGS_REG))])]
21131   ""
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    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21135               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21136   "")
21137
21138 (define_peephole2
21139   [(match_scratch:SI 0 "r")
21140    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21141               (clobber (reg:CC FLAGS_REG))])]
21142   "optimize_insn_for_size_p ()"
21143   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21144               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21145    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21146               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21147   "")
21148 \f
21149 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21150 ;; required and register dies.  Similarly for 128 to -128.
21151 (define_peephole2
21152   [(set (match_operand 0 "flags_reg_operand" "")
21153         (match_operator 1 "compare_operator"
21154           [(match_operand 2 "register_operand" "")
21155            (match_operand 3 "const_int_operand" "")]))]
21156   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21157      && incdec_operand (operands[3], GET_MODE (operands[3])))
21158     || (!TARGET_FUSE_CMP_AND_BRANCH
21159         && INTVAL (operands[3]) == 128))
21160    && ix86_match_ccmode (insn, CCGCmode)
21161    && peep2_reg_dead_p (1, operands[2])"
21162   [(parallel [(set (match_dup 0)
21163                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21164               (clobber (match_dup 2))])]
21165   "")
21166 \f
21167 (define_peephole2
21168   [(match_scratch:DI 0 "r")
21169    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21170               (clobber (reg:CC FLAGS_REG))
21171               (clobber (mem:BLK (scratch)))])]
21172   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21173   [(clobber (match_dup 0))
21174    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21175               (clobber (mem:BLK (scratch)))])])
21176
21177 (define_peephole2
21178   [(match_scratch:DI 0 "r")
21179    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21180               (clobber (reg:CC FLAGS_REG))
21181               (clobber (mem:BLK (scratch)))])]
21182   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21183   [(clobber (match_dup 0))
21184    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21185    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21186               (clobber (mem:BLK (scratch)))])])
21187
21188 ;; Convert esp subtractions to push.
21189 (define_peephole2
21190   [(match_scratch:DI 0 "r")
21191    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21192               (clobber (reg:CC FLAGS_REG))])]
21193   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21194   [(clobber (match_dup 0))
21195    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21196
21197 (define_peephole2
21198   [(match_scratch:DI 0 "r")
21199    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21200               (clobber (reg:CC FLAGS_REG))])]
21201   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21202   [(clobber (match_dup 0))
21203    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21204    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21205
21206 ;; Convert epilogue deallocator to pop.
21207 (define_peephole2
21208   [(match_scratch:DI 0 "r")
21209    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21210               (clobber (reg:CC FLAGS_REG))
21211               (clobber (mem:BLK (scratch)))])]
21212   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21213   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21214               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21215               (clobber (mem:BLK (scratch)))])]
21216   "")
21217
21218 ;; Two pops case is tricky, since pop causes dependency on destination register.
21219 ;; We use two registers if available.
21220 (define_peephole2
21221   [(match_scratch:DI 0 "r")
21222    (match_scratch:DI 1 "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 () || !TARGET_ADD_ESP_8"
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 1) (mem:DI (reg:DI SP_REG)))
21231               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21232   "")
21233
21234 (define_peephole2
21235   [(match_scratch:DI 0 "r")
21236    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21237               (clobber (reg:CC FLAGS_REG))
21238               (clobber (mem:BLK (scratch)))])]
21239   "optimize_insn_for_size_p ()"
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               (clobber (mem:BLK (scratch)))])
21243    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21244               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21245   "")
21246
21247 ;; Convert esp additions to pop.
21248 (define_peephole2
21249   [(match_scratch:DI 0 "r")
21250    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21251               (clobber (reg:CC FLAGS_REG))])]
21252   ""
21253   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21254               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21255   "")
21256
21257 ;; Two pops case is tricky, since pop causes dependency on destination register.
21258 ;; We use two registers if available.
21259 (define_peephole2
21260   [(match_scratch:DI 0 "r")
21261    (match_scratch:DI 1 "r")
21262    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21263               (clobber (reg:CC FLAGS_REG))])]
21264   ""
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    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21268               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21269   "")
21270
21271 (define_peephole2
21272   [(match_scratch:DI 0 "r")
21273    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21274               (clobber (reg:CC FLAGS_REG))])]
21275   "optimize_insn_for_size_p ()"
21276   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21277               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21278    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21279               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21280   "")
21281 \f
21282 ;; Convert imul by three, five and nine into lea
21283 (define_peephole2
21284   [(parallel
21285     [(set (match_operand:SI 0 "register_operand" "")
21286           (mult:SI (match_operand:SI 1 "register_operand" "")
21287                    (match_operand:SI 2 "const_int_operand" "")))
21288      (clobber (reg:CC FLAGS_REG))])]
21289   "INTVAL (operands[2]) == 3
21290    || INTVAL (operands[2]) == 5
21291    || INTVAL (operands[2]) == 9"
21292   [(set (match_dup 0)
21293         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21294                  (match_dup 1)))]
21295   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21296
21297 (define_peephole2
21298   [(parallel
21299     [(set (match_operand:SI 0 "register_operand" "")
21300           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21301                    (match_operand:SI 2 "const_int_operand" "")))
21302      (clobber (reg:CC FLAGS_REG))])]
21303   "optimize_insn_for_speed_p ()
21304    && (INTVAL (operands[2]) == 3
21305        || INTVAL (operands[2]) == 5
21306        || INTVAL (operands[2]) == 9)"
21307   [(set (match_dup 0) (match_dup 1))
21308    (set (match_dup 0)
21309         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21310                  (match_dup 0)))]
21311   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21312
21313 (define_peephole2
21314   [(parallel
21315     [(set (match_operand:DI 0 "register_operand" "")
21316           (mult:DI (match_operand:DI 1 "register_operand" "")
21317                    (match_operand:DI 2 "const_int_operand" "")))
21318      (clobber (reg:CC FLAGS_REG))])]
21319   "TARGET_64BIT
21320    && (INTVAL (operands[2]) == 3
21321        || INTVAL (operands[2]) == 5
21322        || INTVAL (operands[2]) == 9)"
21323   [(set (match_dup 0)
21324         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21325                  (match_dup 1)))]
21326   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21327
21328 (define_peephole2
21329   [(parallel
21330     [(set (match_operand:DI 0 "register_operand" "")
21331           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21332                    (match_operand:DI 2 "const_int_operand" "")))
21333      (clobber (reg:CC FLAGS_REG))])]
21334   "TARGET_64BIT
21335    && optimize_insn_for_speed_p ()
21336    && (INTVAL (operands[2]) == 3
21337        || INTVAL (operands[2]) == 5
21338        || INTVAL (operands[2]) == 9)"
21339   [(set (match_dup 0) (match_dup 1))
21340    (set (match_dup 0)
21341         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21342                  (match_dup 0)))]
21343   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21344
21345 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21346 ;; imul $32bit_imm, reg, reg is direct decoded.
21347 (define_peephole2
21348   [(match_scratch:DI 3 "r")
21349    (parallel [(set (match_operand:DI 0 "register_operand" "")
21350                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21351                             (match_operand:DI 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:DI (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:SI 0 "register_operand" "")
21363                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21364                             (match_operand:SI 2 "immediate_operand" "")))
21365               (clobber (reg:CC FLAGS_REG))])]
21366   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21367    && !satisfies_constraint_K (operands[2])"
21368   [(set (match_dup 3) (match_dup 1))
21369    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21370               (clobber (reg:CC FLAGS_REG))])]
21371 "")
21372
21373 (define_peephole2
21374   [(match_scratch:SI 3 "r")
21375    (parallel [(set (match_operand:DI 0 "register_operand" "")
21376                    (zero_extend:DI
21377                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21378                               (match_operand:SI 2 "immediate_operand" ""))))
21379               (clobber (reg:CC FLAGS_REG))])]
21380   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21381    && !satisfies_constraint_K (operands[2])"
21382   [(set (match_dup 3) (match_dup 1))
21383    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21384               (clobber (reg:CC FLAGS_REG))])]
21385 "")
21386
21387 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21388 ;; Convert it into imul reg, reg
21389 ;; It would be better to force assembler to encode instruction using long
21390 ;; immediate, but there is apparently no way to do so.
21391 (define_peephole2
21392   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21393                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21394                             (match_operand:DI 2 "const_int_operand" "")))
21395               (clobber (reg:CC FLAGS_REG))])
21396    (match_scratch:DI 3 "r")]
21397   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21398    && satisfies_constraint_K (operands[2])"
21399   [(set (match_dup 3) (match_dup 2))
21400    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21401               (clobber (reg:CC FLAGS_REG))])]
21402 {
21403   if (!rtx_equal_p (operands[0], operands[1]))
21404     emit_move_insn (operands[0], operands[1]);
21405 })
21406
21407 (define_peephole2
21408   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21409                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21410                             (match_operand:SI 2 "const_int_operand" "")))
21411               (clobber (reg:CC FLAGS_REG))])
21412    (match_scratch:SI 3 "r")]
21413   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21414    && satisfies_constraint_K (operands[2])"
21415   [(set (match_dup 3) (match_dup 2))
21416    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21417               (clobber (reg:CC FLAGS_REG))])]
21418 {
21419   if (!rtx_equal_p (operands[0], operands[1]))
21420     emit_move_insn (operands[0], operands[1]);
21421 })
21422
21423 (define_peephole2
21424   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21425                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21426                             (match_operand:HI 2 "immediate_operand" "")))
21427               (clobber (reg:CC FLAGS_REG))])
21428    (match_scratch:HI 3 "r")]
21429   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21430   [(set (match_dup 3) (match_dup 2))
21431    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21432               (clobber (reg:CC FLAGS_REG))])]
21433 {
21434   if (!rtx_equal_p (operands[0], operands[1]))
21435     emit_move_insn (operands[0], operands[1]);
21436 })
21437
21438 ;; After splitting up read-modify operations, array accesses with memory
21439 ;; operands might end up in form:
21440 ;;  sall    $2, %eax
21441 ;;  movl    4(%esp), %edx
21442 ;;  addl    %edx, %eax
21443 ;; instead of pre-splitting:
21444 ;;  sall    $2, %eax
21445 ;;  addl    4(%esp), %eax
21446 ;; Turn it into:
21447 ;;  movl    4(%esp), %edx
21448 ;;  leal    (%edx,%eax,4), %eax
21449
21450 (define_peephole2
21451   [(parallel [(set (match_operand 0 "register_operand" "")
21452                    (ashift (match_operand 1 "register_operand" "")
21453                            (match_operand 2 "const_int_operand" "")))
21454                (clobber (reg:CC FLAGS_REG))])
21455    (set (match_operand 3 "register_operand")
21456         (match_operand 4 "x86_64_general_operand" ""))
21457    (parallel [(set (match_operand 5 "register_operand" "")
21458                    (plus (match_operand 6 "register_operand" "")
21459                          (match_operand 7 "register_operand" "")))
21460                    (clobber (reg:CC FLAGS_REG))])]
21461   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21462    /* Validate MODE for lea.  */
21463    && ((!TARGET_PARTIAL_REG_STALL
21464         && (GET_MODE (operands[0]) == QImode
21465             || GET_MODE (operands[0]) == HImode))
21466        || GET_MODE (operands[0]) == SImode
21467        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21468    /* We reorder load and the shift.  */
21469    && !rtx_equal_p (operands[1], operands[3])
21470    && !reg_overlap_mentioned_p (operands[0], operands[4])
21471    /* Last PLUS must consist of operand 0 and 3.  */
21472    && !rtx_equal_p (operands[0], operands[3])
21473    && (rtx_equal_p (operands[3], operands[6])
21474        || rtx_equal_p (operands[3], operands[7]))
21475    && (rtx_equal_p (operands[0], operands[6])
21476        || rtx_equal_p (operands[0], operands[7]))
21477    /* The intermediate operand 0 must die or be same as output.  */
21478    && (rtx_equal_p (operands[0], operands[5])
21479        || peep2_reg_dead_p (3, operands[0]))"
21480   [(set (match_dup 3) (match_dup 4))
21481    (set (match_dup 0) (match_dup 1))]
21482 {
21483   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21484   int scale = 1 << INTVAL (operands[2]);
21485   rtx index = gen_lowpart (Pmode, operands[1]);
21486   rtx base = gen_lowpart (Pmode, operands[3]);
21487   rtx dest = gen_lowpart (mode, operands[5]);
21488
21489   operands[1] = gen_rtx_PLUS (Pmode, base,
21490                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21491   if (mode != Pmode)
21492     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21493   operands[0] = dest;
21494 })
21495 \f
21496 ;; Call-value patterns last so that the wildcard operand does not
21497 ;; disrupt insn-recog's switch tables.
21498
21499 (define_insn "*call_value_pop_0"
21500   [(set (match_operand 0 "" "")
21501         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21502               (match_operand:SI 2 "" "")))
21503    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21504                             (match_operand:SI 3 "immediate_operand" "")))]
21505   "!TARGET_64BIT"
21506 {
21507   if (SIBLING_CALL_P (insn))
21508     return "jmp\t%P1";
21509   else
21510     return "call\t%P1";
21511 }
21512   [(set_attr "type" "callv")])
21513
21514 (define_insn "*call_value_pop_1"
21515   [(set (match_operand 0 "" "")
21516         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21517               (match_operand:SI 2 "" "")))
21518    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21519                             (match_operand:SI 3 "immediate_operand" "i")))]
21520   "!TARGET_64BIT"
21521 {
21522   if (constant_call_address_operand (operands[1], Pmode))
21523     {
21524       if (SIBLING_CALL_P (insn))
21525         return "jmp\t%P1";
21526       else
21527         return "call\t%P1";
21528     }
21529   if (SIBLING_CALL_P (insn))
21530     return "jmp\t%A1";
21531   else
21532     return "call\t%A1";
21533 }
21534   [(set_attr "type" "callv")])
21535
21536 (define_insn "*call_value_0"
21537   [(set (match_operand 0 "" "")
21538         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21539               (match_operand:SI 2 "" "")))]
21540   "!TARGET_64BIT"
21541 {
21542   if (SIBLING_CALL_P (insn))
21543     return "jmp\t%P1";
21544   else
21545     return "call\t%P1";
21546 }
21547   [(set_attr "type" "callv")])
21548
21549 (define_insn "*call_value_0_rex64"
21550   [(set (match_operand 0 "" "")
21551         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21552               (match_operand:DI 2 "const_int_operand" "")))]
21553   "TARGET_64BIT"
21554 {
21555   if (SIBLING_CALL_P (insn))
21556     return "jmp\t%P1";
21557   else
21558     return "call\t%P1";
21559 }
21560   [(set_attr "type" "callv")])
21561
21562 (define_insn "*call_value_0_rex64_ms_sysv"
21563   [(set (match_operand 0 "" "")
21564         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21565               (match_operand:DI 2 "const_int_operand" "")))
21566    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21567    (clobber (reg:TI XMM6_REG))
21568    (clobber (reg:TI XMM7_REG))
21569    (clobber (reg:TI XMM8_REG))
21570    (clobber (reg:TI XMM9_REG))
21571    (clobber (reg:TI XMM10_REG))
21572    (clobber (reg:TI XMM11_REG))
21573    (clobber (reg:TI XMM12_REG))
21574    (clobber (reg:TI XMM13_REG))
21575    (clobber (reg:TI XMM14_REG))
21576    (clobber (reg:TI XMM15_REG))
21577    (clobber (reg:DI SI_REG))
21578    (clobber (reg:DI DI_REG))]
21579   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21580 {
21581   if (SIBLING_CALL_P (insn))
21582     return "jmp\t%P1";
21583   else
21584     return "call\t%P1";
21585 }
21586   [(set_attr "type" "callv")])
21587
21588 (define_insn "*call_value_1"
21589   [(set (match_operand 0 "" "")
21590         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21591               (match_operand:SI 2 "" "")))]
21592   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21593 {
21594   if (constant_call_address_operand (operands[1], Pmode))
21595     return "call\t%P1";
21596   return "call\t%A1";
21597 }
21598   [(set_attr "type" "callv")])
21599
21600 (define_insn "*sibcall_value_1"
21601   [(set (match_operand 0 "" "")
21602         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21603               (match_operand:SI 2 "" "")))]
21604   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21605 {
21606   if (constant_call_address_operand (operands[1], Pmode))
21607     return "jmp\t%P1";
21608   return "jmp\t%A1";
21609 }
21610   [(set_attr "type" "callv")])
21611
21612 (define_insn "*call_value_1_rex64"
21613   [(set (match_operand 0 "" "")
21614         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21615               (match_operand:DI 2 "" "")))]
21616   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21617    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21618 {
21619   if (constant_call_address_operand (operands[1], Pmode))
21620     return "call\t%P1";
21621   return "call\t%A1";
21622 }
21623   [(set_attr "type" "callv")])
21624
21625 (define_insn "*call_value_1_rex64_ms_sysv"
21626   [(set (match_operand 0 "" "")
21627         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21628               (match_operand:DI 2 "" "")))
21629    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21630    (clobber (reg:TI 27))
21631    (clobber (reg:TI 28))
21632    (clobber (reg:TI 45))
21633    (clobber (reg:TI 46))
21634    (clobber (reg:TI 47))
21635    (clobber (reg:TI 48))
21636    (clobber (reg:TI 49))
21637    (clobber (reg:TI 50))
21638    (clobber (reg:TI 51))
21639    (clobber (reg:TI 52))
21640    (clobber (reg:DI SI_REG))
21641    (clobber (reg:DI DI_REG))]
21642   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21643 {
21644   if (constant_call_address_operand (operands[1], Pmode))
21645     return "call\t%P1";
21646   return "call\t%A1";
21647 }
21648   [(set_attr "type" "callv")])
21649
21650 (define_insn "*call_value_1_rex64_large"
21651   [(set (match_operand 0 "" "")
21652         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21653               (match_operand:DI 2 "" "")))]
21654   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21655   "call\t%A1"
21656   [(set_attr "type" "callv")])
21657
21658 (define_insn "*sibcall_value_1_rex64"
21659   [(set (match_operand 0 "" "")
21660         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21661               (match_operand:DI 2 "" "")))]
21662   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21663   "jmp\t%P1"
21664   [(set_attr "type" "callv")])
21665
21666 (define_insn "*sibcall_value_1_rex64_v"
21667   [(set (match_operand 0 "" "")
21668         (call (mem:QI (reg:DI R11_REG))
21669               (match_operand:DI 1 "" "")))]
21670   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21671   "jmp\t{*%%}r11"
21672   [(set_attr "type" "callv")])
21673 \f
21674 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21675 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21676 ;; caught for use by garbage collectors and the like.  Using an insn that
21677 ;; maps to SIGILL makes it more likely the program will rightfully die.
21678 ;; Keeping with tradition, "6" is in honor of #UD.
21679 (define_insn "trap"
21680   [(trap_if (const_int 1) (const_int 6))]
21681   ""
21682   { return ASM_SHORT "0x0b0f"; }
21683   [(set_attr "length" "2")])
21684
21685 (define_expand "sse_prologue_save"
21686   [(parallel [(set (match_operand:BLK 0 "" "")
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" ""))
21696               (use (match_operand:DI 2 "immediate_operand" ""))
21697               (use (label_ref:DI (match_operand 3 "" "")))])]
21698   "TARGET_64BIT"
21699   "")
21700
21701 (define_insn "*sse_prologue_save_insn"
21702   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21703                           (match_operand:DI 4 "const_int_operand" "n")))
21704         (unspec:BLK [(reg:DI 21)
21705                      (reg:DI 22)
21706                      (reg:DI 23)
21707                      (reg:DI 24)
21708                      (reg:DI 25)
21709                      (reg:DI 26)
21710                      (reg:DI 27)
21711                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21712    (use (match_operand:DI 1 "register_operand" "r"))
21713    (use (match_operand:DI 2 "const_int_operand" "i"))
21714    (use (label_ref:DI (match_operand 3 "" "X")))]
21715   "TARGET_64BIT
21716    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21717    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21718 {
21719   int i;
21720   operands[0] = gen_rtx_MEM (Pmode,
21721                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21722   /* VEX instruction with a REX prefix will #UD.  */
21723   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21724     gcc_unreachable ();
21725
21726   output_asm_insn ("jmp\t%A1", operands);
21727   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21728     {
21729       operands[4] = adjust_address (operands[0], DImode, i*16);
21730       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21731       PUT_MODE (operands[4], TImode);
21732       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21733         output_asm_insn ("rex", operands);
21734       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21735     }
21736   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21737                                      CODE_LABEL_NUMBER (operands[3]));
21738   return "";
21739 }
21740   [(set_attr "type" "other")
21741    (set_attr "length_immediate" "0")
21742    (set_attr "length_address" "0")
21743    (set (attr "length")
21744      (if_then_else
21745        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21746        (const_string "34")
21747        (const_string "42")))
21748    (set_attr "memory" "store")
21749    (set_attr "modrm" "0")
21750    (set_attr "prefix" "maybe_vex")
21751    (set_attr "mode" "DI")])
21752
21753 (define_expand "prefetch"
21754   [(prefetch (match_operand 0 "address_operand" "")
21755              (match_operand:SI 1 "const_int_operand" "")
21756              (match_operand:SI 2 "const_int_operand" ""))]
21757   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21758 {
21759   int rw = INTVAL (operands[1]);
21760   int locality = INTVAL (operands[2]);
21761
21762   gcc_assert (rw == 0 || rw == 1);
21763   gcc_assert (locality >= 0 && locality <= 3);
21764   gcc_assert (GET_MODE (operands[0]) == Pmode
21765               || GET_MODE (operands[0]) == VOIDmode);
21766
21767   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21768      supported by SSE counterpart or the SSE prefetch is not available
21769      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21770      of locality.  */
21771   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21772     operands[2] = GEN_INT (3);
21773   else
21774     operands[1] = const0_rtx;
21775 })
21776
21777 (define_insn "*prefetch_sse"
21778   [(prefetch (match_operand:SI 0 "address_operand" "p")
21779              (const_int 0)
21780              (match_operand:SI 1 "const_int_operand" ""))]
21781   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21782 {
21783   static const char * const patterns[4] = {
21784    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21785   };
21786
21787   int locality = INTVAL (operands[1]);
21788   gcc_assert (locality >= 0 && locality <= 3);
21789
21790   return patterns[locality];
21791 }
21792   [(set_attr "type" "sse")
21793    (set_attr "memory" "none")])
21794
21795 (define_insn "*prefetch_sse_rex"
21796   [(prefetch (match_operand:DI 0 "address_operand" "p")
21797              (const_int 0)
21798              (match_operand:SI 1 "const_int_operand" ""))]
21799   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21800 {
21801   static const char * const patterns[4] = {
21802    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21803   };
21804
21805   int locality = INTVAL (operands[1]);
21806   gcc_assert (locality >= 0 && locality <= 3);
21807
21808   return patterns[locality];
21809 }
21810   [(set_attr "type" "sse")
21811    (set_attr "memory" "none")])
21812
21813 (define_insn "*prefetch_3dnow"
21814   [(prefetch (match_operand:SI 0 "address_operand" "p")
21815              (match_operand:SI 1 "const_int_operand" "n")
21816              (const_int 3))]
21817   "TARGET_3DNOW && !TARGET_64BIT"
21818 {
21819   if (INTVAL (operands[1]) == 0)
21820     return "prefetch\t%a0";
21821   else
21822     return "prefetchw\t%a0";
21823 }
21824   [(set_attr "type" "mmx")
21825    (set_attr "memory" "none")])
21826
21827 (define_insn "*prefetch_3dnow_rex"
21828   [(prefetch (match_operand:DI 0 "address_operand" "p")
21829              (match_operand:SI 1 "const_int_operand" "n")
21830              (const_int 3))]
21831   "TARGET_3DNOW && TARGET_64BIT"
21832 {
21833   if (INTVAL (operands[1]) == 0)
21834     return "prefetch\t%a0";
21835   else
21836     return "prefetchw\t%a0";
21837 }
21838   [(set_attr "type" "mmx")
21839    (set_attr "memory" "none")])
21840
21841 (define_expand "stack_protect_set"
21842   [(match_operand 0 "memory_operand" "")
21843    (match_operand 1 "memory_operand" "")]
21844   ""
21845 {
21846 #ifdef TARGET_THREAD_SSP_OFFSET
21847   if (TARGET_64BIT)
21848     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21849                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21850   else
21851     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21852                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21853 #else
21854   if (TARGET_64BIT)
21855     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21856   else
21857     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21858 #endif
21859   DONE;
21860 })
21861
21862 (define_insn "stack_protect_set_si"
21863   [(set (match_operand:SI 0 "memory_operand" "=m")
21864         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21865    (set (match_scratch:SI 2 "=&r") (const_int 0))
21866    (clobber (reg:CC FLAGS_REG))]
21867   ""
21868   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21869   [(set_attr "type" "multi")])
21870
21871 (define_insn "stack_protect_set_di"
21872   [(set (match_operand:DI 0 "memory_operand" "=m")
21873         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21874    (set (match_scratch:DI 2 "=&r") (const_int 0))
21875    (clobber (reg:CC FLAGS_REG))]
21876   "TARGET_64BIT"
21877   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21878   [(set_attr "type" "multi")])
21879
21880 (define_insn "stack_tls_protect_set_si"
21881   [(set (match_operand:SI 0 "memory_operand" "=m")
21882         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21883    (set (match_scratch:SI 2 "=&r") (const_int 0))
21884    (clobber (reg:CC FLAGS_REG))]
21885   ""
21886   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21887   [(set_attr "type" "multi")])
21888
21889 (define_insn "stack_tls_protect_set_di"
21890   [(set (match_operand:DI 0 "memory_operand" "=m")
21891         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21892    (set (match_scratch:DI 2 "=&r") (const_int 0))
21893    (clobber (reg:CC FLAGS_REG))]
21894   "TARGET_64BIT"
21895   {
21896      /* The kernel uses a different segment register for performance reasons; a
21897         system call would not have to trash the userspace segment register,
21898         which would be expensive */
21899      if (ix86_cmodel != CM_KERNEL)
21900         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21901      else
21902         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21903   }
21904   [(set_attr "type" "multi")])
21905
21906 (define_expand "stack_protect_test"
21907   [(match_operand 0 "memory_operand" "")
21908    (match_operand 1 "memory_operand" "")
21909    (match_operand 2 "" "")]
21910   ""
21911 {
21912   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21913   ix86_compare_op0 = operands[0];
21914   ix86_compare_op1 = operands[1];
21915   ix86_compare_emitted = flags;
21916
21917 #ifdef TARGET_THREAD_SSP_OFFSET
21918   if (TARGET_64BIT)
21919     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21920                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21921   else
21922     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21923                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21924 #else
21925   if (TARGET_64BIT)
21926     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21927   else
21928     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21929 #endif
21930   emit_jump_insn (gen_beq (operands[2]));
21931   DONE;
21932 })
21933
21934 (define_insn "stack_protect_test_si"
21935   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21936         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21937                      (match_operand:SI 2 "memory_operand" "m")]
21938                     UNSPEC_SP_TEST))
21939    (clobber (match_scratch:SI 3 "=&r"))]
21940   ""
21941   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21942   [(set_attr "type" "multi")])
21943
21944 (define_insn "stack_protect_test_di"
21945   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21946         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21947                      (match_operand:DI 2 "memory_operand" "m")]
21948                     UNSPEC_SP_TEST))
21949    (clobber (match_scratch:DI 3 "=&r"))]
21950   "TARGET_64BIT"
21951   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21952   [(set_attr "type" "multi")])
21953
21954 (define_insn "stack_tls_protect_test_si"
21955   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21956         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21957                      (match_operand:SI 2 "const_int_operand" "i")]
21958                     UNSPEC_SP_TLS_TEST))
21959    (clobber (match_scratch:SI 3 "=r"))]
21960   ""
21961   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21962   [(set_attr "type" "multi")])
21963
21964 (define_insn "stack_tls_protect_test_di"
21965   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21966         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21967                      (match_operand:DI 2 "const_int_operand" "i")]
21968                     UNSPEC_SP_TLS_TEST))
21969    (clobber (match_scratch:DI 3 "=r"))]
21970   "TARGET_64BIT"
21971   {
21972      /* The kernel uses a different segment register for performance reasons; a
21973         system call would not have to trash the userspace segment register,
21974         which would be expensive */
21975      if (ix86_cmodel != CM_KERNEL)
21976         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21977      else
21978         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21979   }
21980   [(set_attr "type" "multi")])
21981
21982 (define_mode_iterator CRC32MODE [QI HI SI])
21983 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21984 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21985
21986 (define_insn "sse4_2_crc32<mode>"
21987   [(set (match_operand:SI 0 "register_operand" "=r")
21988         (unspec:SI
21989           [(match_operand:SI 1 "register_operand" "0")
21990            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21991           UNSPEC_CRC32))]
21992   "TARGET_SSE4_2"
21993   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21994   [(set_attr "type" "sselog1")
21995    (set_attr "prefix_rep" "1")
21996    (set_attr "prefix_extra" "1")
21997    (set_attr "mode" "SI")])
21998
21999 (define_insn "sse4_2_crc32di"
22000   [(set (match_operand:DI 0 "register_operand" "=r")
22001         (unspec:DI
22002           [(match_operand:DI 1 "register_operand" "0")
22003            (match_operand:DI 2 "nonimmediate_operand" "rm")]
22004           UNSPEC_CRC32))]
22005   "TARGET_SSE4_2 && TARGET_64BIT"
22006   "crc32q\t{%2, %0|%0, %2}"
22007   [(set_attr "type" "sselog1")
22008    (set_attr "prefix_rep" "1")
22009    (set_attr "prefix_extra" "1")
22010    (set_attr "mode" "DI")])
22011
22012 (include "mmx.md")
22013 (include "sse.md")
22014 (include "sync.md")