Import gcc-4.4.1
[dragonfly.git] / contrib / gcc-4.4 / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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 ;; Pre-reload splitter to add memory clobber to the pattern.
5143 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5144   [(set (match_operand:X87MODEF 0 "register_operand" "")
5145         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5146   "((TARGET_80387
5147      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5148            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5149          || TARGET_MIX_SSE_I387))
5150     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5151         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5152         && ((<SSEMODEI24:MODE>mode == SImode
5153              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5154              && optimize_function_for_speed_p (cfun)
5155              && flag_trapping_math)
5156             || !(TARGET_INTER_UNIT_CONVERSIONS
5157                  || optimize_function_for_size_p (cfun)))))
5158    && !(reload_completed || reload_in_progress)"
5159   "#"
5160   "&& 1"
5161   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5162               (clobber (match_dup 2))])]
5163 {
5164   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5165
5166   /* Avoid store forwarding (partial memory) stall penalty
5167      by passing DImode value through XMM registers.  */
5168   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5169       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5170       && optimize_function_for_speed_p (cfun))
5171     {
5172       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5173                                                             operands[1],
5174                                                             operands[2]));
5175       DONE;
5176     }
5177 })
5178
5179 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5180   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5181         (float:MODEF
5182           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5183    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5184   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5185    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5186   "#"
5187   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5188    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5189    (set_attr "unit" "*,i387,*,*,*")
5190    (set_attr "athlon_decode" "*,*,double,direct,double")
5191    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5192    (set_attr "fp_int_src" "true")])
5193
5194 (define_insn "*floatsi<mode>2_vector_mixed"
5195   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5196         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5197   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5198    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5199   "@
5200    fild%z1\t%1
5201    #"
5202   [(set_attr "type" "fmov,sseicvt")
5203    (set_attr "mode" "<MODE>,<ssevecmode>")
5204    (set_attr "unit" "i387,*")
5205    (set_attr "athlon_decode" "*,direct")
5206    (set_attr "amdfam10_decode" "*,double")
5207    (set_attr "fp_int_src" "true")])
5208
5209 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5210   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5211         (float:MODEF
5212           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5213   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5214   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5215    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5216   "#"
5217   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5218    (set_attr "mode" "<MODEF:MODE>")
5219    (set_attr "unit" "*,i387,*,*")
5220    (set_attr "athlon_decode" "*,*,double,direct")
5221    (set_attr "amdfam10_decode" "*,*,vector,double")
5222    (set_attr "fp_int_src" "true")])
5223
5224 (define_split
5225   [(set (match_operand:MODEF 0 "register_operand" "")
5226         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5227    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5228   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5229    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5230    && TARGET_INTER_UNIT_CONVERSIONS
5231    && reload_completed
5232    && (SSE_REG_P (operands[0])
5233        || (GET_CODE (operands[0]) == SUBREG
5234            && SSE_REG_P (operands[0])))"
5235   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5236   "")
5237
5238 (define_split
5239   [(set (match_operand:MODEF 0 "register_operand" "")
5240         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5241    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5242   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5243    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5244    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5245    && reload_completed
5246    && (SSE_REG_P (operands[0])
5247        || (GET_CODE (operands[0]) == SUBREG
5248            && SSE_REG_P (operands[0])))"
5249   [(set (match_dup 2) (match_dup 1))
5250    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5251   "")
5252
5253 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5254   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5255         (float:MODEF
5256           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
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   "@
5261    fild%z1\t%1
5262    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5263    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5264   [(set_attr "type" "fmov,sseicvt,sseicvt")
5265    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5266    (set_attr "mode" "<MODEF:MODE>")
5267    (set_attr "unit" "i387,*,*")
5268    (set_attr "athlon_decode" "*,double,direct")
5269    (set_attr "amdfam10_decode" "*,vector,double")
5270    (set_attr "fp_int_src" "true")])
5271
5272 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5273   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5274         (float:MODEF
5275           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5276   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5277    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5278    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5279   "@
5280    fild%z1\t%1
5281    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5282   [(set_attr "type" "fmov,sseicvt")
5283    (set_attr "prefix" "orig,maybe_vex")
5284    (set_attr "mode" "<MODEF:MODE>")
5285    (set_attr "athlon_decode" "*,direct")
5286    (set_attr "amdfam10_decode" "*,double")
5287    (set_attr "fp_int_src" "true")])
5288
5289 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5290   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5291         (float:MODEF
5292           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5293    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5294   "TARGET_SSE2 && TARGET_SSE_MATH
5295    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5296   "#"
5297   [(set_attr "type" "sseicvt")
5298    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5299    (set_attr "athlon_decode" "double,direct,double")
5300    (set_attr "amdfam10_decode" "vector,double,double")
5301    (set_attr "fp_int_src" "true")])
5302
5303 (define_insn "*floatsi<mode>2_vector_sse"
5304   [(set (match_operand:MODEF 0 "register_operand" "=x")
5305         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5306   "TARGET_SSE2 && TARGET_SSE_MATH
5307    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5308   "#"
5309   [(set_attr "type" "sseicvt")
5310    (set_attr "mode" "<MODE>")
5311    (set_attr "athlon_decode" "direct")
5312    (set_attr "amdfam10_decode" "double")
5313    (set_attr "fp_int_src" "true")])
5314
5315 (define_split
5316   [(set (match_operand:MODEF 0 "register_operand" "")
5317         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5318    (clobber (match_operand:SI 2 "memory_operand" ""))]
5319   "TARGET_SSE2 && TARGET_SSE_MATH
5320    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5321    && reload_completed
5322    && (SSE_REG_P (operands[0])
5323        || (GET_CODE (operands[0]) == SUBREG
5324            && SSE_REG_P (operands[0])))"
5325   [(const_int 0)]
5326 {
5327   rtx op1 = operands[1];
5328
5329   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5330                                      <MODE>mode, 0);
5331   if (GET_CODE (op1) == SUBREG)
5332     op1 = SUBREG_REG (op1);
5333
5334   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5335     {
5336       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5337       emit_insn (gen_sse2_loadld (operands[4],
5338                                   CONST0_RTX (V4SImode), operands[1]));
5339     }
5340   /* We can ignore possible trapping value in the
5341      high part of SSE register for non-trapping math. */
5342   else if (SSE_REG_P (op1) && !flag_trapping_math)
5343     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5344   else
5345     {
5346       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5347       emit_move_insn (operands[2], operands[1]);
5348       emit_insn (gen_sse2_loadld (operands[4],
5349                                   CONST0_RTX (V4SImode), operands[2]));
5350     }
5351   emit_insn
5352     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5353   DONE;
5354 })
5355
5356 (define_split
5357   [(set (match_operand:MODEF 0 "register_operand" "")
5358         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5359    (clobber (match_operand:SI 2 "memory_operand" ""))]
5360   "TARGET_SSE2 && TARGET_SSE_MATH
5361    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5362    && reload_completed
5363    && (SSE_REG_P (operands[0])
5364        || (GET_CODE (operands[0]) == SUBREG
5365            && SSE_REG_P (operands[0])))"
5366   [(const_int 0)]
5367 {
5368   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5369                                      <MODE>mode, 0);
5370   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5371
5372   emit_insn (gen_sse2_loadld (operands[4],
5373                               CONST0_RTX (V4SImode), operands[1]));
5374   emit_insn
5375     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5376   DONE;
5377 })
5378
5379 (define_split
5380   [(set (match_operand:MODEF 0 "register_operand" "")
5381         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5382   "TARGET_SSE2 && TARGET_SSE_MATH
5383    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5384    && reload_completed
5385    && (SSE_REG_P (operands[0])
5386        || (GET_CODE (operands[0]) == SUBREG
5387            && SSE_REG_P (operands[0])))"
5388   [(const_int 0)]
5389 {
5390   rtx op1 = operands[1];
5391
5392   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5393                                      <MODE>mode, 0);
5394   if (GET_CODE (op1) == SUBREG)
5395     op1 = SUBREG_REG (op1);
5396
5397   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5398     {
5399       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5400       emit_insn (gen_sse2_loadld (operands[4],
5401                                   CONST0_RTX (V4SImode), operands[1]));
5402     }
5403   /* We can ignore possible trapping value in the
5404      high part of SSE register for non-trapping math. */
5405   else if (SSE_REG_P (op1) && !flag_trapping_math)
5406     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5407   else
5408     gcc_unreachable ();
5409   emit_insn
5410     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5411   DONE;
5412 })
5413
5414 (define_split
5415   [(set (match_operand:MODEF 0 "register_operand" "")
5416         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5417   "TARGET_SSE2 && TARGET_SSE_MATH
5418    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5419    && reload_completed
5420    && (SSE_REG_P (operands[0])
5421        || (GET_CODE (operands[0]) == SUBREG
5422            && SSE_REG_P (operands[0])))"
5423   [(const_int 0)]
5424 {
5425   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5426                                      <MODE>mode, 0);
5427   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5428
5429   emit_insn (gen_sse2_loadld (operands[4],
5430                               CONST0_RTX (V4SImode), operands[1]));
5431   emit_insn
5432     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5433   DONE;
5434 })
5435
5436 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5437   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5438         (float:MODEF
5439           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5440   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5441   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5442    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5443   "#"
5444   [(set_attr "type" "sseicvt")
5445    (set_attr "mode" "<MODEF:MODE>")
5446    (set_attr "athlon_decode" "double,direct")
5447    (set_attr "amdfam10_decode" "vector,double")
5448    (set_attr "fp_int_src" "true")])
5449
5450 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5451   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5452         (float:MODEF
5453           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5454   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5455    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5456    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5457   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5458   [(set_attr "type" "sseicvt")
5459    (set_attr "prefix" "maybe_vex")
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_split
5466   [(set (match_operand:MODEF 0 "register_operand" "")
5467         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5468    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
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    && reload_completed
5473    && (SSE_REG_P (operands[0])
5474        || (GET_CODE (operands[0]) == SUBREG
5475            && SSE_REG_P (operands[0])))"
5476   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5477   "")
5478
5479 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5480   [(set (match_operand:MODEF 0 "register_operand" "=x")
5481         (float:MODEF
5482           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5483   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5484    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5485    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5486   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5487   [(set_attr "type" "sseicvt")
5488    (set_attr "prefix" "maybe_vex")
5489    (set_attr "mode" "<MODEF:MODE>")
5490    (set_attr "athlon_decode" "direct")
5491    (set_attr "amdfam10_decode" "double")
5492    (set_attr "fp_int_src" "true")])
5493
5494 (define_split
5495   [(set (match_operand:MODEF 0 "register_operand" "")
5496         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5497    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
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    && reload_completed
5502    && (SSE_REG_P (operands[0])
5503        || (GET_CODE (operands[0]) == SUBREG
5504            && SSE_REG_P (operands[0])))"
5505   [(set (match_dup 2) (match_dup 1))
5506    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5507   "")
5508
5509 (define_split
5510   [(set (match_operand:MODEF 0 "register_operand" "")
5511         (float:MODEF (match_operand:SSEMODEI24 1 "memory_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    && reload_completed
5516    && (SSE_REG_P (operands[0])
5517        || (GET_CODE (operands[0]) == SUBREG
5518            && SSE_REG_P (operands[0])))"
5519   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5520   "")
5521
5522 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5523   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5524         (float:X87MODEF
5525           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5526   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5527   "TARGET_80387"
5528   "@
5529    fild%z1\t%1
5530    #"
5531   [(set_attr "type" "fmov,multi")
5532    (set_attr "mode" "<X87MODEF:MODE>")
5533    (set_attr "unit" "*,i387")
5534    (set_attr "fp_int_src" "true")])
5535
5536 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5537   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5538         (float:X87MODEF
5539           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5540   "TARGET_80387"
5541   "fild%z1\t%1"
5542   [(set_attr "type" "fmov")
5543    (set_attr "mode" "<X87MODEF:MODE>")
5544    (set_attr "fp_int_src" "true")])
5545
5546 (define_split
5547   [(set (match_operand:X87MODEF 0 "register_operand" "")
5548         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5549    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5550   "TARGET_80387
5551    && reload_completed
5552    && FP_REG_P (operands[0])"
5553   [(set (match_dup 2) (match_dup 1))
5554    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5555   "")
5556
5557 (define_split
5558   [(set (match_operand:X87MODEF 0 "register_operand" "")
5559         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5560    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5561   "TARGET_80387
5562    && reload_completed
5563    && FP_REG_P (operands[0])"
5564   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5565   "")
5566
5567 ;; Avoid store forwarding (partial memory) stall penalty
5568 ;; by passing DImode value through XMM registers.  */
5569
5570 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5571   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5572         (float:X87MODEF
5573           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5574    (clobber (match_scratch:V4SI 3 "=X,x"))
5575    (clobber (match_scratch:V4SI 4 "=X,x"))
5576    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5577   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5578    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5579   "#"
5580   [(set_attr "type" "multi")
5581    (set_attr "mode" "<X87MODEF:MODE>")
5582    (set_attr "unit" "i387")
5583    (set_attr "fp_int_src" "true")])
5584
5585 (define_split
5586   [(set (match_operand:X87MODEF 0 "register_operand" "")
5587         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5588    (clobber (match_scratch:V4SI 3 ""))
5589    (clobber (match_scratch:V4SI 4 ""))
5590    (clobber (match_operand:DI 2 "memory_operand" ""))]
5591   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5592    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5593    && reload_completed
5594    && FP_REG_P (operands[0])"
5595   [(set (match_dup 2) (match_dup 3))
5596    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5597 {
5598   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5599      Assemble the 64-bit DImode value in an xmm register.  */
5600   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5601                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5602   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5603                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5604   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5605
5606   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5607 })
5608
5609 (define_split
5610   [(set (match_operand:X87MODEF 0 "register_operand" "")
5611         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5612    (clobber (match_scratch:V4SI 3 ""))
5613    (clobber (match_scratch:V4SI 4 ""))
5614    (clobber (match_operand:DI 2 "memory_operand" ""))]
5615   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5616    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5617    && reload_completed
5618    && FP_REG_P (operands[0])"
5619   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5620   "")
5621
5622 ;; Avoid store forwarding (partial memory) stall penalty by extending
5623 ;; SImode value to DImode through XMM register instead of pushing two
5624 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5625 ;; targets benefit from this optimization. Also note that fild
5626 ;; loads from memory only.
5627
5628 (define_insn "*floatunssi<mode>2_1"
5629   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5630         (unsigned_float:X87MODEF
5631           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5632    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5633    (clobber (match_scratch:SI 3 "=X,x"))]
5634   "!TARGET_64BIT
5635    && TARGET_80387 && TARGET_SSE"
5636   "#"
5637   [(set_attr "type" "multi")
5638    (set_attr "mode" "<MODE>")])
5639
5640 (define_split
5641   [(set (match_operand:X87MODEF 0 "register_operand" "")
5642         (unsigned_float:X87MODEF
5643           (match_operand:SI 1 "register_operand" "")))
5644    (clobber (match_operand:DI 2 "memory_operand" ""))
5645    (clobber (match_scratch:SI 3 ""))]
5646   "!TARGET_64BIT
5647    && TARGET_80387 && TARGET_SSE
5648    && reload_completed"
5649   [(set (match_dup 2) (match_dup 1))
5650    (set (match_dup 0)
5651         (float:X87MODEF (match_dup 2)))]
5652   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5653
5654 (define_split
5655   [(set (match_operand:X87MODEF 0 "register_operand" "")
5656         (unsigned_float:X87MODEF
5657           (match_operand:SI 1 "memory_operand" "")))
5658    (clobber (match_operand:DI 2 "memory_operand" ""))
5659    (clobber (match_scratch:SI 3 ""))]
5660   "!TARGET_64BIT
5661    && TARGET_80387 && TARGET_SSE
5662    && reload_completed"
5663   [(set (match_dup 2) (match_dup 3))
5664    (set (match_dup 0)
5665         (float:X87MODEF (match_dup 2)))]
5666 {
5667   emit_move_insn (operands[3], operands[1]);
5668   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5669 })
5670
5671 (define_expand "floatunssi<mode>2"
5672   [(parallel
5673      [(set (match_operand:X87MODEF 0 "register_operand" "")
5674            (unsigned_float:X87MODEF
5675              (match_operand:SI 1 "nonimmediate_operand" "")))
5676       (clobber (match_dup 2))
5677       (clobber (match_scratch:SI 3 ""))])]
5678   "!TARGET_64BIT
5679    && ((TARGET_80387 && TARGET_SSE)
5680        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5681 {
5682   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5683     {
5684       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5685       DONE;
5686     }
5687   else
5688     {
5689       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5690       operands[2] = assign_386_stack_local (DImode, slot);
5691     }
5692 })
5693
5694 (define_expand "floatunsdisf2"
5695   [(use (match_operand:SF 0 "register_operand" ""))
5696    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5697   "TARGET_64BIT && TARGET_SSE_MATH"
5698   "x86_emit_floatuns (operands); DONE;")
5699
5700 (define_expand "floatunsdidf2"
5701   [(use (match_operand:DF 0 "register_operand" ""))
5702    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5703   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5704    && TARGET_SSE2 && TARGET_SSE_MATH"
5705 {
5706   if (TARGET_64BIT)
5707     x86_emit_floatuns (operands);
5708   else
5709     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5710   DONE;
5711 })
5712 \f
5713 ;; Add instructions
5714
5715 ;; %%% splits for addditi3
5716
5717 (define_expand "addti3"
5718   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5719         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5720                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5721   "TARGET_64BIT"
5722   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5723
5724 (define_insn "*addti3_1"
5725   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5726         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5727                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5728    (clobber (reg:CC FLAGS_REG))]
5729   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5730   "#")
5731
5732 (define_split
5733   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5734         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5735                  (match_operand:TI 2 "x86_64_general_operand" "")))
5736    (clobber (reg:CC FLAGS_REG))]
5737   "TARGET_64BIT && reload_completed"
5738   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5739                                           UNSPEC_ADD_CARRY))
5740               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5741    (parallel [(set (match_dup 3)
5742                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5743                                      (match_dup 4))
5744                             (match_dup 5)))
5745               (clobber (reg:CC FLAGS_REG))])]
5746   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5747
5748 ;; %%% splits for addsidi3
5749 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5750 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5751 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5752
5753 (define_expand "adddi3"
5754   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5755         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5756                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5757   ""
5758   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5759
5760 (define_insn "*adddi3_1"
5761   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5762         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5763                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5764    (clobber (reg:CC FLAGS_REG))]
5765   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5766   "#")
5767
5768 (define_split
5769   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5770         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5771                  (match_operand:DI 2 "general_operand" "")))
5772    (clobber (reg:CC FLAGS_REG))]
5773   "!TARGET_64BIT && reload_completed"
5774   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5775                                           UNSPEC_ADD_CARRY))
5776               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5777    (parallel [(set (match_dup 3)
5778                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5779                                      (match_dup 4))
5780                             (match_dup 5)))
5781               (clobber (reg:CC FLAGS_REG))])]
5782   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5783
5784 (define_insn "adddi3_carry_rex64"
5785   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5786           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5787                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5788                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5789    (clobber (reg:CC FLAGS_REG))]
5790   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5791   "adc{q}\t{%2, %0|%0, %2}"
5792   [(set_attr "type" "alu")
5793    (set_attr "pent_pair" "pu")
5794    (set_attr "mode" "DI")])
5795
5796 (define_insn "*adddi3_cc_rex64"
5797   [(set (reg:CC FLAGS_REG)
5798         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5799                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5800                    UNSPEC_ADD_CARRY))
5801    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5802         (plus:DI (match_dup 1) (match_dup 2)))]
5803   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5804   "add{q}\t{%2, %0|%0, %2}"
5805   [(set_attr "type" "alu")
5806    (set_attr "mode" "DI")])
5807
5808 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5809   [(set (reg:CCC FLAGS_REG)
5810         (compare:CCC
5811             (plusminus:SWI
5812                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5813                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5814             (match_dup 1)))
5815    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5816         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5817   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5818   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5819   [(set_attr "type" "alu")
5820    (set_attr "mode" "<MODE>")])
5821
5822 (define_insn "*add<mode>3_cconly_overflow"
5823   [(set (reg:CCC FLAGS_REG)
5824         (compare:CCC
5825                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5826                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5827                 (match_dup 1)))
5828    (clobber (match_scratch:SWI 0 "=<r>"))]
5829   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5830   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5831   [(set_attr "type" "alu")
5832    (set_attr "mode" "<MODE>")])
5833
5834 (define_insn "*sub<mode>3_cconly_overflow"
5835   [(set (reg:CCC FLAGS_REG)
5836         (compare:CCC
5837              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5838                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5839              (match_dup 0)))]
5840   ""
5841   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5842   [(set_attr "type" "icmp")
5843    (set_attr "mode" "<MODE>")])
5844
5845 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5846   [(set (reg:CCC FLAGS_REG)
5847         (compare:CCC
5848             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5849                           (match_operand:SI 2 "general_operand" "g"))
5850             (match_dup 1)))
5851    (set (match_operand:DI 0 "register_operand" "=r")
5852         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5853   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5854   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5855   [(set_attr "type" "alu")
5856    (set_attr "mode" "SI")])
5857
5858 (define_insn "addqi3_carry"
5859   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5860           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5861                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5862                    (match_operand:QI 2 "general_operand" "qn,qm")))
5863    (clobber (reg:CC FLAGS_REG))]
5864   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5865   "adc{b}\t{%2, %0|%0, %2}"
5866   [(set_attr "type" "alu")
5867    (set_attr "pent_pair" "pu")
5868    (set_attr "mode" "QI")])
5869
5870 (define_insn "addhi3_carry"
5871   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5872           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5873                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5874                    (match_operand:HI 2 "general_operand" "rn,rm")))
5875    (clobber (reg:CC FLAGS_REG))]
5876   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5877   "adc{w}\t{%2, %0|%0, %2}"
5878   [(set_attr "type" "alu")
5879    (set_attr "pent_pair" "pu")
5880    (set_attr "mode" "HI")])
5881
5882 (define_insn "addsi3_carry"
5883   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5884           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5885                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5886                    (match_operand:SI 2 "general_operand" "ri,rm")))
5887    (clobber (reg:CC FLAGS_REG))]
5888   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5889   "adc{l}\t{%2, %0|%0, %2}"
5890   [(set_attr "type" "alu")
5891    (set_attr "pent_pair" "pu")
5892    (set_attr "mode" "SI")])
5893
5894 (define_insn "*addsi3_carry_zext"
5895   [(set (match_operand:DI 0 "register_operand" "=r")
5896           (zero_extend:DI
5897             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5898                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5899                      (match_operand:SI 2 "general_operand" "g"))))
5900    (clobber (reg:CC FLAGS_REG))]
5901   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5902   "adc{l}\t{%2, %k0|%k0, %2}"
5903   [(set_attr "type" "alu")
5904    (set_attr "pent_pair" "pu")
5905    (set_attr "mode" "SI")])
5906
5907 (define_insn "*addsi3_cc"
5908   [(set (reg:CC FLAGS_REG)
5909         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5910                     (match_operand:SI 2 "general_operand" "ri,rm")]
5911                    UNSPEC_ADD_CARRY))
5912    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5913         (plus:SI (match_dup 1) (match_dup 2)))]
5914   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5915   "add{l}\t{%2, %0|%0, %2}"
5916   [(set_attr "type" "alu")
5917    (set_attr "mode" "SI")])
5918
5919 (define_insn "addqi3_cc"
5920   [(set (reg:CC FLAGS_REG)
5921         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5922                     (match_operand:QI 2 "general_operand" "qn,qm")]
5923                    UNSPEC_ADD_CARRY))
5924    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5925         (plus:QI (match_dup 1) (match_dup 2)))]
5926   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5927   "add{b}\t{%2, %0|%0, %2}"
5928   [(set_attr "type" "alu")
5929    (set_attr "mode" "QI")])
5930
5931 (define_expand "addsi3"
5932   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5933         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5934                  (match_operand:SI 2 "general_operand" "")))]
5935   ""
5936   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5937
5938 (define_insn "*lea_1"
5939   [(set (match_operand:SI 0 "register_operand" "=r")
5940         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5941   "!TARGET_64BIT"
5942   "lea{l}\t{%a1, %0|%0, %a1}"
5943   [(set_attr "type" "lea")
5944    (set_attr "mode" "SI")])
5945
5946 (define_insn "*lea_1_rex64"
5947   [(set (match_operand:SI 0 "register_operand" "=r")
5948         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5949   "TARGET_64BIT"
5950   "lea{l}\t{%a1, %0|%0, %a1}"
5951   [(set_attr "type" "lea")
5952    (set_attr "mode" "SI")])
5953
5954 (define_insn "*lea_1_zext"
5955   [(set (match_operand:DI 0 "register_operand" "=r")
5956         (zero_extend:DI
5957          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5958   "TARGET_64BIT"
5959   "lea{l}\t{%a1, %k0|%k0, %a1}"
5960   [(set_attr "type" "lea")
5961    (set_attr "mode" "SI")])
5962
5963 (define_insn "*lea_2_rex64"
5964   [(set (match_operand:DI 0 "register_operand" "=r")
5965         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5966   "TARGET_64BIT"
5967   "lea{q}\t{%a1, %0|%0, %a1}"
5968   [(set_attr "type" "lea")
5969    (set_attr "mode" "DI")])
5970
5971 ;; The lea patterns for non-Pmodes needs to be matched by several
5972 ;; insns converted to real lea by splitters.
5973
5974 (define_insn_and_split "*lea_general_1"
5975   [(set (match_operand 0 "register_operand" "=r")
5976         (plus (plus (match_operand 1 "index_register_operand" "l")
5977                     (match_operand 2 "register_operand" "r"))
5978               (match_operand 3 "immediate_operand" "i")))]
5979   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5980     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5981    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5982    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5983    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5984    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5985        || GET_MODE (operands[3]) == VOIDmode)"
5986   "#"
5987   "&& reload_completed"
5988   [(const_int 0)]
5989 {
5990   rtx pat;
5991   operands[0] = gen_lowpart (SImode, operands[0]);
5992   operands[1] = gen_lowpart (Pmode, operands[1]);
5993   operands[2] = gen_lowpart (Pmode, operands[2]);
5994   operands[3] = gen_lowpart (Pmode, operands[3]);
5995   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5996                       operands[3]);
5997   if (Pmode != SImode)
5998     pat = gen_rtx_SUBREG (SImode, pat, 0);
5999   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6000   DONE;
6001 }
6002   [(set_attr "type" "lea")
6003    (set_attr "mode" "SI")])
6004
6005 (define_insn_and_split "*lea_general_1_zext"
6006   [(set (match_operand:DI 0 "register_operand" "=r")
6007         (zero_extend:DI
6008           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6009                             (match_operand:SI 2 "register_operand" "r"))
6010                    (match_operand:SI 3 "immediate_operand" "i"))))]
6011   "TARGET_64BIT"
6012   "#"
6013   "&& reload_completed"
6014   [(set (match_dup 0)
6015         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6016                                                      (match_dup 2))
6017                                             (match_dup 3)) 0)))]
6018 {
6019   operands[1] = gen_lowpart (Pmode, operands[1]);
6020   operands[2] = gen_lowpart (Pmode, operands[2]);
6021   operands[3] = gen_lowpart (Pmode, operands[3]);
6022 }
6023   [(set_attr "type" "lea")
6024    (set_attr "mode" "SI")])
6025
6026 (define_insn_and_split "*lea_general_2"
6027   [(set (match_operand 0 "register_operand" "=r")
6028         (plus (mult (match_operand 1 "index_register_operand" "l")
6029                     (match_operand 2 "const248_operand" "i"))
6030               (match_operand 3 "nonmemory_operand" "ri")))]
6031   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6032     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6033    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6034    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6035    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6036        || GET_MODE (operands[3]) == VOIDmode)"
6037   "#"
6038   "&& reload_completed"
6039   [(const_int 0)]
6040 {
6041   rtx pat;
6042   operands[0] = gen_lowpart (SImode, operands[0]);
6043   operands[1] = gen_lowpart (Pmode, operands[1]);
6044   operands[3] = gen_lowpart (Pmode, operands[3]);
6045   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6046                       operands[3]);
6047   if (Pmode != SImode)
6048     pat = gen_rtx_SUBREG (SImode, pat, 0);
6049   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6050   DONE;
6051 }
6052   [(set_attr "type" "lea")
6053    (set_attr "mode" "SI")])
6054
6055 (define_insn_and_split "*lea_general_2_zext"
6056   [(set (match_operand:DI 0 "register_operand" "=r")
6057         (zero_extend:DI
6058           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6059                             (match_operand:SI 2 "const248_operand" "n"))
6060                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6061   "TARGET_64BIT"
6062   "#"
6063   "&& reload_completed"
6064   [(set (match_dup 0)
6065         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6066                                                      (match_dup 2))
6067                                             (match_dup 3)) 0)))]
6068 {
6069   operands[1] = gen_lowpart (Pmode, operands[1]);
6070   operands[3] = gen_lowpart (Pmode, operands[3]);
6071 }
6072   [(set_attr "type" "lea")
6073    (set_attr "mode" "SI")])
6074
6075 (define_insn_and_split "*lea_general_3"
6076   [(set (match_operand 0 "register_operand" "=r")
6077         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6078                           (match_operand 2 "const248_operand" "i"))
6079                     (match_operand 3 "register_operand" "r"))
6080               (match_operand 4 "immediate_operand" "i")))]
6081   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6082     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6083    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6084    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6085    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6086   "#"
6087   "&& reload_completed"
6088   [(const_int 0)]
6089 {
6090   rtx pat;
6091   operands[0] = gen_lowpart (SImode, operands[0]);
6092   operands[1] = gen_lowpart (Pmode, operands[1]);
6093   operands[3] = gen_lowpart (Pmode, operands[3]);
6094   operands[4] = gen_lowpart (Pmode, operands[4]);
6095   pat = gen_rtx_PLUS (Pmode,
6096                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6097                                                          operands[2]),
6098                                     operands[3]),
6099                       operands[4]);
6100   if (Pmode != SImode)
6101     pat = gen_rtx_SUBREG (SImode, pat, 0);
6102   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6103   DONE;
6104 }
6105   [(set_attr "type" "lea")
6106    (set_attr "mode" "SI")])
6107
6108 (define_insn_and_split "*lea_general_3_zext"
6109   [(set (match_operand:DI 0 "register_operand" "=r")
6110         (zero_extend:DI
6111           (plus:SI (plus:SI (mult:SI
6112                               (match_operand:SI 1 "index_register_operand" "l")
6113                               (match_operand:SI 2 "const248_operand" "n"))
6114                             (match_operand:SI 3 "register_operand" "r"))
6115                    (match_operand:SI 4 "immediate_operand" "i"))))]
6116   "TARGET_64BIT"
6117   "#"
6118   "&& reload_completed"
6119   [(set (match_dup 0)
6120         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6121                                                               (match_dup 2))
6122                                                      (match_dup 3))
6123                                             (match_dup 4)) 0)))]
6124 {
6125   operands[1] = gen_lowpart (Pmode, operands[1]);
6126   operands[3] = gen_lowpart (Pmode, operands[3]);
6127   operands[4] = gen_lowpart (Pmode, operands[4]);
6128 }
6129   [(set_attr "type" "lea")
6130    (set_attr "mode" "SI")])
6131
6132 (define_insn "*adddi_1_rex64"
6133   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6134         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6135                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6136    (clobber (reg:CC FLAGS_REG))]
6137   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6138 {
6139   switch (get_attr_type (insn))
6140     {
6141     case TYPE_LEA:
6142       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6143       return "lea{q}\t{%a2, %0|%0, %a2}";
6144
6145     case TYPE_INCDEC:
6146       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6147       if (operands[2] == const1_rtx)
6148         return "inc{q}\t%0";
6149       else
6150         {
6151           gcc_assert (operands[2] == constm1_rtx);
6152           return "dec{q}\t%0";
6153         }
6154
6155     default:
6156       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6157
6158       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6159          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6160       if (CONST_INT_P (operands[2])
6161           /* Avoid overflows.  */
6162           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6163           && (INTVAL (operands[2]) == 128
6164               || (INTVAL (operands[2]) < 0
6165                   && INTVAL (operands[2]) != -128)))
6166         {
6167           operands[2] = GEN_INT (-INTVAL (operands[2]));
6168           return "sub{q}\t{%2, %0|%0, %2}";
6169         }
6170       return "add{q}\t{%2, %0|%0, %2}";
6171     }
6172 }
6173   [(set (attr "type")
6174      (cond [(eq_attr "alternative" "2")
6175               (const_string "lea")
6176             ; Current assemblers are broken and do not allow @GOTOFF in
6177             ; ought but a memory context.
6178             (match_operand:DI 2 "pic_symbolic_operand" "")
6179               (const_string "lea")
6180             (match_operand:DI 2 "incdec_operand" "")
6181               (const_string "incdec")
6182            ]
6183            (const_string "alu")))
6184    (set_attr "mode" "DI")])
6185
6186 ;; Convert lea to the lea pattern to avoid flags dependency.
6187 (define_split
6188   [(set (match_operand:DI 0 "register_operand" "")
6189         (plus:DI (match_operand:DI 1 "register_operand" "")
6190                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6191    (clobber (reg:CC FLAGS_REG))]
6192   "TARGET_64BIT && reload_completed
6193    && true_regnum (operands[0]) != true_regnum (operands[1])"
6194   [(set (match_dup 0)
6195         (plus:DI (match_dup 1)
6196                  (match_dup 2)))]
6197   "")
6198
6199 (define_insn "*adddi_2_rex64"
6200   [(set (reg FLAGS_REG)
6201         (compare
6202           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6203                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6204           (const_int 0)))
6205    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6206         (plus:DI (match_dup 1) (match_dup 2)))]
6207   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6208    && ix86_binary_operator_ok (PLUS, DImode, operands)
6209    /* Current assemblers are broken and do not allow @GOTOFF in
6210       ought but a memory context.  */
6211    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6212 {
6213   switch (get_attr_type (insn))
6214     {
6215     case TYPE_INCDEC:
6216       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6217       if (operands[2] == const1_rtx)
6218         return "inc{q}\t%0";
6219       else
6220         {
6221           gcc_assert (operands[2] == constm1_rtx);
6222           return "dec{q}\t%0";
6223         }
6224
6225     default:
6226       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6227       /* ???? We ought to handle there the 32bit case too
6228          - do we need new constraint?  */
6229       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6230          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6231       if (CONST_INT_P (operands[2])
6232           /* Avoid overflows.  */
6233           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6234           && (INTVAL (operands[2]) == 128
6235               || (INTVAL (operands[2]) < 0
6236                   && INTVAL (operands[2]) != -128)))
6237         {
6238           operands[2] = GEN_INT (-INTVAL (operands[2]));
6239           return "sub{q}\t{%2, %0|%0, %2}";
6240         }
6241       return "add{q}\t{%2, %0|%0, %2}";
6242     }
6243 }
6244   [(set (attr "type")
6245      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6246         (const_string "incdec")
6247         (const_string "alu")))
6248    (set_attr "mode" "DI")])
6249
6250 (define_insn "*adddi_3_rex64"
6251   [(set (reg FLAGS_REG)
6252         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6253                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6254    (clobber (match_scratch:DI 0 "=r"))]
6255   "TARGET_64BIT
6256    && ix86_match_ccmode (insn, CCZmode)
6257    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6258    /* Current assemblers are broken and do not allow @GOTOFF in
6259       ought but a memory context.  */
6260    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6261 {
6262   switch (get_attr_type (insn))
6263     {
6264     case TYPE_INCDEC:
6265       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6266       if (operands[2] == const1_rtx)
6267         return "inc{q}\t%0";
6268       else
6269         {
6270           gcc_assert (operands[2] == constm1_rtx);
6271           return "dec{q}\t%0";
6272         }
6273
6274     default:
6275       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6276       /* ???? We ought to handle there the 32bit case too
6277          - do we need new constraint?  */
6278       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6279          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6280       if (CONST_INT_P (operands[2])
6281           /* Avoid overflows.  */
6282           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6283           && (INTVAL (operands[2]) == 128
6284               || (INTVAL (operands[2]) < 0
6285                   && INTVAL (operands[2]) != -128)))
6286         {
6287           operands[2] = GEN_INT (-INTVAL (operands[2]));
6288           return "sub{q}\t{%2, %0|%0, %2}";
6289         }
6290       return "add{q}\t{%2, %0|%0, %2}";
6291     }
6292 }
6293   [(set (attr "type")
6294      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6295         (const_string "incdec")
6296         (const_string "alu")))
6297    (set_attr "mode" "DI")])
6298
6299 ; For comparisons against 1, -1 and 128, we may generate better code
6300 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6301 ; is matched then.  We can't accept general immediate, because for
6302 ; case of overflows,  the result is messed up.
6303 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6304 ; when negated.
6305 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6306 ; only for comparisons not depending on it.
6307 (define_insn "*adddi_4_rex64"
6308   [(set (reg FLAGS_REG)
6309         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6310                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6311    (clobber (match_scratch:DI 0 "=rm"))]
6312   "TARGET_64BIT
6313    &&  ix86_match_ccmode (insn, CCGCmode)"
6314 {
6315   switch (get_attr_type (insn))
6316     {
6317     case TYPE_INCDEC:
6318       if (operands[2] == constm1_rtx)
6319         return "inc{q}\t%0";
6320       else
6321         {
6322           gcc_assert (operands[2] == const1_rtx);
6323           return "dec{q}\t%0";
6324         }
6325
6326     default:
6327       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6328       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6329          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6330       if ((INTVAL (operands[2]) == -128
6331            || (INTVAL (operands[2]) > 0
6332                && INTVAL (operands[2]) != 128))
6333           /* Avoid overflows.  */
6334           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6335         return "sub{q}\t{%2, %0|%0, %2}";
6336       operands[2] = GEN_INT (-INTVAL (operands[2]));
6337       return "add{q}\t{%2, %0|%0, %2}";
6338     }
6339 }
6340   [(set (attr "type")
6341      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6342         (const_string "incdec")
6343         (const_string "alu")))
6344    (set_attr "mode" "DI")])
6345
6346 (define_insn "*adddi_5_rex64"
6347   [(set (reg FLAGS_REG)
6348         (compare
6349           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6350                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6351           (const_int 0)))
6352    (clobber (match_scratch:DI 0 "=r"))]
6353   "TARGET_64BIT
6354    && ix86_match_ccmode (insn, CCGOCmode)
6355    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6356    /* Current assemblers are broken and do not allow @GOTOFF in
6357       ought but a memory context.  */
6358    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6359 {
6360   switch (get_attr_type (insn))
6361     {
6362     case TYPE_INCDEC:
6363       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6364       if (operands[2] == const1_rtx)
6365         return "inc{q}\t%0";
6366       else
6367         {
6368           gcc_assert (operands[2] == constm1_rtx);
6369           return "dec{q}\t%0";
6370         }
6371
6372     default:
6373       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6374       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6375          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6376       if (CONST_INT_P (operands[2])
6377           /* Avoid overflows.  */
6378           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6379           && (INTVAL (operands[2]) == 128
6380               || (INTVAL (operands[2]) < 0
6381                   && INTVAL (operands[2]) != -128)))
6382         {
6383           operands[2] = GEN_INT (-INTVAL (operands[2]));
6384           return "sub{q}\t{%2, %0|%0, %2}";
6385         }
6386       return "add{q}\t{%2, %0|%0, %2}";
6387     }
6388 }
6389   [(set (attr "type")
6390      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6391         (const_string "incdec")
6392         (const_string "alu")))
6393    (set_attr "mode" "DI")])
6394
6395
6396 (define_insn "*addsi_1"
6397   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6398         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6399                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6400    (clobber (reg:CC FLAGS_REG))]
6401   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6402 {
6403   switch (get_attr_type (insn))
6404     {
6405     case TYPE_LEA:
6406       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6407       return "lea{l}\t{%a2, %0|%0, %a2}";
6408
6409     case TYPE_INCDEC:
6410       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6411       if (operands[2] == const1_rtx)
6412         return "inc{l}\t%0";
6413       else
6414         {
6415           gcc_assert (operands[2] == constm1_rtx);
6416           return "dec{l}\t%0";
6417         }
6418
6419     default:
6420       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6421
6422       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6423          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6424       if (CONST_INT_P (operands[2])
6425           && (INTVAL (operands[2]) == 128
6426               || (INTVAL (operands[2]) < 0
6427                   && INTVAL (operands[2]) != -128)))
6428         {
6429           operands[2] = GEN_INT (-INTVAL (operands[2]));
6430           return "sub{l}\t{%2, %0|%0, %2}";
6431         }
6432       return "add{l}\t{%2, %0|%0, %2}";
6433     }
6434 }
6435   [(set (attr "type")
6436      (cond [(eq_attr "alternative" "2")
6437               (const_string "lea")
6438             ; Current assemblers are broken and do not allow @GOTOFF in
6439             ; ought but a memory context.
6440             (match_operand:SI 2 "pic_symbolic_operand" "")
6441               (const_string "lea")
6442             (match_operand:SI 2 "incdec_operand" "")
6443               (const_string "incdec")
6444            ]
6445            (const_string "alu")))
6446    (set_attr "mode" "SI")])
6447
6448 ;; Convert lea to the lea pattern to avoid flags dependency.
6449 (define_split
6450   [(set (match_operand 0 "register_operand" "")
6451         (plus (match_operand 1 "register_operand" "")
6452               (match_operand 2 "nonmemory_operand" "")))
6453    (clobber (reg:CC FLAGS_REG))]
6454   "reload_completed
6455    && true_regnum (operands[0]) != true_regnum (operands[1])"
6456   [(const_int 0)]
6457 {
6458   rtx pat;
6459   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6460      may confuse gen_lowpart.  */
6461   if (GET_MODE (operands[0]) != Pmode)
6462     {
6463       operands[1] = gen_lowpart (Pmode, operands[1]);
6464       operands[2] = gen_lowpart (Pmode, operands[2]);
6465     }
6466   operands[0] = gen_lowpart (SImode, operands[0]);
6467   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6468   if (Pmode != SImode)
6469     pat = gen_rtx_SUBREG (SImode, pat, 0);
6470   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6471   DONE;
6472 })
6473
6474 ;; It may seem that nonimmediate operand is proper one for operand 1.
6475 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6476 ;; we take care in ix86_binary_operator_ok to not allow two memory
6477 ;; operands so proper swapping will be done in reload.  This allow
6478 ;; patterns constructed from addsi_1 to match.
6479 (define_insn "addsi_1_zext"
6480   [(set (match_operand:DI 0 "register_operand" "=r,r")
6481         (zero_extend:DI
6482           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6483                    (match_operand:SI 2 "general_operand" "g,li"))))
6484    (clobber (reg:CC FLAGS_REG))]
6485   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6486 {
6487   switch (get_attr_type (insn))
6488     {
6489     case TYPE_LEA:
6490       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6491       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6492
6493     case TYPE_INCDEC:
6494       if (operands[2] == const1_rtx)
6495         return "inc{l}\t%k0";
6496       else
6497         {
6498           gcc_assert (operands[2] == constm1_rtx);
6499           return "dec{l}\t%k0";
6500         }
6501
6502     default:
6503       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6504          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6505       if (CONST_INT_P (operands[2])
6506           && (INTVAL (operands[2]) == 128
6507               || (INTVAL (operands[2]) < 0
6508                   && INTVAL (operands[2]) != -128)))
6509         {
6510           operands[2] = GEN_INT (-INTVAL (operands[2]));
6511           return "sub{l}\t{%2, %k0|%k0, %2}";
6512         }
6513       return "add{l}\t{%2, %k0|%k0, %2}";
6514     }
6515 }
6516   [(set (attr "type")
6517      (cond [(eq_attr "alternative" "1")
6518               (const_string "lea")
6519             ; Current assemblers are broken and do not allow @GOTOFF in
6520             ; ought but a memory context.
6521             (match_operand:SI 2 "pic_symbolic_operand" "")
6522               (const_string "lea")
6523             (match_operand:SI 2 "incdec_operand" "")
6524               (const_string "incdec")
6525            ]
6526            (const_string "alu")))
6527    (set_attr "mode" "SI")])
6528
6529 ;; Convert lea to the lea pattern to avoid flags dependency.
6530 (define_split
6531   [(set (match_operand:DI 0 "register_operand" "")
6532         (zero_extend:DI
6533           (plus:SI (match_operand:SI 1 "register_operand" "")
6534                    (match_operand:SI 2 "nonmemory_operand" ""))))
6535    (clobber (reg:CC FLAGS_REG))]
6536   "TARGET_64BIT && reload_completed
6537    && true_regnum (operands[0]) != true_regnum (operands[1])"
6538   [(set (match_dup 0)
6539         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6540 {
6541   operands[1] = gen_lowpart (Pmode, operands[1]);
6542   operands[2] = gen_lowpart (Pmode, operands[2]);
6543 })
6544
6545 (define_insn "*addsi_2"
6546   [(set (reg FLAGS_REG)
6547         (compare
6548           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6549                    (match_operand:SI 2 "general_operand" "g,ri"))
6550           (const_int 0)))
6551    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6552         (plus:SI (match_dup 1) (match_dup 2)))]
6553   "ix86_match_ccmode (insn, CCGOCmode)
6554    && ix86_binary_operator_ok (PLUS, SImode, operands)
6555    /* Current assemblers are broken and do not allow @GOTOFF in
6556       ought but a memory context.  */
6557    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6558 {
6559   switch (get_attr_type (insn))
6560     {
6561     case TYPE_INCDEC:
6562       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6563       if (operands[2] == const1_rtx)
6564         return "inc{l}\t%0";
6565       else
6566         {
6567           gcc_assert (operands[2] == constm1_rtx);
6568           return "dec{l}\t%0";
6569         }
6570
6571     default:
6572       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6573       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6574          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6575       if (CONST_INT_P (operands[2])
6576           && (INTVAL (operands[2]) == 128
6577               || (INTVAL (operands[2]) < 0
6578                   && INTVAL (operands[2]) != -128)))
6579         {
6580           operands[2] = GEN_INT (-INTVAL (operands[2]));
6581           return "sub{l}\t{%2, %0|%0, %2}";
6582         }
6583       return "add{l}\t{%2, %0|%0, %2}";
6584     }
6585 }
6586   [(set (attr "type")
6587      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6588         (const_string "incdec")
6589         (const_string "alu")))
6590    (set_attr "mode" "SI")])
6591
6592 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6593 (define_insn "*addsi_2_zext"
6594   [(set (reg FLAGS_REG)
6595         (compare
6596           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6597                    (match_operand:SI 2 "general_operand" "g"))
6598           (const_int 0)))
6599    (set (match_operand:DI 0 "register_operand" "=r")
6600         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6601   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6602    && ix86_binary_operator_ok (PLUS, SImode, operands)
6603    /* Current assemblers are broken and do not allow @GOTOFF in
6604       ought but a memory context.  */
6605    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6606 {
6607   switch (get_attr_type (insn))
6608     {
6609     case TYPE_INCDEC:
6610       if (operands[2] == const1_rtx)
6611         return "inc{l}\t%k0";
6612       else
6613         {
6614           gcc_assert (operands[2] == constm1_rtx);
6615           return "dec{l}\t%k0";
6616         }
6617
6618     default:
6619       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6620          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6621       if (CONST_INT_P (operands[2])
6622           && (INTVAL (operands[2]) == 128
6623               || (INTVAL (operands[2]) < 0
6624                   && INTVAL (operands[2]) != -128)))
6625         {
6626           operands[2] = GEN_INT (-INTVAL (operands[2]));
6627           return "sub{l}\t{%2, %k0|%k0, %2}";
6628         }
6629       return "add{l}\t{%2, %k0|%k0, %2}";
6630     }
6631 }
6632   [(set (attr "type")
6633      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6634         (const_string "incdec")
6635         (const_string "alu")))
6636    (set_attr "mode" "SI")])
6637
6638 (define_insn "*addsi_3"
6639   [(set (reg FLAGS_REG)
6640         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6641                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6642    (clobber (match_scratch:SI 0 "=r"))]
6643   "ix86_match_ccmode (insn, CCZmode)
6644    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6645    /* Current assemblers are broken and do not allow @GOTOFF in
6646       ought but a memory context.  */
6647    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6648 {
6649   switch (get_attr_type (insn))
6650     {
6651     case TYPE_INCDEC:
6652       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6653       if (operands[2] == const1_rtx)
6654         return "inc{l}\t%0";
6655       else
6656         {
6657           gcc_assert (operands[2] == constm1_rtx);
6658           return "dec{l}\t%0";
6659         }
6660
6661     default:
6662       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6663       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6664          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6665       if (CONST_INT_P (operands[2])
6666           && (INTVAL (operands[2]) == 128
6667               || (INTVAL (operands[2]) < 0
6668                   && INTVAL (operands[2]) != -128)))
6669         {
6670           operands[2] = GEN_INT (-INTVAL (operands[2]));
6671           return "sub{l}\t{%2, %0|%0, %2}";
6672         }
6673       return "add{l}\t{%2, %0|%0, %2}";
6674     }
6675 }
6676   [(set (attr "type")
6677      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6678         (const_string "incdec")
6679         (const_string "alu")))
6680    (set_attr "mode" "SI")])
6681
6682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6683 (define_insn "*addsi_3_zext"
6684   [(set (reg FLAGS_REG)
6685         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6686                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6687    (set (match_operand:DI 0 "register_operand" "=r")
6688         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6689   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6690    && ix86_binary_operator_ok (PLUS, SImode, operands)
6691    /* Current assemblers are broken and do not allow @GOTOFF in
6692       ought but a memory context.  */
6693    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6694 {
6695   switch (get_attr_type (insn))
6696     {
6697     case TYPE_INCDEC:
6698       if (operands[2] == const1_rtx)
6699         return "inc{l}\t%k0";
6700       else
6701         {
6702           gcc_assert (operands[2] == constm1_rtx);
6703           return "dec{l}\t%k0";
6704         }
6705
6706     default:
6707       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6708          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6709       if (CONST_INT_P (operands[2])
6710           && (INTVAL (operands[2]) == 128
6711               || (INTVAL (operands[2]) < 0
6712                   && INTVAL (operands[2]) != -128)))
6713         {
6714           operands[2] = GEN_INT (-INTVAL (operands[2]));
6715           return "sub{l}\t{%2, %k0|%k0, %2}";
6716         }
6717       return "add{l}\t{%2, %k0|%k0, %2}";
6718     }
6719 }
6720   [(set (attr "type")
6721      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6722         (const_string "incdec")
6723         (const_string "alu")))
6724    (set_attr "mode" "SI")])
6725
6726 ; For comparisons against 1, -1 and 128, we may generate better code
6727 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6728 ; is matched then.  We can't accept general immediate, because for
6729 ; case of overflows,  the result is messed up.
6730 ; This pattern also don't hold of 0x80000000, since the value overflows
6731 ; when negated.
6732 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6733 ; only for comparisons not depending on it.
6734 (define_insn "*addsi_4"
6735   [(set (reg FLAGS_REG)
6736         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6737                  (match_operand:SI 2 "const_int_operand" "n")))
6738    (clobber (match_scratch:SI 0 "=rm"))]
6739   "ix86_match_ccmode (insn, CCGCmode)
6740    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6741 {
6742   switch (get_attr_type (insn))
6743     {
6744     case TYPE_INCDEC:
6745       if (operands[2] == constm1_rtx)
6746         return "inc{l}\t%0";
6747       else
6748         {
6749           gcc_assert (operands[2] == const1_rtx);
6750           return "dec{l}\t%0";
6751         }
6752
6753     default:
6754       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6755       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6756          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6757       if ((INTVAL (operands[2]) == -128
6758            || (INTVAL (operands[2]) > 0
6759                && INTVAL (operands[2]) != 128)))
6760         return "sub{l}\t{%2, %0|%0, %2}";
6761       operands[2] = GEN_INT (-INTVAL (operands[2]));
6762       return "add{l}\t{%2, %0|%0, %2}";
6763     }
6764 }
6765   [(set (attr "type")
6766      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6767         (const_string "incdec")
6768         (const_string "alu")))
6769    (set_attr "mode" "SI")])
6770
6771 (define_insn "*addsi_5"
6772   [(set (reg FLAGS_REG)
6773         (compare
6774           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6775                    (match_operand:SI 2 "general_operand" "g"))
6776           (const_int 0)))
6777    (clobber (match_scratch:SI 0 "=r"))]
6778   "ix86_match_ccmode (insn, CCGOCmode)
6779    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6780    /* Current assemblers are broken and do not allow @GOTOFF in
6781       ought but a memory context.  */
6782    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6783 {
6784   switch (get_attr_type (insn))
6785     {
6786     case TYPE_INCDEC:
6787       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6788       if (operands[2] == const1_rtx)
6789         return "inc{l}\t%0";
6790       else
6791         {
6792           gcc_assert (operands[2] == constm1_rtx);
6793           return "dec{l}\t%0";
6794         }
6795
6796     default:
6797       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6798       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6799          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6800       if (CONST_INT_P (operands[2])
6801           && (INTVAL (operands[2]) == 128
6802               || (INTVAL (operands[2]) < 0
6803                   && INTVAL (operands[2]) != -128)))
6804         {
6805           operands[2] = GEN_INT (-INTVAL (operands[2]));
6806           return "sub{l}\t{%2, %0|%0, %2}";
6807         }
6808       return "add{l}\t{%2, %0|%0, %2}";
6809     }
6810 }
6811   [(set (attr "type")
6812      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6813         (const_string "incdec")
6814         (const_string "alu")))
6815    (set_attr "mode" "SI")])
6816
6817 (define_expand "addhi3"
6818   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6819         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6820                  (match_operand:HI 2 "general_operand" "")))]
6821   "TARGET_HIMODE_MATH"
6822   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6823
6824 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6825 ;; type optimizations enabled by define-splits.  This is not important
6826 ;; for PII, and in fact harmful because of partial register stalls.
6827
6828 (define_insn "*addhi_1_lea"
6829   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6830         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6831                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6832    (clobber (reg:CC FLAGS_REG))]
6833   "!TARGET_PARTIAL_REG_STALL
6834    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6835 {
6836   switch (get_attr_type (insn))
6837     {
6838     case TYPE_LEA:
6839       return "#";
6840     case TYPE_INCDEC:
6841       if (operands[2] == const1_rtx)
6842         return "inc{w}\t%0";
6843       else
6844         {
6845           gcc_assert (operands[2] == constm1_rtx);
6846           return "dec{w}\t%0";
6847         }
6848
6849     default:
6850       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6851          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6852       if (CONST_INT_P (operands[2])
6853           && (INTVAL (operands[2]) == 128
6854               || (INTVAL (operands[2]) < 0
6855                   && INTVAL (operands[2]) != -128)))
6856         {
6857           operands[2] = GEN_INT (-INTVAL (operands[2]));
6858           return "sub{w}\t{%2, %0|%0, %2}";
6859         }
6860       return "add{w}\t{%2, %0|%0, %2}";
6861     }
6862 }
6863   [(set (attr "type")
6864      (if_then_else (eq_attr "alternative" "2")
6865         (const_string "lea")
6866         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6867            (const_string "incdec")
6868            (const_string "alu"))))
6869    (set_attr "mode" "HI,HI,SI")])
6870
6871 (define_insn "*addhi_1"
6872   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6873         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6874                  (match_operand:HI 2 "general_operand" "rn,rm")))
6875    (clobber (reg:CC FLAGS_REG))]
6876   "TARGET_PARTIAL_REG_STALL
6877    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6878 {
6879   switch (get_attr_type (insn))
6880     {
6881     case TYPE_INCDEC:
6882       if (operands[2] == const1_rtx)
6883         return "inc{w}\t%0";
6884       else
6885         {
6886           gcc_assert (operands[2] == constm1_rtx);
6887           return "dec{w}\t%0";
6888         }
6889
6890     default:
6891       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6892          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6893       if (CONST_INT_P (operands[2])
6894           && (INTVAL (operands[2]) == 128
6895               || (INTVAL (operands[2]) < 0
6896                   && INTVAL (operands[2]) != -128)))
6897         {
6898           operands[2] = GEN_INT (-INTVAL (operands[2]));
6899           return "sub{w}\t{%2, %0|%0, %2}";
6900         }
6901       return "add{w}\t{%2, %0|%0, %2}";
6902     }
6903 }
6904   [(set (attr "type")
6905      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6906         (const_string "incdec")
6907         (const_string "alu")))
6908    (set_attr "mode" "HI")])
6909
6910 (define_insn "*addhi_2"
6911   [(set (reg FLAGS_REG)
6912         (compare
6913           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6914                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6915           (const_int 0)))
6916    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6917         (plus:HI (match_dup 1) (match_dup 2)))]
6918   "ix86_match_ccmode (insn, CCGOCmode)
6919    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6920 {
6921   switch (get_attr_type (insn))
6922     {
6923     case TYPE_INCDEC:
6924       if (operands[2] == const1_rtx)
6925         return "inc{w}\t%0";
6926       else
6927         {
6928           gcc_assert (operands[2] == constm1_rtx);
6929           return "dec{w}\t%0";
6930         }
6931
6932     default:
6933       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6934          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6935       if (CONST_INT_P (operands[2])
6936           && (INTVAL (operands[2]) == 128
6937               || (INTVAL (operands[2]) < 0
6938                   && INTVAL (operands[2]) != -128)))
6939         {
6940           operands[2] = GEN_INT (-INTVAL (operands[2]));
6941           return "sub{w}\t{%2, %0|%0, %2}";
6942         }
6943       return "add{w}\t{%2, %0|%0, %2}";
6944     }
6945 }
6946   [(set (attr "type")
6947      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6948         (const_string "incdec")
6949         (const_string "alu")))
6950    (set_attr "mode" "HI")])
6951
6952 (define_insn "*addhi_3"
6953   [(set (reg FLAGS_REG)
6954         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6955                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6956    (clobber (match_scratch:HI 0 "=r"))]
6957   "ix86_match_ccmode (insn, CCZmode)
6958    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6959 {
6960   switch (get_attr_type (insn))
6961     {
6962     case TYPE_INCDEC:
6963       if (operands[2] == const1_rtx)
6964         return "inc{w}\t%0";
6965       else
6966         {
6967           gcc_assert (operands[2] == constm1_rtx);
6968           return "dec{w}\t%0";
6969         }
6970
6971     default:
6972       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6973          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6974       if (CONST_INT_P (operands[2])
6975           && (INTVAL (operands[2]) == 128
6976               || (INTVAL (operands[2]) < 0
6977                   && INTVAL (operands[2]) != -128)))
6978         {
6979           operands[2] = GEN_INT (-INTVAL (operands[2]));
6980           return "sub{w}\t{%2, %0|%0, %2}";
6981         }
6982       return "add{w}\t{%2, %0|%0, %2}";
6983     }
6984 }
6985   [(set (attr "type")
6986      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6987         (const_string "incdec")
6988         (const_string "alu")))
6989    (set_attr "mode" "HI")])
6990
6991 ; See comments above addsi_4 for details.
6992 (define_insn "*addhi_4"
6993   [(set (reg FLAGS_REG)
6994         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6995                  (match_operand:HI 2 "const_int_operand" "n")))
6996    (clobber (match_scratch:HI 0 "=rm"))]
6997   "ix86_match_ccmode (insn, CCGCmode)
6998    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6999 {
7000   switch (get_attr_type (insn))
7001     {
7002     case TYPE_INCDEC:
7003       if (operands[2] == constm1_rtx)
7004         return "inc{w}\t%0";
7005       else
7006         {
7007           gcc_assert (operands[2] == const1_rtx);
7008           return "dec{w}\t%0";
7009         }
7010
7011     default:
7012       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7013       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7014          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7015       if ((INTVAL (operands[2]) == -128
7016            || (INTVAL (operands[2]) > 0
7017                && INTVAL (operands[2]) != 128)))
7018         return "sub{w}\t{%2, %0|%0, %2}";
7019       operands[2] = GEN_INT (-INTVAL (operands[2]));
7020       return "add{w}\t{%2, %0|%0, %2}";
7021     }
7022 }
7023   [(set (attr "type")
7024      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7025         (const_string "incdec")
7026         (const_string "alu")))
7027    (set_attr "mode" "SI")])
7028
7029
7030 (define_insn "*addhi_5"
7031   [(set (reg FLAGS_REG)
7032         (compare
7033           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7034                    (match_operand:HI 2 "general_operand" "rmn"))
7035           (const_int 0)))
7036    (clobber (match_scratch:HI 0 "=r"))]
7037   "ix86_match_ccmode (insn, CCGOCmode)
7038    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7039 {
7040   switch (get_attr_type (insn))
7041     {
7042     case TYPE_INCDEC:
7043       if (operands[2] == const1_rtx)
7044         return "inc{w}\t%0";
7045       else
7046         {
7047           gcc_assert (operands[2] == constm1_rtx);
7048           return "dec{w}\t%0";
7049         }
7050
7051     default:
7052       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7053          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7054       if (CONST_INT_P (operands[2])
7055           && (INTVAL (operands[2]) == 128
7056               || (INTVAL (operands[2]) < 0
7057                   && INTVAL (operands[2]) != -128)))
7058         {
7059           operands[2] = GEN_INT (-INTVAL (operands[2]));
7060           return "sub{w}\t{%2, %0|%0, %2}";
7061         }
7062       return "add{w}\t{%2, %0|%0, %2}";
7063     }
7064 }
7065   [(set (attr "type")
7066      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7067         (const_string "incdec")
7068         (const_string "alu")))
7069    (set_attr "mode" "HI")])
7070
7071 (define_expand "addqi3"
7072   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7073         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7074                  (match_operand:QI 2 "general_operand" "")))]
7075   "TARGET_QIMODE_MATH"
7076   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7077
7078 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7079 (define_insn "*addqi_1_lea"
7080   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7081         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7082                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7083    (clobber (reg:CC FLAGS_REG))]
7084   "!TARGET_PARTIAL_REG_STALL
7085    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7086 {
7087   int widen = (which_alternative == 2);
7088   switch (get_attr_type (insn))
7089     {
7090     case TYPE_LEA:
7091       return "#";
7092     case TYPE_INCDEC:
7093       if (operands[2] == const1_rtx)
7094         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7095       else
7096         {
7097           gcc_assert (operands[2] == constm1_rtx);
7098           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7099         }
7100
7101     default:
7102       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7103          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7104       if (CONST_INT_P (operands[2])
7105           && (INTVAL (operands[2]) == 128
7106               || (INTVAL (operands[2]) < 0
7107                   && INTVAL (operands[2]) != -128)))
7108         {
7109           operands[2] = GEN_INT (-INTVAL (operands[2]));
7110           if (widen)
7111             return "sub{l}\t{%2, %k0|%k0, %2}";
7112           else
7113             return "sub{b}\t{%2, %0|%0, %2}";
7114         }
7115       if (widen)
7116         return "add{l}\t{%k2, %k0|%k0, %k2}";
7117       else
7118         return "add{b}\t{%2, %0|%0, %2}";
7119     }
7120 }
7121   [(set (attr "type")
7122      (if_then_else (eq_attr "alternative" "3")
7123         (const_string "lea")
7124         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7125            (const_string "incdec")
7126            (const_string "alu"))))
7127    (set_attr "mode" "QI,QI,SI,SI")])
7128
7129 (define_insn "*addqi_1"
7130   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7131         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7132                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7133    (clobber (reg:CC FLAGS_REG))]
7134   "TARGET_PARTIAL_REG_STALL
7135    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7136 {
7137   int widen = (which_alternative == 2);
7138   switch (get_attr_type (insn))
7139     {
7140     case TYPE_INCDEC:
7141       if (operands[2] == const1_rtx)
7142         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7143       else
7144         {
7145           gcc_assert (operands[2] == constm1_rtx);
7146           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7147         }
7148
7149     default:
7150       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7151          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7152       if (CONST_INT_P (operands[2])
7153           && (INTVAL (operands[2]) == 128
7154               || (INTVAL (operands[2]) < 0
7155                   && INTVAL (operands[2]) != -128)))
7156         {
7157           operands[2] = GEN_INT (-INTVAL (operands[2]));
7158           if (widen)
7159             return "sub{l}\t{%2, %k0|%k0, %2}";
7160           else
7161             return "sub{b}\t{%2, %0|%0, %2}";
7162         }
7163       if (widen)
7164         return "add{l}\t{%k2, %k0|%k0, %k2}";
7165       else
7166         return "add{b}\t{%2, %0|%0, %2}";
7167     }
7168 }
7169   [(set (attr "type")
7170      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7171         (const_string "incdec")
7172         (const_string "alu")))
7173    (set_attr "mode" "QI,QI,SI")])
7174
7175 (define_insn "*addqi_1_slp"
7176   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7177         (plus:QI (match_dup 0)
7178                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7179    (clobber (reg:CC FLAGS_REG))]
7180   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7181    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7182 {
7183   switch (get_attr_type (insn))
7184     {
7185     case TYPE_INCDEC:
7186       if (operands[1] == const1_rtx)
7187         return "inc{b}\t%0";
7188       else
7189         {
7190           gcc_assert (operands[1] == constm1_rtx);
7191           return "dec{b}\t%0";
7192         }
7193
7194     default:
7195       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7196       if (CONST_INT_P (operands[1])
7197           && INTVAL (operands[1]) < 0)
7198         {
7199           operands[1] = GEN_INT (-INTVAL (operands[1]));
7200           return "sub{b}\t{%1, %0|%0, %1}";
7201         }
7202       return "add{b}\t{%1, %0|%0, %1}";
7203     }
7204 }
7205   [(set (attr "type")
7206      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7207         (const_string "incdec")
7208         (const_string "alu1")))
7209    (set (attr "memory")
7210      (if_then_else (match_operand 1 "memory_operand" "")
7211         (const_string "load")
7212         (const_string "none")))
7213    (set_attr "mode" "QI")])
7214
7215 (define_insn "*addqi_2"
7216   [(set (reg FLAGS_REG)
7217         (compare
7218           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7219                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7220           (const_int 0)))
7221    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7222         (plus:QI (match_dup 1) (match_dup 2)))]
7223   "ix86_match_ccmode (insn, CCGOCmode)
7224    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7225 {
7226   switch (get_attr_type (insn))
7227     {
7228     case TYPE_INCDEC:
7229       if (operands[2] == const1_rtx)
7230         return "inc{b}\t%0";
7231       else
7232         {
7233           gcc_assert (operands[2] == constm1_rtx
7234                       || (CONST_INT_P (operands[2])
7235                           && INTVAL (operands[2]) == 255));
7236           return "dec{b}\t%0";
7237         }
7238
7239     default:
7240       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7241       if (CONST_INT_P (operands[2])
7242           && INTVAL (operands[2]) < 0)
7243         {
7244           operands[2] = GEN_INT (-INTVAL (operands[2]));
7245           return "sub{b}\t{%2, %0|%0, %2}";
7246         }
7247       return "add{b}\t{%2, %0|%0, %2}";
7248     }
7249 }
7250   [(set (attr "type")
7251      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7252         (const_string "incdec")
7253         (const_string "alu")))
7254    (set_attr "mode" "QI")])
7255
7256 (define_insn "*addqi_3"
7257   [(set (reg FLAGS_REG)
7258         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7259                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7260    (clobber (match_scratch:QI 0 "=q"))]
7261   "ix86_match_ccmode (insn, CCZmode)
7262    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7263 {
7264   switch (get_attr_type (insn))
7265     {
7266     case TYPE_INCDEC:
7267       if (operands[2] == const1_rtx)
7268         return "inc{b}\t%0";
7269       else
7270         {
7271           gcc_assert (operands[2] == constm1_rtx
7272                       || (CONST_INT_P (operands[2])
7273                           && INTVAL (operands[2]) == 255));
7274           return "dec{b}\t%0";
7275         }
7276
7277     default:
7278       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7279       if (CONST_INT_P (operands[2])
7280           && INTVAL (operands[2]) < 0)
7281         {
7282           operands[2] = GEN_INT (-INTVAL (operands[2]));
7283           return "sub{b}\t{%2, %0|%0, %2}";
7284         }
7285       return "add{b}\t{%2, %0|%0, %2}";
7286     }
7287 }
7288   [(set (attr "type")
7289      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7290         (const_string "incdec")
7291         (const_string "alu")))
7292    (set_attr "mode" "QI")])
7293
7294 ; See comments above addsi_4 for details.
7295 (define_insn "*addqi_4"
7296   [(set (reg FLAGS_REG)
7297         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7298                  (match_operand:QI 2 "const_int_operand" "n")))
7299    (clobber (match_scratch:QI 0 "=qm"))]
7300   "ix86_match_ccmode (insn, CCGCmode)
7301    && (INTVAL (operands[2]) & 0xff) != 0x80"
7302 {
7303   switch (get_attr_type (insn))
7304     {
7305     case TYPE_INCDEC:
7306       if (operands[2] == constm1_rtx
7307           || (CONST_INT_P (operands[2])
7308               && INTVAL (operands[2]) == 255))
7309         return "inc{b}\t%0";
7310       else
7311         {
7312           gcc_assert (operands[2] == const1_rtx);
7313           return "dec{b}\t%0";
7314         }
7315
7316     default:
7317       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7318       if (INTVAL (operands[2]) < 0)
7319         {
7320           operands[2] = GEN_INT (-INTVAL (operands[2]));
7321           return "add{b}\t{%2, %0|%0, %2}";
7322         }
7323       return "sub{b}\t{%2, %0|%0, %2}";
7324     }
7325 }
7326   [(set (attr "type")
7327      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7328         (const_string "incdec")
7329         (const_string "alu")))
7330    (set_attr "mode" "QI")])
7331
7332
7333 (define_insn "*addqi_5"
7334   [(set (reg FLAGS_REG)
7335         (compare
7336           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7337                    (match_operand:QI 2 "general_operand" "qmn"))
7338           (const_int 0)))
7339    (clobber (match_scratch:QI 0 "=q"))]
7340   "ix86_match_ccmode (insn, CCGOCmode)
7341    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7342 {
7343   switch (get_attr_type (insn))
7344     {
7345     case TYPE_INCDEC:
7346       if (operands[2] == const1_rtx)
7347         return "inc{b}\t%0";
7348       else
7349         {
7350           gcc_assert (operands[2] == constm1_rtx
7351                       || (CONST_INT_P (operands[2])
7352                           && INTVAL (operands[2]) == 255));
7353           return "dec{b}\t%0";
7354         }
7355
7356     default:
7357       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7358       if (CONST_INT_P (operands[2])
7359           && INTVAL (operands[2]) < 0)
7360         {
7361           operands[2] = GEN_INT (-INTVAL (operands[2]));
7362           return "sub{b}\t{%2, %0|%0, %2}";
7363         }
7364       return "add{b}\t{%2, %0|%0, %2}";
7365     }
7366 }
7367   [(set (attr "type")
7368      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7369         (const_string "incdec")
7370         (const_string "alu")))
7371    (set_attr "mode" "QI")])
7372
7373
7374 (define_insn "addqi_ext_1"
7375   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7376                          (const_int 8)
7377                          (const_int 8))
7378         (plus:SI
7379           (zero_extract:SI
7380             (match_operand 1 "ext_register_operand" "0")
7381             (const_int 8)
7382             (const_int 8))
7383           (match_operand:QI 2 "general_operand" "Qmn")))
7384    (clobber (reg:CC FLAGS_REG))]
7385   "!TARGET_64BIT"
7386 {
7387   switch (get_attr_type (insn))
7388     {
7389     case TYPE_INCDEC:
7390       if (operands[2] == const1_rtx)
7391         return "inc{b}\t%h0";
7392       else
7393         {
7394           gcc_assert (operands[2] == constm1_rtx
7395                       || (CONST_INT_P (operands[2])
7396                           && INTVAL (operands[2]) == 255));
7397           return "dec{b}\t%h0";
7398         }
7399
7400     default:
7401       return "add{b}\t{%2, %h0|%h0, %2}";
7402     }
7403 }
7404   [(set (attr "type")
7405      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7406         (const_string "incdec")
7407         (const_string "alu")))
7408    (set_attr "mode" "QI")])
7409
7410 (define_insn "*addqi_ext_1_rex64"
7411   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7412                          (const_int 8)
7413                          (const_int 8))
7414         (plus:SI
7415           (zero_extract:SI
7416             (match_operand 1 "ext_register_operand" "0")
7417             (const_int 8)
7418             (const_int 8))
7419           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7420    (clobber (reg:CC FLAGS_REG))]
7421   "TARGET_64BIT"
7422 {
7423   switch (get_attr_type (insn))
7424     {
7425     case TYPE_INCDEC:
7426       if (operands[2] == const1_rtx)
7427         return "inc{b}\t%h0";
7428       else
7429         {
7430           gcc_assert (operands[2] == constm1_rtx
7431                       || (CONST_INT_P (operands[2])
7432                           && INTVAL (operands[2]) == 255));
7433           return "dec{b}\t%h0";
7434         }
7435
7436     default:
7437       return "add{b}\t{%2, %h0|%h0, %2}";
7438     }
7439 }
7440   [(set (attr "type")
7441      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7442         (const_string "incdec")
7443         (const_string "alu")))
7444    (set_attr "mode" "QI")])
7445
7446 (define_insn "*addqi_ext_2"
7447   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7448                          (const_int 8)
7449                          (const_int 8))
7450         (plus:SI
7451           (zero_extract:SI
7452             (match_operand 1 "ext_register_operand" "%0")
7453             (const_int 8)
7454             (const_int 8))
7455           (zero_extract:SI
7456             (match_operand 2 "ext_register_operand" "Q")
7457             (const_int 8)
7458             (const_int 8))))
7459    (clobber (reg:CC FLAGS_REG))]
7460   ""
7461   "add{b}\t{%h2, %h0|%h0, %h2}"
7462   [(set_attr "type" "alu")
7463    (set_attr "mode" "QI")])
7464
7465 ;; The patterns that match these are at the end of this file.
7466
7467 (define_expand "addxf3"
7468   [(set (match_operand:XF 0 "register_operand" "")
7469         (plus:XF (match_operand:XF 1 "register_operand" "")
7470                  (match_operand:XF 2 "register_operand" "")))]
7471   "TARGET_80387"
7472   "")
7473
7474 (define_expand "add<mode>3"
7475   [(set (match_operand:MODEF 0 "register_operand" "")
7476         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7477                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7478   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7479   "")
7480 \f
7481 ;; Subtract instructions
7482
7483 ;; %%% splits for subditi3
7484
7485 (define_expand "subti3"
7486   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7487         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7488                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7489   "TARGET_64BIT"
7490   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7491
7492 (define_insn "*subti3_1"
7493   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7494         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7495                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7496    (clobber (reg:CC FLAGS_REG))]
7497   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7498   "#")
7499
7500 (define_split
7501   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7502         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7503                   (match_operand:TI 2 "x86_64_general_operand" "")))
7504    (clobber (reg:CC FLAGS_REG))]
7505   "TARGET_64BIT && reload_completed"
7506   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7507               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7508    (parallel [(set (match_dup 3)
7509                    (minus:DI (match_dup 4)
7510                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7511                                       (match_dup 5))))
7512               (clobber (reg:CC FLAGS_REG))])]
7513   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7514
7515 ;; %%% splits for subsidi3
7516
7517 (define_expand "subdi3"
7518   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7519         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7520                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7521   ""
7522   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7523
7524 (define_insn "*subdi3_1"
7525   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7526         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7527                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7528    (clobber (reg:CC FLAGS_REG))]
7529   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7530   "#")
7531
7532 (define_split
7533   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7534         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7535                   (match_operand:DI 2 "general_operand" "")))
7536    (clobber (reg:CC FLAGS_REG))]
7537   "!TARGET_64BIT && reload_completed"
7538   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7539               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7540    (parallel [(set (match_dup 3)
7541                    (minus:SI (match_dup 4)
7542                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7543                                       (match_dup 5))))
7544               (clobber (reg:CC FLAGS_REG))])]
7545   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7546
7547 (define_insn "subdi3_carry_rex64"
7548   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7549           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7550             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7551                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7552    (clobber (reg:CC FLAGS_REG))]
7553   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7554   "sbb{q}\t{%2, %0|%0, %2}"
7555   [(set_attr "type" "alu")
7556    (set_attr "pent_pair" "pu")
7557    (set_attr "mode" "DI")])
7558
7559 (define_insn "*subdi_1_rex64"
7560   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7561         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7562                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7565   "sub{q}\t{%2, %0|%0, %2}"
7566   [(set_attr "type" "alu")
7567    (set_attr "mode" "DI")])
7568
7569 (define_insn "*subdi_2_rex64"
7570   [(set (reg FLAGS_REG)
7571         (compare
7572           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7573                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7574           (const_int 0)))
7575    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7576         (minus:DI (match_dup 1) (match_dup 2)))]
7577   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7578    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7579   "sub{q}\t{%2, %0|%0, %2}"
7580   [(set_attr "type" "alu")
7581    (set_attr "mode" "DI")])
7582
7583 (define_insn "*subdi_3_rex63"
7584   [(set (reg FLAGS_REG)
7585         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7586                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7587    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7588         (minus:DI (match_dup 1) (match_dup 2)))]
7589   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7590    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7591   "sub{q}\t{%2, %0|%0, %2}"
7592   [(set_attr "type" "alu")
7593    (set_attr "mode" "DI")])
7594
7595 (define_insn "subqi3_carry"
7596   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7597           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7598             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7599                (match_operand:QI 2 "general_operand" "qn,qm"))))
7600    (clobber (reg:CC FLAGS_REG))]
7601   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7602   "sbb{b}\t{%2, %0|%0, %2}"
7603   [(set_attr "type" "alu")
7604    (set_attr "pent_pair" "pu")
7605    (set_attr "mode" "QI")])
7606
7607 (define_insn "subhi3_carry"
7608   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7609           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7610             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7611                (match_operand:HI 2 "general_operand" "rn,rm"))))
7612    (clobber (reg:CC FLAGS_REG))]
7613   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7614   "sbb{w}\t{%2, %0|%0, %2}"
7615   [(set_attr "type" "alu")
7616    (set_attr "pent_pair" "pu")
7617    (set_attr "mode" "HI")])
7618
7619 (define_insn "subsi3_carry"
7620   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7621           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7622             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7623                (match_operand:SI 2 "general_operand" "ri,rm"))))
7624    (clobber (reg:CC FLAGS_REG))]
7625   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7626   "sbb{l}\t{%2, %0|%0, %2}"
7627   [(set_attr "type" "alu")
7628    (set_attr "pent_pair" "pu")
7629    (set_attr "mode" "SI")])
7630
7631 (define_insn "subsi3_carry_zext"
7632   [(set (match_operand:DI 0 "register_operand" "=r")
7633           (zero_extend:DI
7634             (minus:SI (match_operand:SI 1 "register_operand" "0")
7635               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7636                  (match_operand:SI 2 "general_operand" "g")))))
7637    (clobber (reg:CC FLAGS_REG))]
7638   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7639   "sbb{l}\t{%2, %k0|%k0, %2}"
7640   [(set_attr "type" "alu")
7641    (set_attr "pent_pair" "pu")
7642    (set_attr "mode" "SI")])
7643
7644 (define_expand "subsi3"
7645   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7646         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7647                   (match_operand:SI 2 "general_operand" "")))]
7648   ""
7649   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7650
7651 (define_insn "*subsi_1"
7652   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7653         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7654                   (match_operand:SI 2 "general_operand" "ri,rm")))
7655    (clobber (reg:CC FLAGS_REG))]
7656   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7657   "sub{l}\t{%2, %0|%0, %2}"
7658   [(set_attr "type" "alu")
7659    (set_attr "mode" "SI")])
7660
7661 (define_insn "*subsi_1_zext"
7662   [(set (match_operand:DI 0 "register_operand" "=r")
7663         (zero_extend:DI
7664           (minus:SI (match_operand:SI 1 "register_operand" "0")
7665                     (match_operand:SI 2 "general_operand" "g"))))
7666    (clobber (reg:CC FLAGS_REG))]
7667   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7668   "sub{l}\t{%2, %k0|%k0, %2}"
7669   [(set_attr "type" "alu")
7670    (set_attr "mode" "SI")])
7671
7672 (define_insn "*subsi_2"
7673   [(set (reg FLAGS_REG)
7674         (compare
7675           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7676                     (match_operand:SI 2 "general_operand" "ri,rm"))
7677           (const_int 0)))
7678    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7679         (minus:SI (match_dup 1) (match_dup 2)))]
7680   "ix86_match_ccmode (insn, CCGOCmode)
7681    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7682   "sub{l}\t{%2, %0|%0, %2}"
7683   [(set_attr "type" "alu")
7684    (set_attr "mode" "SI")])
7685
7686 (define_insn "*subsi_2_zext"
7687   [(set (reg FLAGS_REG)
7688         (compare
7689           (minus:SI (match_operand:SI 1 "register_operand" "0")
7690                     (match_operand:SI 2 "general_operand" "g"))
7691           (const_int 0)))
7692    (set (match_operand:DI 0 "register_operand" "=r")
7693         (zero_extend:DI
7694           (minus:SI (match_dup 1)
7695                     (match_dup 2))))]
7696   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7697    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7698   "sub{l}\t{%2, %k0|%k0, %2}"
7699   [(set_attr "type" "alu")
7700    (set_attr "mode" "SI")])
7701
7702 (define_insn "*subsi_3"
7703   [(set (reg FLAGS_REG)
7704         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7705                  (match_operand:SI 2 "general_operand" "ri,rm")))
7706    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7707         (minus:SI (match_dup 1) (match_dup 2)))]
7708   "ix86_match_ccmode (insn, CCmode)
7709    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7710   "sub{l}\t{%2, %0|%0, %2}"
7711   [(set_attr "type" "alu")
7712    (set_attr "mode" "SI")])
7713
7714 (define_insn "*subsi_3_zext"
7715   [(set (reg FLAGS_REG)
7716         (compare (match_operand:SI 1 "register_operand" "0")
7717                  (match_operand:SI 2 "general_operand" "g")))
7718    (set (match_operand:DI 0 "register_operand" "=r")
7719         (zero_extend:DI
7720           (minus:SI (match_dup 1)
7721                     (match_dup 2))))]
7722   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7723    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7724   "sub{l}\t{%2, %1|%1, %2}"
7725   [(set_attr "type" "alu")
7726    (set_attr "mode" "DI")])
7727
7728 (define_expand "subhi3"
7729   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7730         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7731                   (match_operand:HI 2 "general_operand" "")))]
7732   "TARGET_HIMODE_MATH"
7733   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7734
7735 (define_insn "*subhi_1"
7736   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7737         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7738                   (match_operand:HI 2 "general_operand" "rn,rm")))
7739    (clobber (reg:CC FLAGS_REG))]
7740   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7741   "sub{w}\t{%2, %0|%0, %2}"
7742   [(set_attr "type" "alu")
7743    (set_attr "mode" "HI")])
7744
7745 (define_insn "*subhi_2"
7746   [(set (reg FLAGS_REG)
7747         (compare
7748           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7749                     (match_operand:HI 2 "general_operand" "rn,rm"))
7750           (const_int 0)))
7751    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7752         (minus:HI (match_dup 1) (match_dup 2)))]
7753   "ix86_match_ccmode (insn, CCGOCmode)
7754    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7755   "sub{w}\t{%2, %0|%0, %2}"
7756   [(set_attr "type" "alu")
7757    (set_attr "mode" "HI")])
7758
7759 (define_insn "*subhi_3"
7760   [(set (reg FLAGS_REG)
7761         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7762                  (match_operand:HI 2 "general_operand" "rn,rm")))
7763    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7764         (minus:HI (match_dup 1) (match_dup 2)))]
7765   "ix86_match_ccmode (insn, CCmode)
7766    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7767   "sub{w}\t{%2, %0|%0, %2}"
7768   [(set_attr "type" "alu")
7769    (set_attr "mode" "HI")])
7770
7771 (define_expand "subqi3"
7772   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7773         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7774                   (match_operand:QI 2 "general_operand" "")))]
7775   "TARGET_QIMODE_MATH"
7776   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7777
7778 (define_insn "*subqi_1"
7779   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7780         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7781                   (match_operand:QI 2 "general_operand" "qn,qm")))
7782    (clobber (reg:CC FLAGS_REG))]
7783   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7784   "sub{b}\t{%2, %0|%0, %2}"
7785   [(set_attr "type" "alu")
7786    (set_attr "mode" "QI")])
7787
7788 (define_insn "*subqi_1_slp"
7789   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7790         (minus:QI (match_dup 0)
7791                   (match_operand:QI 1 "general_operand" "qn,qm")))
7792    (clobber (reg:CC FLAGS_REG))]
7793   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7794    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7795   "sub{b}\t{%1, %0|%0, %1}"
7796   [(set_attr "type" "alu1")
7797    (set_attr "mode" "QI")])
7798
7799 (define_insn "*subqi_2"
7800   [(set (reg FLAGS_REG)
7801         (compare
7802           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7803                     (match_operand:QI 2 "general_operand" "qn,qm"))
7804           (const_int 0)))
7805    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7806         (minus:QI (match_dup 1) (match_dup 2)))]
7807   "ix86_match_ccmode (insn, CCGOCmode)
7808    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7809   "sub{b}\t{%2, %0|%0, %2}"
7810   [(set_attr "type" "alu")
7811    (set_attr "mode" "QI")])
7812
7813 (define_insn "*subqi_3"
7814   [(set (reg FLAGS_REG)
7815         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7816                  (match_operand:QI 2 "general_operand" "qn,qm")))
7817    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7818         (minus:QI (match_dup 1) (match_dup 2)))]
7819   "ix86_match_ccmode (insn, CCmode)
7820    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7821   "sub{b}\t{%2, %0|%0, %2}"
7822   [(set_attr "type" "alu")
7823    (set_attr "mode" "QI")])
7824
7825 ;; The patterns that match these are at the end of this file.
7826
7827 (define_expand "subxf3"
7828   [(set (match_operand:XF 0 "register_operand" "")
7829         (minus:XF (match_operand:XF 1 "register_operand" "")
7830                   (match_operand:XF 2 "register_operand" "")))]
7831   "TARGET_80387"
7832   "")
7833
7834 (define_expand "sub<mode>3"
7835   [(set (match_operand:MODEF 0 "register_operand" "")
7836         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7837                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7838   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7839   "")
7840 \f
7841 ;; Multiply instructions
7842
7843 (define_expand "muldi3"
7844   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7845                    (mult:DI (match_operand:DI 1 "register_operand" "")
7846                             (match_operand:DI 2 "x86_64_general_operand" "")))
7847               (clobber (reg:CC FLAGS_REG))])]
7848   "TARGET_64BIT"
7849   "")
7850
7851 ;; On AMDFAM10
7852 ;; IMUL reg64, reg64, imm8      Direct
7853 ;; IMUL reg64, mem64, imm8      VectorPath
7854 ;; IMUL reg64, reg64, imm32     Direct
7855 ;; IMUL reg64, mem64, imm32     VectorPath
7856 ;; IMUL reg64, reg64            Direct
7857 ;; IMUL reg64, mem64            Direct
7858
7859 (define_insn "*muldi3_1_rex64"
7860   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7861         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7862                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7863    (clobber (reg:CC FLAGS_REG))]
7864   "TARGET_64BIT
7865    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7866   "@
7867    imul{q}\t{%2, %1, %0|%0, %1, %2}
7868    imul{q}\t{%2, %1, %0|%0, %1, %2}
7869    imul{q}\t{%2, %0|%0, %2}"
7870   [(set_attr "type" "imul")
7871    (set_attr "prefix_0f" "0,0,1")
7872    (set (attr "athlon_decode")
7873         (cond [(eq_attr "cpu" "athlon")
7874                   (const_string "vector")
7875                (eq_attr "alternative" "1")
7876                   (const_string "vector")
7877                (and (eq_attr "alternative" "2")
7878                     (match_operand 1 "memory_operand" ""))
7879                   (const_string "vector")]
7880               (const_string "direct")))
7881    (set (attr "amdfam10_decode")
7882         (cond [(and (eq_attr "alternative" "0,1")
7883                     (match_operand 1 "memory_operand" ""))
7884                   (const_string "vector")]
7885               (const_string "direct")))
7886    (set_attr "mode" "DI")])
7887
7888 (define_expand "mulsi3"
7889   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7890                    (mult:SI (match_operand:SI 1 "register_operand" "")
7891                             (match_operand:SI 2 "general_operand" "")))
7892               (clobber (reg:CC FLAGS_REG))])]
7893   ""
7894   "")
7895
7896 ;; On AMDFAM10
7897 ;; IMUL reg32, reg32, imm8      Direct
7898 ;; IMUL reg32, mem32, imm8      VectorPath
7899 ;; IMUL reg32, reg32, imm32     Direct
7900 ;; IMUL reg32, mem32, imm32     VectorPath
7901 ;; IMUL reg32, reg32            Direct
7902 ;; IMUL reg32, mem32            Direct
7903
7904 (define_insn "*mulsi3_1"
7905   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7906         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7907                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7908    (clobber (reg:CC FLAGS_REG))]
7909   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7910   "@
7911    imul{l}\t{%2, %1, %0|%0, %1, %2}
7912    imul{l}\t{%2, %1, %0|%0, %1, %2}
7913    imul{l}\t{%2, %0|%0, %2}"
7914   [(set_attr "type" "imul")
7915    (set_attr "prefix_0f" "0,0,1")
7916    (set (attr "athlon_decode")
7917         (cond [(eq_attr "cpu" "athlon")
7918                   (const_string "vector")
7919                (eq_attr "alternative" "1")
7920                   (const_string "vector")
7921                (and (eq_attr "alternative" "2")
7922                     (match_operand 1 "memory_operand" ""))
7923                   (const_string "vector")]
7924               (const_string "direct")))
7925    (set (attr "amdfam10_decode")
7926         (cond [(and (eq_attr "alternative" "0,1")
7927                     (match_operand 1 "memory_operand" ""))
7928                   (const_string "vector")]
7929               (const_string "direct")))
7930    (set_attr "mode" "SI")])
7931
7932 (define_insn "*mulsi3_1_zext"
7933   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7934         (zero_extend:DI
7935           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7936                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7937    (clobber (reg:CC FLAGS_REG))]
7938   "TARGET_64BIT
7939    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7940   "@
7941    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7942    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7943    imul{l}\t{%2, %k0|%k0, %2}"
7944   [(set_attr "type" "imul")
7945    (set_attr "prefix_0f" "0,0,1")
7946    (set (attr "athlon_decode")
7947         (cond [(eq_attr "cpu" "athlon")
7948                   (const_string "vector")
7949                (eq_attr "alternative" "1")
7950                   (const_string "vector")
7951                (and (eq_attr "alternative" "2")
7952                     (match_operand 1 "memory_operand" ""))
7953                   (const_string "vector")]
7954               (const_string "direct")))
7955    (set (attr "amdfam10_decode")
7956         (cond [(and (eq_attr "alternative" "0,1")
7957                     (match_operand 1 "memory_operand" ""))
7958                   (const_string "vector")]
7959               (const_string "direct")))
7960    (set_attr "mode" "SI")])
7961
7962 (define_expand "mulhi3"
7963   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7964                    (mult:HI (match_operand:HI 1 "register_operand" "")
7965                             (match_operand:HI 2 "general_operand" "")))
7966               (clobber (reg:CC FLAGS_REG))])]
7967   "TARGET_HIMODE_MATH"
7968   "")
7969
7970 ;; On AMDFAM10
7971 ;; IMUL reg16, reg16, imm8      VectorPath
7972 ;; IMUL reg16, mem16, imm8      VectorPath
7973 ;; IMUL reg16, reg16, imm16     VectorPath
7974 ;; IMUL reg16, mem16, imm16     VectorPath
7975 ;; IMUL reg16, reg16            Direct
7976 ;; IMUL reg16, mem16            Direct
7977 (define_insn "*mulhi3_1"
7978   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7979         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7980                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7981    (clobber (reg:CC FLAGS_REG))]
7982   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7983   "@
7984    imul{w}\t{%2, %1, %0|%0, %1, %2}
7985    imul{w}\t{%2, %1, %0|%0, %1, %2}
7986    imul{w}\t{%2, %0|%0, %2}"
7987   [(set_attr "type" "imul")
7988    (set_attr "prefix_0f" "0,0,1")
7989    (set (attr "athlon_decode")
7990         (cond [(eq_attr "cpu" "athlon")
7991                   (const_string "vector")
7992                (eq_attr "alternative" "1,2")
7993                   (const_string "vector")]
7994               (const_string "direct")))
7995    (set (attr "amdfam10_decode")
7996         (cond [(eq_attr "alternative" "0,1")
7997                   (const_string "vector")]
7998               (const_string "direct")))
7999    (set_attr "mode" "HI")])
8000
8001 (define_expand "mulqi3"
8002   [(parallel [(set (match_operand:QI 0 "register_operand" "")
8003                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8004                             (match_operand:QI 2 "register_operand" "")))
8005               (clobber (reg:CC FLAGS_REG))])]
8006   "TARGET_QIMODE_MATH"
8007   "")
8008
8009 ;;On AMDFAM10
8010 ;; MUL reg8     Direct
8011 ;; MUL mem8     Direct
8012
8013 (define_insn "*mulqi3_1"
8014   [(set (match_operand:QI 0 "register_operand" "=a")
8015         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8016                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8017    (clobber (reg:CC FLAGS_REG))]
8018   "TARGET_QIMODE_MATH
8019    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8020   "mul{b}\t%2"
8021   [(set_attr "type" "imul")
8022    (set_attr "length_immediate" "0")
8023    (set (attr "athlon_decode")
8024      (if_then_else (eq_attr "cpu" "athlon")
8025         (const_string "vector")
8026         (const_string "direct")))
8027    (set_attr "amdfam10_decode" "direct")
8028    (set_attr "mode" "QI")])
8029
8030 (define_expand "umulqihi3"
8031   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8032                    (mult:HI (zero_extend:HI
8033                               (match_operand:QI 1 "nonimmediate_operand" ""))
8034                             (zero_extend:HI
8035                               (match_operand:QI 2 "register_operand" ""))))
8036               (clobber (reg:CC FLAGS_REG))])]
8037   "TARGET_QIMODE_MATH"
8038   "")
8039
8040 (define_insn "*umulqihi3_1"
8041   [(set (match_operand:HI 0 "register_operand" "=a")
8042         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8043                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8044    (clobber (reg:CC FLAGS_REG))]
8045   "TARGET_QIMODE_MATH
8046    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8047   "mul{b}\t%2"
8048   [(set_attr "type" "imul")
8049    (set_attr "length_immediate" "0")
8050    (set (attr "athlon_decode")
8051      (if_then_else (eq_attr "cpu" "athlon")
8052         (const_string "vector")
8053         (const_string "direct")))
8054    (set_attr "amdfam10_decode" "direct")
8055    (set_attr "mode" "QI")])
8056
8057 (define_expand "mulqihi3"
8058   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8059                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8060                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8061               (clobber (reg:CC FLAGS_REG))])]
8062   "TARGET_QIMODE_MATH"
8063   "")
8064
8065 (define_insn "*mulqihi3_insn"
8066   [(set (match_operand:HI 0 "register_operand" "=a")
8067         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8068                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8069    (clobber (reg:CC FLAGS_REG))]
8070   "TARGET_QIMODE_MATH
8071    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8072   "imul{b}\t%2"
8073   [(set_attr "type" "imul")
8074    (set_attr "length_immediate" "0")
8075    (set (attr "athlon_decode")
8076      (if_then_else (eq_attr "cpu" "athlon")
8077         (const_string "vector")
8078         (const_string "direct")))
8079    (set_attr "amdfam10_decode" "direct")
8080    (set_attr "mode" "QI")])
8081
8082 (define_expand "umulditi3"
8083   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8084                    (mult:TI (zero_extend:TI
8085                               (match_operand:DI 1 "nonimmediate_operand" ""))
8086                             (zero_extend:TI
8087                               (match_operand:DI 2 "register_operand" ""))))
8088               (clobber (reg:CC FLAGS_REG))])]
8089   "TARGET_64BIT"
8090   "")
8091
8092 (define_insn "*umulditi3_insn"
8093   [(set (match_operand:TI 0 "register_operand" "=A")
8094         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8095                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8096    (clobber (reg:CC FLAGS_REG))]
8097   "TARGET_64BIT
8098    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8099   "mul{q}\t%2"
8100   [(set_attr "type" "imul")
8101    (set_attr "length_immediate" "0")
8102    (set (attr "athlon_decode")
8103      (if_then_else (eq_attr "cpu" "athlon")
8104         (const_string "vector")
8105         (const_string "double")))
8106    (set_attr "amdfam10_decode" "double")
8107    (set_attr "mode" "DI")])
8108
8109 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8110 (define_expand "umulsidi3"
8111   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8112                    (mult:DI (zero_extend:DI
8113                               (match_operand:SI 1 "nonimmediate_operand" ""))
8114                             (zero_extend:DI
8115                               (match_operand:SI 2 "register_operand" ""))))
8116               (clobber (reg:CC FLAGS_REG))])]
8117   "!TARGET_64BIT"
8118   "")
8119
8120 (define_insn "*umulsidi3_insn"
8121   [(set (match_operand:DI 0 "register_operand" "=A")
8122         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8123                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8124    (clobber (reg:CC FLAGS_REG))]
8125   "!TARGET_64BIT
8126    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8127   "mul{l}\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" "SI")])
8136
8137 (define_expand "mulditi3"
8138   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8139                    (mult:TI (sign_extend:TI
8140                               (match_operand:DI 1 "nonimmediate_operand" ""))
8141                             (sign_extend:TI
8142                               (match_operand:DI 2 "register_operand" ""))))
8143               (clobber (reg:CC FLAGS_REG))])]
8144   "TARGET_64BIT"
8145   "")
8146
8147 (define_insn "*mulditi3_insn"
8148   [(set (match_operand:TI 0 "register_operand" "=A")
8149         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8150                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8151    (clobber (reg:CC FLAGS_REG))]
8152   "TARGET_64BIT
8153    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8154   "imul{q}\t%2"
8155   [(set_attr "type" "imul")
8156    (set_attr "length_immediate" "0")
8157    (set (attr "athlon_decode")
8158      (if_then_else (eq_attr "cpu" "athlon")
8159         (const_string "vector")
8160         (const_string "double")))
8161    (set_attr "amdfam10_decode" "double")
8162    (set_attr "mode" "DI")])
8163
8164 (define_expand "mulsidi3"
8165   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8166                    (mult:DI (sign_extend:DI
8167                               (match_operand:SI 1 "nonimmediate_operand" ""))
8168                             (sign_extend:DI
8169                               (match_operand:SI 2 "register_operand" ""))))
8170               (clobber (reg:CC FLAGS_REG))])]
8171   "!TARGET_64BIT"
8172   "")
8173
8174 (define_insn "*mulsidi3_insn"
8175   [(set (match_operand:DI 0 "register_operand" "=A")
8176         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8177                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8178    (clobber (reg:CC FLAGS_REG))]
8179   "!TARGET_64BIT
8180    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8181   "imul{l}\t%2"
8182   [(set_attr "type" "imul")
8183    (set_attr "length_immediate" "0")
8184    (set (attr "athlon_decode")
8185      (if_then_else (eq_attr "cpu" "athlon")
8186         (const_string "vector")
8187         (const_string "double")))
8188    (set_attr "amdfam10_decode" "double")
8189    (set_attr "mode" "SI")])
8190
8191 (define_expand "umuldi3_highpart"
8192   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8193                    (truncate:DI
8194                      (lshiftrt:TI
8195                        (mult:TI (zero_extend:TI
8196                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8197                                 (zero_extend:TI
8198                                   (match_operand:DI 2 "register_operand" "")))
8199                        (const_int 64))))
8200               (clobber (match_scratch:DI 3 ""))
8201               (clobber (reg:CC FLAGS_REG))])]
8202   "TARGET_64BIT"
8203   "")
8204
8205 (define_insn "*umuldi3_highpart_rex64"
8206   [(set (match_operand:DI 0 "register_operand" "=d")
8207         (truncate:DI
8208           (lshiftrt:TI
8209             (mult:TI (zero_extend:TI
8210                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8211                      (zero_extend:TI
8212                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8213             (const_int 64))))
8214    (clobber (match_scratch:DI 3 "=1"))
8215    (clobber (reg:CC FLAGS_REG))]
8216   "TARGET_64BIT
8217    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8218   "mul{q}\t%2"
8219   [(set_attr "type" "imul")
8220    (set_attr "length_immediate" "0")
8221    (set (attr "athlon_decode")
8222      (if_then_else (eq_attr "cpu" "athlon")
8223         (const_string "vector")
8224         (const_string "double")))
8225    (set_attr "amdfam10_decode" "double")
8226    (set_attr "mode" "DI")])
8227
8228 (define_expand "umulsi3_highpart"
8229   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8230                    (truncate:SI
8231                      (lshiftrt:DI
8232                        (mult:DI (zero_extend:DI
8233                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8234                                 (zero_extend:DI
8235                                   (match_operand:SI 2 "register_operand" "")))
8236                        (const_int 32))))
8237               (clobber (match_scratch:SI 3 ""))
8238               (clobber (reg:CC FLAGS_REG))])]
8239   ""
8240   "")
8241
8242 (define_insn "*umulsi3_highpart_insn"
8243   [(set (match_operand:SI 0 "register_operand" "=d")
8244         (truncate:SI
8245           (lshiftrt:DI
8246             (mult:DI (zero_extend:DI
8247                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8248                      (zero_extend:DI
8249                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8250             (const_int 32))))
8251    (clobber (match_scratch:SI 3 "=1"))
8252    (clobber (reg:CC FLAGS_REG))]
8253   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8254   "mul{l}\t%2"
8255   [(set_attr "type" "imul")
8256    (set_attr "length_immediate" "0")
8257    (set (attr "athlon_decode")
8258      (if_then_else (eq_attr "cpu" "athlon")
8259         (const_string "vector")
8260         (const_string "double")))
8261    (set_attr "amdfam10_decode" "double")
8262    (set_attr "mode" "SI")])
8263
8264 (define_insn "*umulsi3_highpart_zext"
8265   [(set (match_operand:DI 0 "register_operand" "=d")
8266         (zero_extend:DI (truncate:SI
8267           (lshiftrt:DI
8268             (mult:DI (zero_extend:DI
8269                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8270                      (zero_extend:DI
8271                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8272             (const_int 32)))))
8273    (clobber (match_scratch:SI 3 "=1"))
8274    (clobber (reg:CC FLAGS_REG))]
8275   "TARGET_64BIT
8276    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8277   "mul{l}\t%2"
8278   [(set_attr "type" "imul")
8279    (set_attr "length_immediate" "0")
8280    (set (attr "athlon_decode")
8281      (if_then_else (eq_attr "cpu" "athlon")
8282         (const_string "vector")
8283         (const_string "double")))
8284    (set_attr "amdfam10_decode" "double")
8285    (set_attr "mode" "SI")])
8286
8287 (define_expand "smuldi3_highpart"
8288   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8289                    (truncate:DI
8290                      (lshiftrt:TI
8291                        (mult:TI (sign_extend:TI
8292                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8293                                 (sign_extend:TI
8294                                   (match_operand:DI 2 "register_operand" "")))
8295                        (const_int 64))))
8296               (clobber (match_scratch:DI 3 ""))
8297               (clobber (reg:CC FLAGS_REG))])]
8298   "TARGET_64BIT"
8299   "")
8300
8301 (define_insn "*smuldi3_highpart_rex64"
8302   [(set (match_operand:DI 0 "register_operand" "=d")
8303         (truncate:DI
8304           (lshiftrt:TI
8305             (mult:TI (sign_extend:TI
8306                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8307                      (sign_extend:TI
8308                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8309             (const_int 64))))
8310    (clobber (match_scratch:DI 3 "=1"))
8311    (clobber (reg:CC FLAGS_REG))]
8312   "TARGET_64BIT
8313    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8314   "imul{q}\t%2"
8315   [(set_attr "type" "imul")
8316    (set (attr "athlon_decode")
8317      (if_then_else (eq_attr "cpu" "athlon")
8318         (const_string "vector")
8319         (const_string "double")))
8320    (set_attr "amdfam10_decode" "double")
8321    (set_attr "mode" "DI")])
8322
8323 (define_expand "smulsi3_highpart"
8324   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8325                    (truncate:SI
8326                      (lshiftrt:DI
8327                        (mult:DI (sign_extend:DI
8328                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8329                                 (sign_extend:DI
8330                                   (match_operand:SI 2 "register_operand" "")))
8331                        (const_int 32))))
8332               (clobber (match_scratch:SI 3 ""))
8333               (clobber (reg:CC FLAGS_REG))])]
8334   ""
8335   "")
8336
8337 (define_insn "*smulsi3_highpart_insn"
8338   [(set (match_operand:SI 0 "register_operand" "=d")
8339         (truncate:SI
8340           (lshiftrt:DI
8341             (mult:DI (sign_extend:DI
8342                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8343                      (sign_extend:DI
8344                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8345             (const_int 32))))
8346    (clobber (match_scratch:SI 3 "=1"))
8347    (clobber (reg:CC FLAGS_REG))]
8348   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8349   "imul{l}\t%2"
8350   [(set_attr "type" "imul")
8351    (set (attr "athlon_decode")
8352      (if_then_else (eq_attr "cpu" "athlon")
8353         (const_string "vector")
8354         (const_string "double")))
8355    (set_attr "amdfam10_decode" "double")
8356    (set_attr "mode" "SI")])
8357
8358 (define_insn "*smulsi3_highpart_zext"
8359   [(set (match_operand:DI 0 "register_operand" "=d")
8360         (zero_extend:DI (truncate:SI
8361           (lshiftrt:DI
8362             (mult:DI (sign_extend:DI
8363                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8364                      (sign_extend:DI
8365                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8366             (const_int 32)))))
8367    (clobber (match_scratch:SI 3 "=1"))
8368    (clobber (reg:CC FLAGS_REG))]
8369   "TARGET_64BIT
8370    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8371   "imul{l}\t%2"
8372   [(set_attr "type" "imul")
8373    (set (attr "athlon_decode")
8374      (if_then_else (eq_attr "cpu" "athlon")
8375         (const_string "vector")
8376         (const_string "double")))
8377    (set_attr "amdfam10_decode" "double")
8378    (set_attr "mode" "SI")])
8379
8380 ;; The patterns that match these are at the end of this file.
8381
8382 (define_expand "mulxf3"
8383   [(set (match_operand:XF 0 "register_operand" "")
8384         (mult:XF (match_operand:XF 1 "register_operand" "")
8385                  (match_operand:XF 2 "register_operand" "")))]
8386   "TARGET_80387"
8387   "")
8388
8389 (define_expand "mul<mode>3"
8390   [(set (match_operand:MODEF 0 "register_operand" "")
8391         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8392                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8393   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8394   "")
8395
8396 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8397
8398 \f
8399 ;; Divide instructions
8400
8401 (define_insn "divqi3"
8402   [(set (match_operand:QI 0 "register_operand" "=a")
8403         (div:QI (match_operand:HI 1 "register_operand" "0")
8404                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8405    (clobber (reg:CC FLAGS_REG))]
8406   "TARGET_QIMODE_MATH"
8407   "idiv{b}\t%2"
8408   [(set_attr "type" "idiv")
8409    (set_attr "mode" "QI")])
8410
8411 (define_insn "udivqi3"
8412   [(set (match_operand:QI 0 "register_operand" "=a")
8413         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8414                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8415    (clobber (reg:CC FLAGS_REG))]
8416   "TARGET_QIMODE_MATH"
8417   "div{b}\t%2"
8418   [(set_attr "type" "idiv")
8419    (set_attr "mode" "QI")])
8420
8421 ;; The patterns that match these are at the end of this file.
8422
8423 (define_expand "divxf3"
8424   [(set (match_operand:XF 0 "register_operand" "")
8425         (div:XF (match_operand:XF 1 "register_operand" "")
8426                 (match_operand:XF 2 "register_operand" "")))]
8427   "TARGET_80387"
8428   "")
8429
8430 (define_expand "divdf3"
8431   [(set (match_operand:DF 0 "register_operand" "")
8432         (div:DF (match_operand:DF 1 "register_operand" "")
8433                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8434    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8435    "")
8436
8437 (define_expand "divsf3"
8438   [(set (match_operand:SF 0 "register_operand" "")
8439         (div:SF (match_operand:SF 1 "register_operand" "")
8440                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8441   "TARGET_80387 || TARGET_SSE_MATH"
8442 {
8443   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8444       && flag_finite_math_only && !flag_trapping_math
8445       && flag_unsafe_math_optimizations)
8446     {
8447       ix86_emit_swdivsf (operands[0], operands[1],
8448                          operands[2], SFmode);
8449       DONE;
8450     }
8451 })
8452 \f
8453 ;; Remainder instructions.
8454
8455 (define_expand "divmoddi4"
8456   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8457                    (div:DI (match_operand:DI 1 "register_operand" "")
8458                            (match_operand:DI 2 "nonimmediate_operand" "")))
8459               (set (match_operand:DI 3 "register_operand" "")
8460                    (mod:DI (match_dup 1) (match_dup 2)))
8461               (clobber (reg:CC FLAGS_REG))])]
8462   "TARGET_64BIT"
8463   "")
8464
8465 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8466 ;; Penalize eax case slightly because it results in worse scheduling
8467 ;; of code.
8468 (define_insn "*divmoddi4_nocltd_rex64"
8469   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8470         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8471                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8472    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8473         (mod:DI (match_dup 2) (match_dup 3)))
8474    (clobber (reg:CC FLAGS_REG))]
8475   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8476   "#"
8477   [(set_attr "type" "multi")])
8478
8479 (define_insn "*divmoddi4_cltd_rex64"
8480   [(set (match_operand:DI 0 "register_operand" "=a")
8481         (div:DI (match_operand:DI 2 "register_operand" "a")
8482                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8483    (set (match_operand:DI 1 "register_operand" "=&d")
8484         (mod:DI (match_dup 2) (match_dup 3)))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8487   "#"
8488   [(set_attr "type" "multi")])
8489
8490 (define_insn "*divmoddi_noext_rex64"
8491   [(set (match_operand:DI 0 "register_operand" "=a")
8492         (div:DI (match_operand:DI 1 "register_operand" "0")
8493                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8494    (set (match_operand:DI 3 "register_operand" "=d")
8495         (mod:DI (match_dup 1) (match_dup 2)))
8496    (use (match_operand:DI 4 "register_operand" "3"))
8497    (clobber (reg:CC FLAGS_REG))]
8498   "TARGET_64BIT"
8499   "idiv{q}\t%2"
8500   [(set_attr "type" "idiv")
8501    (set_attr "mode" "DI")])
8502
8503 (define_split
8504   [(set (match_operand:DI 0 "register_operand" "")
8505         (div:DI (match_operand:DI 1 "register_operand" "")
8506                 (match_operand:DI 2 "nonimmediate_operand" "")))
8507    (set (match_operand:DI 3 "register_operand" "")
8508         (mod:DI (match_dup 1) (match_dup 2)))
8509    (clobber (reg:CC FLAGS_REG))]
8510   "TARGET_64BIT && reload_completed"
8511   [(parallel [(set (match_dup 3)
8512                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8513               (clobber (reg:CC FLAGS_REG))])
8514    (parallel [(set (match_dup 0)
8515                    (div:DI (reg:DI 0) (match_dup 2)))
8516               (set (match_dup 3)
8517                    (mod:DI (reg:DI 0) (match_dup 2)))
8518               (use (match_dup 3))
8519               (clobber (reg:CC FLAGS_REG))])]
8520 {
8521   /* Avoid use of cltd in favor of a mov+shift.  */
8522   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8523     {
8524       if (true_regnum (operands[1]))
8525         emit_move_insn (operands[0], operands[1]);
8526       else
8527         emit_move_insn (operands[3], operands[1]);
8528       operands[4] = operands[3];
8529     }
8530   else
8531     {
8532       gcc_assert (!true_regnum (operands[1]));
8533       operands[4] = operands[1];
8534     }
8535 })
8536
8537
8538 (define_expand "divmodsi4"
8539   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8540                    (div:SI (match_operand:SI 1 "register_operand" "")
8541                            (match_operand:SI 2 "nonimmediate_operand" "")))
8542               (set (match_operand:SI 3 "register_operand" "")
8543                    (mod:SI (match_dup 1) (match_dup 2)))
8544               (clobber (reg:CC FLAGS_REG))])]
8545   ""
8546   "")
8547
8548 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8549 ;; Penalize eax case slightly because it results in worse scheduling
8550 ;; of code.
8551 (define_insn "*divmodsi4_nocltd"
8552   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8553         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8554                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8555    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8556         (mod:SI (match_dup 2) (match_dup 3)))
8557    (clobber (reg:CC FLAGS_REG))]
8558   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8559   "#"
8560   [(set_attr "type" "multi")])
8561
8562 (define_insn "*divmodsi4_cltd"
8563   [(set (match_operand:SI 0 "register_operand" "=a")
8564         (div:SI (match_operand:SI 2 "register_operand" "a")
8565                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8566    (set (match_operand:SI 1 "register_operand" "=&d")
8567         (mod:SI (match_dup 2) (match_dup 3)))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8570   "#"
8571   [(set_attr "type" "multi")])
8572
8573 (define_insn "*divmodsi_noext"
8574   [(set (match_operand:SI 0 "register_operand" "=a")
8575         (div:SI (match_operand:SI 1 "register_operand" "0")
8576                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8577    (set (match_operand:SI 3 "register_operand" "=d")
8578         (mod:SI (match_dup 1) (match_dup 2)))
8579    (use (match_operand:SI 4 "register_operand" "3"))
8580    (clobber (reg:CC FLAGS_REG))]
8581   ""
8582   "idiv{l}\t%2"
8583   [(set_attr "type" "idiv")
8584    (set_attr "mode" "SI")])
8585
8586 (define_split
8587   [(set (match_operand:SI 0 "register_operand" "")
8588         (div:SI (match_operand:SI 1 "register_operand" "")
8589                 (match_operand:SI 2 "nonimmediate_operand" "")))
8590    (set (match_operand:SI 3 "register_operand" "")
8591         (mod:SI (match_dup 1) (match_dup 2)))
8592    (clobber (reg:CC FLAGS_REG))]
8593   "reload_completed"
8594   [(parallel [(set (match_dup 3)
8595                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8596               (clobber (reg:CC FLAGS_REG))])
8597    (parallel [(set (match_dup 0)
8598                    (div:SI (reg:SI 0) (match_dup 2)))
8599               (set (match_dup 3)
8600                    (mod:SI (reg:SI 0) (match_dup 2)))
8601               (use (match_dup 3))
8602               (clobber (reg:CC FLAGS_REG))])]
8603 {
8604   /* Avoid use of cltd in favor of a mov+shift.  */
8605   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8606     {
8607       if (true_regnum (operands[1]))
8608         emit_move_insn (operands[0], operands[1]);
8609       else
8610         emit_move_insn (operands[3], operands[1]);
8611       operands[4] = operands[3];
8612     }
8613   else
8614     {
8615       gcc_assert (!true_regnum (operands[1]));
8616       operands[4] = operands[1];
8617     }
8618 })
8619 ;; %%% Split me.
8620 (define_insn "divmodhi4"
8621   [(set (match_operand:HI 0 "register_operand" "=a")
8622         (div:HI (match_operand:HI 1 "register_operand" "0")
8623                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8624    (set (match_operand:HI 3 "register_operand" "=&d")
8625         (mod:HI (match_dup 1) (match_dup 2)))
8626    (clobber (reg:CC FLAGS_REG))]
8627   "TARGET_HIMODE_MATH"
8628   "cwtd\;idiv{w}\t%2"
8629   [(set_attr "type" "multi")
8630    (set_attr "length_immediate" "0")
8631    (set_attr "mode" "SI")])
8632
8633 (define_insn "udivmoddi4"
8634   [(set (match_operand:DI 0 "register_operand" "=a")
8635         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8636                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8637    (set (match_operand:DI 3 "register_operand" "=&d")
8638         (umod:DI (match_dup 1) (match_dup 2)))
8639    (clobber (reg:CC FLAGS_REG))]
8640   "TARGET_64BIT"
8641   "xor{q}\t%3, %3\;div{q}\t%2"
8642   [(set_attr "type" "multi")
8643    (set_attr "length_immediate" "0")
8644    (set_attr "mode" "DI")])
8645
8646 (define_insn "*udivmoddi4_noext"
8647   [(set (match_operand:DI 0 "register_operand" "=a")
8648         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8649                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8650    (set (match_operand:DI 3 "register_operand" "=d")
8651         (umod:DI (match_dup 1) (match_dup 2)))
8652    (use (match_dup 3))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "TARGET_64BIT"
8655   "div{q}\t%2"
8656   [(set_attr "type" "idiv")
8657    (set_attr "mode" "DI")])
8658
8659 (define_split
8660   [(set (match_operand:DI 0 "register_operand" "")
8661         (udiv:DI (match_operand:DI 1 "register_operand" "")
8662                  (match_operand:DI 2 "nonimmediate_operand" "")))
8663    (set (match_operand:DI 3 "register_operand" "")
8664         (umod:DI (match_dup 1) (match_dup 2)))
8665    (clobber (reg:CC FLAGS_REG))]
8666   "TARGET_64BIT && reload_completed"
8667   [(set (match_dup 3) (const_int 0))
8668    (parallel [(set (match_dup 0)
8669                    (udiv:DI (match_dup 1) (match_dup 2)))
8670               (set (match_dup 3)
8671                    (umod:DI (match_dup 1) (match_dup 2)))
8672               (use (match_dup 3))
8673               (clobber (reg:CC FLAGS_REG))])]
8674   "")
8675
8676 (define_insn "udivmodsi4"
8677   [(set (match_operand:SI 0 "register_operand" "=a")
8678         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8679                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8680    (set (match_operand:SI 3 "register_operand" "=&d")
8681         (umod:SI (match_dup 1) (match_dup 2)))
8682    (clobber (reg:CC FLAGS_REG))]
8683   ""
8684   "xor{l}\t%3, %3\;div{l}\t%2"
8685   [(set_attr "type" "multi")
8686    (set_attr "length_immediate" "0")
8687    (set_attr "mode" "SI")])
8688
8689 (define_insn "*udivmodsi4_noext"
8690   [(set (match_operand:SI 0 "register_operand" "=a")
8691         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8692                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8693    (set (match_operand:SI 3 "register_operand" "=d")
8694         (umod:SI (match_dup 1) (match_dup 2)))
8695    (use (match_dup 3))
8696    (clobber (reg:CC FLAGS_REG))]
8697   ""
8698   "div{l}\t%2"
8699   [(set_attr "type" "idiv")
8700    (set_attr "mode" "SI")])
8701
8702 (define_split
8703   [(set (match_operand:SI 0 "register_operand" "")
8704         (udiv:SI (match_operand:SI 1 "register_operand" "")
8705                  (match_operand:SI 2 "nonimmediate_operand" "")))
8706    (set (match_operand:SI 3 "register_operand" "")
8707         (umod:SI (match_dup 1) (match_dup 2)))
8708    (clobber (reg:CC FLAGS_REG))]
8709   "reload_completed"
8710   [(set (match_dup 3) (const_int 0))
8711    (parallel [(set (match_dup 0)
8712                    (udiv:SI (match_dup 1) (match_dup 2)))
8713               (set (match_dup 3)
8714                    (umod:SI (match_dup 1) (match_dup 2)))
8715               (use (match_dup 3))
8716               (clobber (reg:CC FLAGS_REG))])]
8717   "")
8718
8719 (define_expand "udivmodhi4"
8720   [(set (match_dup 4) (const_int 0))
8721    (parallel [(set (match_operand:HI 0 "register_operand" "")
8722                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8723                             (match_operand:HI 2 "nonimmediate_operand" "")))
8724               (set (match_operand:HI 3 "register_operand" "")
8725                    (umod:HI (match_dup 1) (match_dup 2)))
8726               (use (match_dup 4))
8727               (clobber (reg:CC FLAGS_REG))])]
8728   "TARGET_HIMODE_MATH"
8729   "operands[4] = gen_reg_rtx (HImode);")
8730
8731 (define_insn "*udivmodhi_noext"
8732   [(set (match_operand:HI 0 "register_operand" "=a")
8733         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8734                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8735    (set (match_operand:HI 3 "register_operand" "=d")
8736         (umod:HI (match_dup 1) (match_dup 2)))
8737    (use (match_operand:HI 4 "register_operand" "3"))
8738    (clobber (reg:CC FLAGS_REG))]
8739   ""
8740   "div{w}\t%2"
8741   [(set_attr "type" "idiv")
8742    (set_attr "mode" "HI")])
8743
8744 ;; We cannot use div/idiv for double division, because it causes
8745 ;; "division by zero" on the overflow and that's not what we expect
8746 ;; from truncate.  Because true (non truncating) double division is
8747 ;; never generated, we can't create this insn anyway.
8748 ;
8749 ;(define_insn ""
8750 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8751 ;       (truncate:SI
8752 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8753 ;                  (zero_extend:DI
8754 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8755 ;   (set (match_operand:SI 3 "register_operand" "=d")
8756 ;       (truncate:SI
8757 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8758 ;   (clobber (reg:CC FLAGS_REG))]
8759 ;  ""
8760 ;  "div{l}\t{%2, %0|%0, %2}"
8761 ;  [(set_attr "type" "idiv")])
8762 \f
8763 ;;- Logical AND instructions
8764
8765 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8766 ;; Note that this excludes ah.
8767
8768 (define_insn "*testdi_1_rex64"
8769   [(set (reg FLAGS_REG)
8770         (compare
8771           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8772                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8773           (const_int 0)))]
8774   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8775    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8776   "@
8777    test{l}\t{%k1, %k0|%k0, %k1}
8778    test{l}\t{%k1, %k0|%k0, %k1}
8779    test{q}\t{%1, %0|%0, %1}
8780    test{q}\t{%1, %0|%0, %1}
8781    test{q}\t{%1, %0|%0, %1}"
8782   [(set_attr "type" "test")
8783    (set_attr "modrm" "0,1,0,1,1")
8784    (set_attr "mode" "SI,SI,DI,DI,DI")
8785    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8786
8787 (define_insn "testsi_1"
8788   [(set (reg FLAGS_REG)
8789         (compare
8790           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8791                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8792           (const_int 0)))]
8793   "ix86_match_ccmode (insn, CCNOmode)
8794    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8795   "test{l}\t{%1, %0|%0, %1}"
8796   [(set_attr "type" "test")
8797    (set_attr "modrm" "0,1,1")
8798    (set_attr "mode" "SI")
8799    (set_attr "pent_pair" "uv,np,uv")])
8800
8801 (define_expand "testsi_ccno_1"
8802   [(set (reg:CCNO FLAGS_REG)
8803         (compare:CCNO
8804           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8805                   (match_operand:SI 1 "nonmemory_operand" ""))
8806           (const_int 0)))]
8807   ""
8808   "")
8809
8810 (define_insn "*testhi_1"
8811   [(set (reg FLAGS_REG)
8812         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8813                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8814                  (const_int 0)))]
8815   "ix86_match_ccmode (insn, CCNOmode)
8816    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8817   "test{w}\t{%1, %0|%0, %1}"
8818   [(set_attr "type" "test")
8819    (set_attr "modrm" "0,1,1")
8820    (set_attr "mode" "HI")
8821    (set_attr "pent_pair" "uv,np,uv")])
8822
8823 (define_expand "testqi_ccz_1"
8824   [(set (reg:CCZ FLAGS_REG)
8825         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8826                              (match_operand:QI 1 "nonmemory_operand" ""))
8827                  (const_int 0)))]
8828   ""
8829   "")
8830
8831 (define_insn "*testqi_1_maybe_si"
8832   [(set (reg FLAGS_REG)
8833         (compare
8834           (and:QI
8835             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8836             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8837           (const_int 0)))]
8838    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8839     && ix86_match_ccmode (insn,
8840                          CONST_INT_P (operands[1])
8841                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8842 {
8843   if (which_alternative == 3)
8844     {
8845       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8846         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8847       return "test{l}\t{%1, %k0|%k0, %1}";
8848     }
8849   return "test{b}\t{%1, %0|%0, %1}";
8850 }
8851   [(set_attr "type" "test")
8852    (set_attr "modrm" "0,1,1,1")
8853    (set_attr "mode" "QI,QI,QI,SI")
8854    (set_attr "pent_pair" "uv,np,uv,np")])
8855
8856 (define_insn "*testqi_1"
8857   [(set (reg FLAGS_REG)
8858         (compare
8859           (and:QI
8860             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8861             (match_operand:QI 1 "general_operand" "n,n,qn"))
8862           (const_int 0)))]
8863   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8864    && ix86_match_ccmode (insn, CCNOmode)"
8865   "test{b}\t{%1, %0|%0, %1}"
8866   [(set_attr "type" "test")
8867    (set_attr "modrm" "0,1,1")
8868    (set_attr "mode" "QI")
8869    (set_attr "pent_pair" "uv,np,uv")])
8870
8871 (define_expand "testqi_ext_ccno_0"
8872   [(set (reg:CCNO FLAGS_REG)
8873         (compare:CCNO
8874           (and:SI
8875             (zero_extract:SI
8876               (match_operand 0 "ext_register_operand" "")
8877               (const_int 8)
8878               (const_int 8))
8879             (match_operand 1 "const_int_operand" ""))
8880           (const_int 0)))]
8881   ""
8882   "")
8883
8884 (define_insn "*testqi_ext_0"
8885   [(set (reg FLAGS_REG)
8886         (compare
8887           (and:SI
8888             (zero_extract:SI
8889               (match_operand 0 "ext_register_operand" "Q")
8890               (const_int 8)
8891               (const_int 8))
8892             (match_operand 1 "const_int_operand" "n"))
8893           (const_int 0)))]
8894   "ix86_match_ccmode (insn, CCNOmode)"
8895   "test{b}\t{%1, %h0|%h0, %1}"
8896   [(set_attr "type" "test")
8897    (set_attr "mode" "QI")
8898    (set_attr "length_immediate" "1")
8899    (set_attr "pent_pair" "np")])
8900
8901 (define_insn "*testqi_ext_1"
8902   [(set (reg FLAGS_REG)
8903         (compare
8904           (and:SI
8905             (zero_extract:SI
8906               (match_operand 0 "ext_register_operand" "Q")
8907               (const_int 8)
8908               (const_int 8))
8909             (zero_extend:SI
8910               (match_operand:QI 1 "general_operand" "Qm")))
8911           (const_int 0)))]
8912   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8913    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8914   "test{b}\t{%1, %h0|%h0, %1}"
8915   [(set_attr "type" "test")
8916    (set_attr "mode" "QI")])
8917
8918 (define_insn "*testqi_ext_1_rex64"
8919   [(set (reg FLAGS_REG)
8920         (compare
8921           (and:SI
8922             (zero_extract:SI
8923               (match_operand 0 "ext_register_operand" "Q")
8924               (const_int 8)
8925               (const_int 8))
8926             (zero_extend:SI
8927               (match_operand:QI 1 "register_operand" "Q")))
8928           (const_int 0)))]
8929   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8930   "test{b}\t{%1, %h0|%h0, %1}"
8931   [(set_attr "type" "test")
8932    (set_attr "mode" "QI")])
8933
8934 (define_insn "*testqi_ext_2"
8935   [(set (reg FLAGS_REG)
8936         (compare
8937           (and:SI
8938             (zero_extract:SI
8939               (match_operand 0 "ext_register_operand" "Q")
8940               (const_int 8)
8941               (const_int 8))
8942             (zero_extract:SI
8943               (match_operand 1 "ext_register_operand" "Q")
8944               (const_int 8)
8945               (const_int 8)))
8946           (const_int 0)))]
8947   "ix86_match_ccmode (insn, CCNOmode)"
8948   "test{b}\t{%h1, %h0|%h0, %h1}"
8949   [(set_attr "type" "test")
8950    (set_attr "mode" "QI")])
8951
8952 ;; Combine likes to form bit extractions for some tests.  Humor it.
8953 (define_insn "*testqi_ext_3"
8954   [(set (reg FLAGS_REG)
8955         (compare (zero_extract:SI
8956                    (match_operand 0 "nonimmediate_operand" "rm")
8957                    (match_operand:SI 1 "const_int_operand" "")
8958                    (match_operand:SI 2 "const_int_operand" ""))
8959                  (const_int 0)))]
8960   "ix86_match_ccmode (insn, CCNOmode)
8961    && INTVAL (operands[1]) > 0
8962    && INTVAL (operands[2]) >= 0
8963    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8964    && (GET_MODE (operands[0]) == SImode
8965        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8966        || GET_MODE (operands[0]) == HImode
8967        || GET_MODE (operands[0]) == QImode)"
8968   "#")
8969
8970 (define_insn "*testqi_ext_3_rex64"
8971   [(set (reg FLAGS_REG)
8972         (compare (zero_extract:DI
8973                    (match_operand 0 "nonimmediate_operand" "rm")
8974                    (match_operand:DI 1 "const_int_operand" "")
8975                    (match_operand:DI 2 "const_int_operand" ""))
8976                  (const_int 0)))]
8977   "TARGET_64BIT
8978    && ix86_match_ccmode (insn, CCNOmode)
8979    && INTVAL (operands[1]) > 0
8980    && INTVAL (operands[2]) >= 0
8981    /* Ensure that resulting mask is zero or sign extended operand.  */
8982    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8983        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8984            && INTVAL (operands[1]) > 32))
8985    && (GET_MODE (operands[0]) == SImode
8986        || GET_MODE (operands[0]) == DImode
8987        || GET_MODE (operands[0]) == HImode
8988        || GET_MODE (operands[0]) == QImode)"
8989   "#")
8990
8991 (define_split
8992   [(set (match_operand 0 "flags_reg_operand" "")
8993         (match_operator 1 "compare_operator"
8994           [(zero_extract
8995              (match_operand 2 "nonimmediate_operand" "")
8996              (match_operand 3 "const_int_operand" "")
8997              (match_operand 4 "const_int_operand" ""))
8998            (const_int 0)]))]
8999   "ix86_match_ccmode (insn, CCNOmode)"
9000   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9001 {
9002   rtx val = operands[2];
9003   HOST_WIDE_INT len = INTVAL (operands[3]);
9004   HOST_WIDE_INT pos = INTVAL (operands[4]);
9005   HOST_WIDE_INT mask;
9006   enum machine_mode mode, submode;
9007
9008   mode = GET_MODE (val);
9009   if (MEM_P (val))
9010     {
9011       /* ??? Combine likes to put non-volatile mem extractions in QImode
9012          no matter the size of the test.  So find a mode that works.  */
9013       if (! MEM_VOLATILE_P (val))
9014         {
9015           mode = smallest_mode_for_size (pos + len, MODE_INT);
9016           val = adjust_address (val, mode, 0);
9017         }
9018     }
9019   else if (GET_CODE (val) == SUBREG
9020            && (submode = GET_MODE (SUBREG_REG (val)),
9021                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9022            && pos + len <= GET_MODE_BITSIZE (submode))
9023     {
9024       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9025       mode = submode;
9026       val = SUBREG_REG (val);
9027     }
9028   else if (mode == HImode && pos + len <= 8)
9029     {
9030       /* Small HImode tests can be converted to QImode.  */
9031       mode = QImode;
9032       val = gen_lowpart (QImode, val);
9033     }
9034
9035   if (len == HOST_BITS_PER_WIDE_INT)
9036     mask = -1;
9037   else
9038     mask = ((HOST_WIDE_INT)1 << len) - 1;
9039   mask <<= pos;
9040
9041   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9042 })
9043
9044 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9045 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9046 ;; this is relatively important trick.
9047 ;; Do the conversion only post-reload to avoid limiting of the register class
9048 ;; to QI regs.
9049 (define_split
9050   [(set (match_operand 0 "flags_reg_operand" "")
9051         (match_operator 1 "compare_operator"
9052           [(and (match_operand 2 "register_operand" "")
9053                 (match_operand 3 "const_int_operand" ""))
9054            (const_int 0)]))]
9055    "reload_completed
9056     && QI_REG_P (operands[2])
9057     && GET_MODE (operands[2]) != QImode
9058     && ((ix86_match_ccmode (insn, CCZmode)
9059          && !(INTVAL (operands[3]) & ~(255 << 8)))
9060         || (ix86_match_ccmode (insn, CCNOmode)
9061             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9062   [(set (match_dup 0)
9063         (match_op_dup 1
9064           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9065                    (match_dup 3))
9066            (const_int 0)]))]
9067   "operands[2] = gen_lowpart (SImode, operands[2]);
9068    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9069
9070 (define_split
9071   [(set (match_operand 0 "flags_reg_operand" "")
9072         (match_operator 1 "compare_operator"
9073           [(and (match_operand 2 "nonimmediate_operand" "")
9074                 (match_operand 3 "const_int_operand" ""))
9075            (const_int 0)]))]
9076    "reload_completed
9077     && GET_MODE (operands[2]) != QImode
9078     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9079     && ((ix86_match_ccmode (insn, CCZmode)
9080          && !(INTVAL (operands[3]) & ~255))
9081         || (ix86_match_ccmode (insn, CCNOmode)
9082             && !(INTVAL (operands[3]) & ~127)))"
9083   [(set (match_dup 0)
9084         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9085                          (const_int 0)]))]
9086   "operands[2] = gen_lowpart (QImode, operands[2]);
9087    operands[3] = gen_lowpart (QImode, operands[3]);")
9088
9089
9090 ;; %%% This used to optimize known byte-wide and operations to memory,
9091 ;; and sometimes to QImode registers.  If this is considered useful,
9092 ;; it should be done with splitters.
9093
9094 (define_expand "anddi3"
9095   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9096         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9097                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9098   "TARGET_64BIT"
9099   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9100
9101 (define_insn "*anddi_1_rex64"
9102   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9103         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9104                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9105    (clobber (reg:CC FLAGS_REG))]
9106   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9107 {
9108   switch (get_attr_type (insn))
9109     {
9110     case TYPE_IMOVX:
9111       {
9112         enum machine_mode mode;
9113
9114         gcc_assert (CONST_INT_P (operands[2]));
9115         if (INTVAL (operands[2]) == 0xff)
9116           mode = QImode;
9117         else
9118           {
9119             gcc_assert (INTVAL (operands[2]) == 0xffff);
9120             mode = HImode;
9121           }
9122
9123         operands[1] = gen_lowpart (mode, operands[1]);
9124         if (mode == QImode)
9125           return "movz{bq|x}\t{%1,%0|%0, %1}";
9126         else
9127           return "movz{wq|x}\t{%1,%0|%0, %1}";
9128       }
9129
9130     default:
9131       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9132       if (get_attr_mode (insn) == MODE_SI)
9133         return "and{l}\t{%k2, %k0|%k0, %k2}";
9134       else
9135         return "and{q}\t{%2, %0|%0, %2}";
9136     }
9137 }
9138   [(set_attr "type" "alu,alu,alu,imovx")
9139    (set_attr "length_immediate" "*,*,*,0")
9140    (set_attr "mode" "SI,DI,DI,DI")])
9141
9142 (define_insn "*anddi_2"
9143   [(set (reg FLAGS_REG)
9144         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9145                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9146                  (const_int 0)))
9147    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9148         (and:DI (match_dup 1) (match_dup 2)))]
9149   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9150    && ix86_binary_operator_ok (AND, DImode, operands)"
9151   "@
9152    and{l}\t{%k2, %k0|%k0, %k2}
9153    and{q}\t{%2, %0|%0, %2}
9154    and{q}\t{%2, %0|%0, %2}"
9155   [(set_attr "type" "alu")
9156    (set_attr "mode" "SI,DI,DI")])
9157
9158 (define_expand "andsi3"
9159   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9160         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9161                 (match_operand:SI 2 "general_operand" "")))]
9162   ""
9163   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9164
9165 (define_insn "*andsi_1"
9166   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9167         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9168                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9169    (clobber (reg:CC FLAGS_REG))]
9170   "ix86_binary_operator_ok (AND, SImode, operands)"
9171 {
9172   switch (get_attr_type (insn))
9173     {
9174     case TYPE_IMOVX:
9175       {
9176         enum machine_mode mode;
9177
9178         gcc_assert (CONST_INT_P (operands[2]));
9179         if (INTVAL (operands[2]) == 0xff)
9180           mode = QImode;
9181         else
9182           {
9183             gcc_assert (INTVAL (operands[2]) == 0xffff);
9184             mode = HImode;
9185           }
9186
9187         operands[1] = gen_lowpart (mode, operands[1]);
9188         if (mode == QImode)
9189           return "movz{bl|x}\t{%1,%0|%0, %1}";
9190         else
9191           return "movz{wl|x}\t{%1,%0|%0, %1}";
9192       }
9193
9194     default:
9195       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9196       return "and{l}\t{%2, %0|%0, %2}";
9197     }
9198 }
9199   [(set_attr "type" "alu,alu,imovx")
9200    (set_attr "length_immediate" "*,*,0")
9201    (set_attr "mode" "SI")])
9202
9203 (define_split
9204   [(set (match_operand 0 "register_operand" "")
9205         (and (match_dup 0)
9206              (const_int -65536)))
9207    (clobber (reg:CC FLAGS_REG))]
9208   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9209   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9210   "operands[1] = gen_lowpart (HImode, operands[0]);")
9211
9212 (define_split
9213   [(set (match_operand 0 "ext_register_operand" "")
9214         (and (match_dup 0)
9215              (const_int -256)))
9216    (clobber (reg:CC FLAGS_REG))]
9217   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9218   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9219   "operands[1] = gen_lowpart (QImode, operands[0]);")
9220
9221 (define_split
9222   [(set (match_operand 0 "ext_register_operand" "")
9223         (and (match_dup 0)
9224              (const_int -65281)))
9225    (clobber (reg:CC FLAGS_REG))]
9226   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9227   [(parallel [(set (zero_extract:SI (match_dup 0)
9228                                     (const_int 8)
9229                                     (const_int 8))
9230                    (xor:SI
9231                      (zero_extract:SI (match_dup 0)
9232                                       (const_int 8)
9233                                       (const_int 8))
9234                      (zero_extract:SI (match_dup 0)
9235                                       (const_int 8)
9236                                       (const_int 8))))
9237               (clobber (reg:CC FLAGS_REG))])]
9238   "operands[0] = gen_lowpart (SImode, operands[0]);")
9239
9240 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9241 (define_insn "*andsi_1_zext"
9242   [(set (match_operand:DI 0 "register_operand" "=r")
9243         (zero_extend:DI
9244           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9245                   (match_operand:SI 2 "general_operand" "g"))))
9246    (clobber (reg:CC FLAGS_REG))]
9247   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9248   "and{l}\t{%2, %k0|%k0, %2}"
9249   [(set_attr "type" "alu")
9250    (set_attr "mode" "SI")])
9251
9252 (define_insn "*andsi_2"
9253   [(set (reg FLAGS_REG)
9254         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9255                          (match_operand:SI 2 "general_operand" "g,ri"))
9256                  (const_int 0)))
9257    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9258         (and:SI (match_dup 1) (match_dup 2)))]
9259   "ix86_match_ccmode (insn, CCNOmode)
9260    && ix86_binary_operator_ok (AND, SImode, operands)"
9261   "and{l}\t{%2, %0|%0, %2}"
9262   [(set_attr "type" "alu")
9263    (set_attr "mode" "SI")])
9264
9265 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9266 (define_insn "*andsi_2_zext"
9267   [(set (reg FLAGS_REG)
9268         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9269                          (match_operand:SI 2 "general_operand" "g"))
9270                  (const_int 0)))
9271    (set (match_operand:DI 0 "register_operand" "=r")
9272         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9273   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9274    && ix86_binary_operator_ok (AND, SImode, operands)"
9275   "and{l}\t{%2, %k0|%k0, %2}"
9276   [(set_attr "type" "alu")
9277    (set_attr "mode" "SI")])
9278
9279 (define_expand "andhi3"
9280   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9281         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9282                 (match_operand:HI 2 "general_operand" "")))]
9283   "TARGET_HIMODE_MATH"
9284   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9285
9286 (define_insn "*andhi_1"
9287   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9288         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9289                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9290    (clobber (reg:CC FLAGS_REG))]
9291   "ix86_binary_operator_ok (AND, HImode, operands)"
9292 {
9293   switch (get_attr_type (insn))
9294     {
9295     case TYPE_IMOVX:
9296       gcc_assert (CONST_INT_P (operands[2]));
9297       gcc_assert (INTVAL (operands[2]) == 0xff);
9298       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9299
9300     default:
9301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9302
9303       return "and{w}\t{%2, %0|%0, %2}";
9304     }
9305 }
9306   [(set_attr "type" "alu,alu,imovx")
9307    (set_attr "length_immediate" "*,*,0")
9308    (set_attr "mode" "HI,HI,SI")])
9309
9310 (define_insn "*andhi_2"
9311   [(set (reg FLAGS_REG)
9312         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9313                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9314                  (const_int 0)))
9315    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9316         (and:HI (match_dup 1) (match_dup 2)))]
9317   "ix86_match_ccmode (insn, CCNOmode)
9318    && ix86_binary_operator_ok (AND, HImode, operands)"
9319   "and{w}\t{%2, %0|%0, %2}"
9320   [(set_attr "type" "alu")
9321    (set_attr "mode" "HI")])
9322
9323 (define_expand "andqi3"
9324   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9325         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9326                 (match_operand:QI 2 "general_operand" "")))]
9327   "TARGET_QIMODE_MATH"
9328   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9329
9330 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9331 (define_insn "*andqi_1"
9332   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9333         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9334                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9335    (clobber (reg:CC FLAGS_REG))]
9336   "ix86_binary_operator_ok (AND, QImode, operands)"
9337   "@
9338    and{b}\t{%2, %0|%0, %2}
9339    and{b}\t{%2, %0|%0, %2}
9340    and{l}\t{%k2, %k0|%k0, %k2}"
9341   [(set_attr "type" "alu")
9342    (set_attr "mode" "QI,QI,SI")])
9343
9344 (define_insn "*andqi_1_slp"
9345   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9346         (and:QI (match_dup 0)
9347                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9348    (clobber (reg:CC FLAGS_REG))]
9349   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9350    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9351   "and{b}\t{%1, %0|%0, %1}"
9352   [(set_attr "type" "alu1")
9353    (set_attr "mode" "QI")])
9354
9355 (define_insn "*andqi_2_maybe_si"
9356   [(set (reg FLAGS_REG)
9357         (compare (and:QI
9358                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9359                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9360                  (const_int 0)))
9361    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9362         (and:QI (match_dup 1) (match_dup 2)))]
9363   "ix86_binary_operator_ok (AND, QImode, operands)
9364    && ix86_match_ccmode (insn,
9365                          CONST_INT_P (operands[2])
9366                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9367 {
9368   if (which_alternative == 2)
9369     {
9370       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9371         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9372       return "and{l}\t{%2, %k0|%k0, %2}";
9373     }
9374   return "and{b}\t{%2, %0|%0, %2}";
9375 }
9376   [(set_attr "type" "alu")
9377    (set_attr "mode" "QI,QI,SI")])
9378
9379 (define_insn "*andqi_2"
9380   [(set (reg FLAGS_REG)
9381         (compare (and:QI
9382                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9383                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9384                  (const_int 0)))
9385    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9386         (and:QI (match_dup 1) (match_dup 2)))]
9387   "ix86_match_ccmode (insn, CCNOmode)
9388    && ix86_binary_operator_ok (AND, QImode, operands)"
9389   "and{b}\t{%2, %0|%0, %2}"
9390   [(set_attr "type" "alu")
9391    (set_attr "mode" "QI")])
9392
9393 (define_insn "*andqi_2_slp"
9394   [(set (reg FLAGS_REG)
9395         (compare (and:QI
9396                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9397                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9398                  (const_int 0)))
9399    (set (strict_low_part (match_dup 0))
9400         (and:QI (match_dup 0) (match_dup 1)))]
9401   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9402    && ix86_match_ccmode (insn, CCNOmode)
9403    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9404   "and{b}\t{%1, %0|%0, %1}"
9405   [(set_attr "type" "alu1")
9406    (set_attr "mode" "QI")])
9407
9408 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9409 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9410 ;; for a QImode operand, which of course failed.
9411
9412 (define_insn "andqi_ext_0"
9413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9414                          (const_int 8)
9415                          (const_int 8))
9416         (and:SI
9417           (zero_extract:SI
9418             (match_operand 1 "ext_register_operand" "0")
9419             (const_int 8)
9420             (const_int 8))
9421           (match_operand 2 "const_int_operand" "n")))
9422    (clobber (reg:CC FLAGS_REG))]
9423   ""
9424   "and{b}\t{%2, %h0|%h0, %2}"
9425   [(set_attr "type" "alu")
9426    (set_attr "length_immediate" "1")
9427    (set_attr "mode" "QI")])
9428
9429 ;; Generated by peephole translating test to and.  This shows up
9430 ;; often in fp comparisons.
9431
9432 (define_insn "*andqi_ext_0_cc"
9433   [(set (reg FLAGS_REG)
9434         (compare
9435           (and:SI
9436             (zero_extract:SI
9437               (match_operand 1 "ext_register_operand" "0")
9438               (const_int 8)
9439               (const_int 8))
9440             (match_operand 2 "const_int_operand" "n"))
9441           (const_int 0)))
9442    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9443                          (const_int 8)
9444                          (const_int 8))
9445         (and:SI
9446           (zero_extract:SI
9447             (match_dup 1)
9448             (const_int 8)
9449             (const_int 8))
9450           (match_dup 2)))]
9451   "ix86_match_ccmode (insn, CCNOmode)"
9452   "and{b}\t{%2, %h0|%h0, %2}"
9453   [(set_attr "type" "alu")
9454    (set_attr "length_immediate" "1")
9455    (set_attr "mode" "QI")])
9456
9457 (define_insn "*andqi_ext_1"
9458   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9459                          (const_int 8)
9460                          (const_int 8))
9461         (and:SI
9462           (zero_extract:SI
9463             (match_operand 1 "ext_register_operand" "0")
9464             (const_int 8)
9465             (const_int 8))
9466           (zero_extend:SI
9467             (match_operand:QI 2 "general_operand" "Qm"))))
9468    (clobber (reg:CC FLAGS_REG))]
9469   "!TARGET_64BIT"
9470   "and{b}\t{%2, %h0|%h0, %2}"
9471   [(set_attr "type" "alu")
9472    (set_attr "length_immediate" "0")
9473    (set_attr "mode" "QI")])
9474
9475 (define_insn "*andqi_ext_1_rex64"
9476   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9477                          (const_int 8)
9478                          (const_int 8))
9479         (and:SI
9480           (zero_extract:SI
9481             (match_operand 1 "ext_register_operand" "0")
9482             (const_int 8)
9483             (const_int 8))
9484           (zero_extend:SI
9485             (match_operand 2 "ext_register_operand" "Q"))))
9486    (clobber (reg:CC FLAGS_REG))]
9487   "TARGET_64BIT"
9488   "and{b}\t{%2, %h0|%h0, %2}"
9489   [(set_attr "type" "alu")
9490    (set_attr "length_immediate" "0")
9491    (set_attr "mode" "QI")])
9492
9493 (define_insn "*andqi_ext_2"
9494   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9495                          (const_int 8)
9496                          (const_int 8))
9497         (and:SI
9498           (zero_extract:SI
9499             (match_operand 1 "ext_register_operand" "%0")
9500             (const_int 8)
9501             (const_int 8))
9502           (zero_extract:SI
9503             (match_operand 2 "ext_register_operand" "Q")
9504             (const_int 8)
9505             (const_int 8))))
9506    (clobber (reg:CC FLAGS_REG))]
9507   ""
9508   "and{b}\t{%h2, %h0|%h0, %h2}"
9509   [(set_attr "type" "alu")
9510    (set_attr "length_immediate" "0")
9511    (set_attr "mode" "QI")])
9512
9513 ;; Convert wide AND instructions with immediate operand to shorter QImode
9514 ;; equivalents when possible.
9515 ;; Don't do the splitting with memory operands, since it introduces risk
9516 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9517 ;; for size, but that can (should?) be handled by generic code instead.
9518 (define_split
9519   [(set (match_operand 0 "register_operand" "")
9520         (and (match_operand 1 "register_operand" "")
9521              (match_operand 2 "const_int_operand" "")))
9522    (clobber (reg:CC FLAGS_REG))]
9523    "reload_completed
9524     && QI_REG_P (operands[0])
9525     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9526     && !(~INTVAL (operands[2]) & ~(255 << 8))
9527     && GET_MODE (operands[0]) != QImode"
9528   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9529                    (and:SI (zero_extract:SI (match_dup 1)
9530                                             (const_int 8) (const_int 8))
9531                            (match_dup 2)))
9532               (clobber (reg:CC FLAGS_REG))])]
9533   "operands[0] = gen_lowpart (SImode, operands[0]);
9534    operands[1] = gen_lowpart (SImode, operands[1]);
9535    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9536
9537 ;; Since AND can be encoded with sign extended immediate, this is only
9538 ;; profitable when 7th bit is not set.
9539 (define_split
9540   [(set (match_operand 0 "register_operand" "")
9541         (and (match_operand 1 "general_operand" "")
9542              (match_operand 2 "const_int_operand" "")))
9543    (clobber (reg:CC FLAGS_REG))]
9544    "reload_completed
9545     && ANY_QI_REG_P (operands[0])
9546     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9547     && !(~INTVAL (operands[2]) & ~255)
9548     && !(INTVAL (operands[2]) & 128)
9549     && GET_MODE (operands[0]) != QImode"
9550   [(parallel [(set (strict_low_part (match_dup 0))
9551                    (and:QI (match_dup 1)
9552                            (match_dup 2)))
9553               (clobber (reg:CC FLAGS_REG))])]
9554   "operands[0] = gen_lowpart (QImode, operands[0]);
9555    operands[1] = gen_lowpart (QImode, operands[1]);
9556    operands[2] = gen_lowpart (QImode, operands[2]);")
9557 \f
9558 ;; Logical inclusive OR instructions
9559
9560 ;; %%% This used to optimize known byte-wide and operations to memory.
9561 ;; If this is considered useful, it should be done with splitters.
9562
9563 (define_expand "iordi3"
9564   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9565         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9566                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9567   "TARGET_64BIT"
9568   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9569
9570 (define_insn "*iordi_1_rex64"
9571   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9572         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9573                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9574    (clobber (reg:CC FLAGS_REG))]
9575   "TARGET_64BIT
9576    && ix86_binary_operator_ok (IOR, DImode, operands)"
9577   "or{q}\t{%2, %0|%0, %2}"
9578   [(set_attr "type" "alu")
9579    (set_attr "mode" "DI")])
9580
9581 (define_insn "*iordi_2_rex64"
9582   [(set (reg FLAGS_REG)
9583         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9584                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9585                  (const_int 0)))
9586    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9587         (ior:DI (match_dup 1) (match_dup 2)))]
9588   "TARGET_64BIT
9589    && ix86_match_ccmode (insn, CCNOmode)
9590    && ix86_binary_operator_ok (IOR, DImode, operands)"
9591   "or{q}\t{%2, %0|%0, %2}"
9592   [(set_attr "type" "alu")
9593    (set_attr "mode" "DI")])
9594
9595 (define_insn "*iordi_3_rex64"
9596   [(set (reg FLAGS_REG)
9597         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9598                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9599                  (const_int 0)))
9600    (clobber (match_scratch:DI 0 "=r"))]
9601   "TARGET_64BIT
9602    && ix86_match_ccmode (insn, CCNOmode)
9603    && ix86_binary_operator_ok (IOR, DImode, operands)"
9604   "or{q}\t{%2, %0|%0, %2}"
9605   [(set_attr "type" "alu")
9606    (set_attr "mode" "DI")])
9607
9608
9609 (define_expand "iorsi3"
9610   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9611         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9612                 (match_operand:SI 2 "general_operand" "")))]
9613   ""
9614   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9615
9616 (define_insn "*iorsi_1"
9617   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9618         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9619                 (match_operand:SI 2 "general_operand" "ri,g")))
9620    (clobber (reg:CC FLAGS_REG))]
9621   "ix86_binary_operator_ok (IOR, SImode, operands)"
9622   "or{l}\t{%2, %0|%0, %2}"
9623   [(set_attr "type" "alu")
9624    (set_attr "mode" "SI")])
9625
9626 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9627 (define_insn "*iorsi_1_zext"
9628   [(set (match_operand:DI 0 "register_operand" "=r")
9629         (zero_extend:DI
9630           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9631                   (match_operand:SI 2 "general_operand" "g"))))
9632    (clobber (reg:CC FLAGS_REG))]
9633   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9634   "or{l}\t{%2, %k0|%k0, %2}"
9635   [(set_attr "type" "alu")
9636    (set_attr "mode" "SI")])
9637
9638 (define_insn "*iorsi_1_zext_imm"
9639   [(set (match_operand:DI 0 "register_operand" "=r")
9640         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9641                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9642    (clobber (reg:CC FLAGS_REG))]
9643   "TARGET_64BIT"
9644   "or{l}\t{%2, %k0|%k0, %2}"
9645   [(set_attr "type" "alu")
9646    (set_attr "mode" "SI")])
9647
9648 (define_insn "*iorsi_2"
9649   [(set (reg FLAGS_REG)
9650         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9651                          (match_operand:SI 2 "general_operand" "g,ri"))
9652                  (const_int 0)))
9653    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9654         (ior:SI (match_dup 1) (match_dup 2)))]
9655   "ix86_match_ccmode (insn, CCNOmode)
9656    && ix86_binary_operator_ok (IOR, SImode, operands)"
9657   "or{l}\t{%2, %0|%0, %2}"
9658   [(set_attr "type" "alu")
9659    (set_attr "mode" "SI")])
9660
9661 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9662 ;; ??? Special case for immediate operand is missing - it is tricky.
9663 (define_insn "*iorsi_2_zext"
9664   [(set (reg FLAGS_REG)
9665         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9666                          (match_operand:SI 2 "general_operand" "g"))
9667                  (const_int 0)))
9668    (set (match_operand:DI 0 "register_operand" "=r")
9669         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9670   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9671    && ix86_binary_operator_ok (IOR, SImode, operands)"
9672   "or{l}\t{%2, %k0|%k0, %2}"
9673   [(set_attr "type" "alu")
9674    (set_attr "mode" "SI")])
9675
9676 (define_insn "*iorsi_2_zext_imm"
9677   [(set (reg FLAGS_REG)
9678         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9679                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9680                  (const_int 0)))
9681    (set (match_operand:DI 0 "register_operand" "=r")
9682         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9683   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9684    && ix86_binary_operator_ok (IOR, SImode, operands)"
9685   "or{l}\t{%2, %k0|%k0, %2}"
9686   [(set_attr "type" "alu")
9687    (set_attr "mode" "SI")])
9688
9689 (define_insn "*iorsi_3"
9690   [(set (reg FLAGS_REG)
9691         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9692                          (match_operand:SI 2 "general_operand" "g"))
9693                  (const_int 0)))
9694    (clobber (match_scratch:SI 0 "=r"))]
9695   "ix86_match_ccmode (insn, CCNOmode)
9696    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9697   "or{l}\t{%2, %0|%0, %2}"
9698   [(set_attr "type" "alu")
9699    (set_attr "mode" "SI")])
9700
9701 (define_expand "iorhi3"
9702   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9703         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9704                 (match_operand:HI 2 "general_operand" "")))]
9705   "TARGET_HIMODE_MATH"
9706   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9707
9708 (define_insn "*iorhi_1"
9709   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9710         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9711                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9712    (clobber (reg:CC FLAGS_REG))]
9713   "ix86_binary_operator_ok (IOR, HImode, operands)"
9714   "or{w}\t{%2, %0|%0, %2}"
9715   [(set_attr "type" "alu")
9716    (set_attr "mode" "HI")])
9717
9718 (define_insn "*iorhi_2"
9719   [(set (reg FLAGS_REG)
9720         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9721                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9722                  (const_int 0)))
9723    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9724         (ior:HI (match_dup 1) (match_dup 2)))]
9725   "ix86_match_ccmode (insn, CCNOmode)
9726    && ix86_binary_operator_ok (IOR, HImode, operands)"
9727   "or{w}\t{%2, %0|%0, %2}"
9728   [(set_attr "type" "alu")
9729    (set_attr "mode" "HI")])
9730
9731 (define_insn "*iorhi_3"
9732   [(set (reg FLAGS_REG)
9733         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9734                          (match_operand:HI 2 "general_operand" "rmn"))
9735                  (const_int 0)))
9736    (clobber (match_scratch:HI 0 "=r"))]
9737   "ix86_match_ccmode (insn, CCNOmode)
9738    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9739   "or{w}\t{%2, %0|%0, %2}"
9740   [(set_attr "type" "alu")
9741    (set_attr "mode" "HI")])
9742
9743 (define_expand "iorqi3"
9744   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9745         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9746                 (match_operand:QI 2 "general_operand" "")))]
9747   "TARGET_QIMODE_MATH"
9748   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9749
9750 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9751 (define_insn "*iorqi_1"
9752   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9753         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9754                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9755    (clobber (reg:CC FLAGS_REG))]
9756   "ix86_binary_operator_ok (IOR, QImode, operands)"
9757   "@
9758    or{b}\t{%2, %0|%0, %2}
9759    or{b}\t{%2, %0|%0, %2}
9760    or{l}\t{%k2, %k0|%k0, %k2}"
9761   [(set_attr "type" "alu")
9762    (set_attr "mode" "QI,QI,SI")])
9763
9764 (define_insn "*iorqi_1_slp"
9765   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9766         (ior:QI (match_dup 0)
9767                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9768    (clobber (reg:CC FLAGS_REG))]
9769   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9770    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9771   "or{b}\t{%1, %0|%0, %1}"
9772   [(set_attr "type" "alu1")
9773    (set_attr "mode" "QI")])
9774
9775 (define_insn "*iorqi_2"
9776   [(set (reg FLAGS_REG)
9777         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9778                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9779                  (const_int 0)))
9780    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9781         (ior:QI (match_dup 1) (match_dup 2)))]
9782   "ix86_match_ccmode (insn, CCNOmode)
9783    && ix86_binary_operator_ok (IOR, QImode, operands)"
9784   "or{b}\t{%2, %0|%0, %2}"
9785   [(set_attr "type" "alu")
9786    (set_attr "mode" "QI")])
9787
9788 (define_insn "*iorqi_2_slp"
9789   [(set (reg FLAGS_REG)
9790         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9791                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9792                  (const_int 0)))
9793    (set (strict_low_part (match_dup 0))
9794         (ior:QI (match_dup 0) (match_dup 1)))]
9795   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9796    && ix86_match_ccmode (insn, CCNOmode)
9797    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9798   "or{b}\t{%1, %0|%0, %1}"
9799   [(set_attr "type" "alu1")
9800    (set_attr "mode" "QI")])
9801
9802 (define_insn "*iorqi_3"
9803   [(set (reg FLAGS_REG)
9804         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9805                          (match_operand:QI 2 "general_operand" "qmn"))
9806                  (const_int 0)))
9807    (clobber (match_scratch:QI 0 "=q"))]
9808   "ix86_match_ccmode (insn, CCNOmode)
9809    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9810   "or{b}\t{%2, %0|%0, %2}"
9811   [(set_attr "type" "alu")
9812    (set_attr "mode" "QI")])
9813
9814 (define_insn "*iorqi_ext_0"
9815   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9816                          (const_int 8)
9817                          (const_int 8))
9818         (ior:SI
9819           (zero_extract:SI
9820             (match_operand 1 "ext_register_operand" "0")
9821             (const_int 8)
9822             (const_int 8))
9823           (match_operand 2 "const_int_operand" "n")))
9824    (clobber (reg:CC FLAGS_REG))]
9825   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9826   "or{b}\t{%2, %h0|%h0, %2}"
9827   [(set_attr "type" "alu")
9828    (set_attr "length_immediate" "1")
9829    (set_attr "mode" "QI")])
9830
9831 (define_insn "*iorqi_ext_1"
9832   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9833                          (const_int 8)
9834                          (const_int 8))
9835         (ior:SI
9836           (zero_extract:SI
9837             (match_operand 1 "ext_register_operand" "0")
9838             (const_int 8)
9839             (const_int 8))
9840           (zero_extend:SI
9841             (match_operand:QI 2 "general_operand" "Qm"))))
9842    (clobber (reg:CC FLAGS_REG))]
9843   "!TARGET_64BIT
9844    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9845   "or{b}\t{%2, %h0|%h0, %2}"
9846   [(set_attr "type" "alu")
9847    (set_attr "length_immediate" "0")
9848    (set_attr "mode" "QI")])
9849
9850 (define_insn "*iorqi_ext_1_rex64"
9851   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9852                          (const_int 8)
9853                          (const_int 8))
9854         (ior:SI
9855           (zero_extract:SI
9856             (match_operand 1 "ext_register_operand" "0")
9857             (const_int 8)
9858             (const_int 8))
9859           (zero_extend:SI
9860             (match_operand 2 "ext_register_operand" "Q"))))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "TARGET_64BIT
9863    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9864   "or{b}\t{%2, %h0|%h0, %2}"
9865   [(set_attr "type" "alu")
9866    (set_attr "length_immediate" "0")
9867    (set_attr "mode" "QI")])
9868
9869 (define_insn "*iorqi_ext_2"
9870   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9871                          (const_int 8)
9872                          (const_int 8))
9873         (ior:SI
9874           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9875                            (const_int 8)
9876                            (const_int 8))
9877           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9878                            (const_int 8)
9879                            (const_int 8))))
9880    (clobber (reg:CC FLAGS_REG))]
9881   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9882   "ior{b}\t{%h2, %h0|%h0, %h2}"
9883   [(set_attr "type" "alu")
9884    (set_attr "length_immediate" "0")
9885    (set_attr "mode" "QI")])
9886
9887 (define_split
9888   [(set (match_operand 0 "register_operand" "")
9889         (ior (match_operand 1 "register_operand" "")
9890              (match_operand 2 "const_int_operand" "")))
9891    (clobber (reg:CC FLAGS_REG))]
9892    "reload_completed
9893     && QI_REG_P (operands[0])
9894     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9895     && !(INTVAL (operands[2]) & ~(255 << 8))
9896     && GET_MODE (operands[0]) != QImode"
9897   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9898                    (ior:SI (zero_extract:SI (match_dup 1)
9899                                             (const_int 8) (const_int 8))
9900                            (match_dup 2)))
9901               (clobber (reg:CC FLAGS_REG))])]
9902   "operands[0] = gen_lowpart (SImode, operands[0]);
9903    operands[1] = gen_lowpart (SImode, operands[1]);
9904    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9905
9906 ;; Since OR can be encoded with sign extended immediate, this is only
9907 ;; profitable when 7th bit is set.
9908 (define_split
9909   [(set (match_operand 0 "register_operand" "")
9910         (ior (match_operand 1 "general_operand" "")
9911              (match_operand 2 "const_int_operand" "")))
9912    (clobber (reg:CC FLAGS_REG))]
9913    "reload_completed
9914     && ANY_QI_REG_P (operands[0])
9915     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9916     && !(INTVAL (operands[2]) & ~255)
9917     && (INTVAL (operands[2]) & 128)
9918     && GET_MODE (operands[0]) != QImode"
9919   [(parallel [(set (strict_low_part (match_dup 0))
9920                    (ior:QI (match_dup 1)
9921                            (match_dup 2)))
9922               (clobber (reg:CC FLAGS_REG))])]
9923   "operands[0] = gen_lowpart (QImode, operands[0]);
9924    operands[1] = gen_lowpart (QImode, operands[1]);
9925    operands[2] = gen_lowpart (QImode, operands[2]);")
9926 \f
9927 ;; Logical XOR instructions
9928
9929 ;; %%% This used to optimize known byte-wide and operations to memory.
9930 ;; If this is considered useful, it should be done with splitters.
9931
9932 (define_expand "xordi3"
9933   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9934         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9935                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9936   "TARGET_64BIT"
9937   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9938
9939 (define_insn "*xordi_1_rex64"
9940   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9941         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9942                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9943    (clobber (reg:CC FLAGS_REG))]
9944   "TARGET_64BIT
9945    && ix86_binary_operator_ok (XOR, DImode, operands)"
9946   "xor{q}\t{%2, %0|%0, %2}"
9947   [(set_attr "type" "alu")
9948    (set_attr "mode" "DI")])
9949
9950 (define_insn "*xordi_2_rex64"
9951   [(set (reg FLAGS_REG)
9952         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9953                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9954                  (const_int 0)))
9955    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9956         (xor:DI (match_dup 1) (match_dup 2)))]
9957   "TARGET_64BIT
9958    && ix86_match_ccmode (insn, CCNOmode)
9959    && ix86_binary_operator_ok (XOR, DImode, operands)"
9960   "xor{q}\t{%2, %0|%0, %2}"
9961   [(set_attr "type" "alu")
9962    (set_attr "mode" "DI")])
9963
9964 (define_insn "*xordi_3_rex64"
9965   [(set (reg FLAGS_REG)
9966         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9967                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9968                  (const_int 0)))
9969    (clobber (match_scratch:DI 0 "=r"))]
9970   "TARGET_64BIT
9971    && ix86_match_ccmode (insn, CCNOmode)
9972    && ix86_binary_operator_ok (XOR, DImode, operands)"
9973   "xor{q}\t{%2, %0|%0, %2}"
9974   [(set_attr "type" "alu")
9975    (set_attr "mode" "DI")])
9976
9977 (define_expand "xorsi3"
9978   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9979         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9980                 (match_operand:SI 2 "general_operand" "")))]
9981   ""
9982   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9983
9984 (define_insn "*xorsi_1"
9985   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9986         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9987                 (match_operand:SI 2 "general_operand" "ri,rm")))
9988    (clobber (reg:CC FLAGS_REG))]
9989   "ix86_binary_operator_ok (XOR, SImode, operands)"
9990   "xor{l}\t{%2, %0|%0, %2}"
9991   [(set_attr "type" "alu")
9992    (set_attr "mode" "SI")])
9993
9994 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9995 ;; Add speccase for immediates
9996 (define_insn "*xorsi_1_zext"
9997   [(set (match_operand:DI 0 "register_operand" "=r")
9998         (zero_extend:DI
9999           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10000                   (match_operand:SI 2 "general_operand" "g"))))
10001    (clobber (reg:CC FLAGS_REG))]
10002   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10003   "xor{l}\t{%2, %k0|%k0, %2}"
10004   [(set_attr "type" "alu")
10005    (set_attr "mode" "SI")])
10006
10007 (define_insn "*xorsi_1_zext_imm"
10008   [(set (match_operand:DI 0 "register_operand" "=r")
10009         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10010                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10011    (clobber (reg:CC FLAGS_REG))]
10012   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10013   "xor{l}\t{%2, %k0|%k0, %2}"
10014   [(set_attr "type" "alu")
10015    (set_attr "mode" "SI")])
10016
10017 (define_insn "*xorsi_2"
10018   [(set (reg FLAGS_REG)
10019         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10020                          (match_operand:SI 2 "general_operand" "g,ri"))
10021                  (const_int 0)))
10022    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10023         (xor:SI (match_dup 1) (match_dup 2)))]
10024   "ix86_match_ccmode (insn, CCNOmode)
10025    && ix86_binary_operator_ok (XOR, SImode, operands)"
10026   "xor{l}\t{%2, %0|%0, %2}"
10027   [(set_attr "type" "alu")
10028    (set_attr "mode" "SI")])
10029
10030 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10031 ;; ??? Special case for immediate operand is missing - it is tricky.
10032 (define_insn "*xorsi_2_zext"
10033   [(set (reg FLAGS_REG)
10034         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10035                          (match_operand:SI 2 "general_operand" "g"))
10036                  (const_int 0)))
10037    (set (match_operand:DI 0 "register_operand" "=r")
10038         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10039   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10040    && ix86_binary_operator_ok (XOR, SImode, operands)"
10041   "xor{l}\t{%2, %k0|%k0, %2}"
10042   [(set_attr "type" "alu")
10043    (set_attr "mode" "SI")])
10044
10045 (define_insn "*xorsi_2_zext_imm"
10046   [(set (reg FLAGS_REG)
10047         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10048                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10049                  (const_int 0)))
10050    (set (match_operand:DI 0 "register_operand" "=r")
10051         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10052   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10053    && ix86_binary_operator_ok (XOR, SImode, operands)"
10054   "xor{l}\t{%2, %k0|%k0, %2}"
10055   [(set_attr "type" "alu")
10056    (set_attr "mode" "SI")])
10057
10058 (define_insn "*xorsi_3"
10059   [(set (reg FLAGS_REG)
10060         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10061                          (match_operand:SI 2 "general_operand" "g"))
10062                  (const_int 0)))
10063    (clobber (match_scratch:SI 0 "=r"))]
10064   "ix86_match_ccmode (insn, CCNOmode)
10065    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10066   "xor{l}\t{%2, %0|%0, %2}"
10067   [(set_attr "type" "alu")
10068    (set_attr "mode" "SI")])
10069
10070 (define_expand "xorhi3"
10071   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10072         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10073                 (match_operand:HI 2 "general_operand" "")))]
10074   "TARGET_HIMODE_MATH"
10075   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10076
10077 (define_insn "*xorhi_1"
10078   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10079         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10080                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10081    (clobber (reg:CC FLAGS_REG))]
10082   "ix86_binary_operator_ok (XOR, HImode, operands)"
10083   "xor{w}\t{%2, %0|%0, %2}"
10084   [(set_attr "type" "alu")
10085    (set_attr "mode" "HI")])
10086
10087 (define_insn "*xorhi_2"
10088   [(set (reg FLAGS_REG)
10089         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10090                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10091                  (const_int 0)))
10092    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10093         (xor:HI (match_dup 1) (match_dup 2)))]
10094   "ix86_match_ccmode (insn, CCNOmode)
10095    && ix86_binary_operator_ok (XOR, HImode, operands)"
10096   "xor{w}\t{%2, %0|%0, %2}"
10097   [(set_attr "type" "alu")
10098    (set_attr "mode" "HI")])
10099
10100 (define_insn "*xorhi_3"
10101   [(set (reg FLAGS_REG)
10102         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10103                          (match_operand:HI 2 "general_operand" "rmn"))
10104                  (const_int 0)))
10105    (clobber (match_scratch:HI 0 "=r"))]
10106   "ix86_match_ccmode (insn, CCNOmode)
10107    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10108   "xor{w}\t{%2, %0|%0, %2}"
10109   [(set_attr "type" "alu")
10110    (set_attr "mode" "HI")])
10111
10112 (define_expand "xorqi3"
10113   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10114         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10115                 (match_operand:QI 2 "general_operand" "")))]
10116   "TARGET_QIMODE_MATH"
10117   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10118
10119 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10120 (define_insn "*xorqi_1"
10121   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10122         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10123                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10124    (clobber (reg:CC FLAGS_REG))]
10125   "ix86_binary_operator_ok (XOR, QImode, operands)"
10126   "@
10127    xor{b}\t{%2, %0|%0, %2}
10128    xor{b}\t{%2, %0|%0, %2}
10129    xor{l}\t{%k2, %k0|%k0, %k2}"
10130   [(set_attr "type" "alu")
10131    (set_attr "mode" "QI,QI,SI")])
10132
10133 (define_insn "*xorqi_1_slp"
10134   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10135         (xor:QI (match_dup 0)
10136                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10137    (clobber (reg:CC FLAGS_REG))]
10138   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10139    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10140   "xor{b}\t{%1, %0|%0, %1}"
10141   [(set_attr "type" "alu1")
10142    (set_attr "mode" "QI")])
10143
10144 (define_insn "*xorqi_ext_0"
10145   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10146                          (const_int 8)
10147                          (const_int 8))
10148         (xor:SI
10149           (zero_extract:SI
10150             (match_operand 1 "ext_register_operand" "0")
10151             (const_int 8)
10152             (const_int 8))
10153           (match_operand 2 "const_int_operand" "n")))
10154    (clobber (reg:CC FLAGS_REG))]
10155   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10156   "xor{b}\t{%2, %h0|%h0, %2}"
10157   [(set_attr "type" "alu")
10158    (set_attr "length_immediate" "1")
10159    (set_attr "mode" "QI")])
10160
10161 (define_insn "*xorqi_ext_1"
10162   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10163                          (const_int 8)
10164                          (const_int 8))
10165         (xor:SI
10166           (zero_extract:SI
10167             (match_operand 1 "ext_register_operand" "0")
10168             (const_int 8)
10169             (const_int 8))
10170           (zero_extend:SI
10171             (match_operand:QI 2 "general_operand" "Qm"))))
10172    (clobber (reg:CC FLAGS_REG))]
10173   "!TARGET_64BIT
10174    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10175   "xor{b}\t{%2, %h0|%h0, %2}"
10176   [(set_attr "type" "alu")
10177    (set_attr "length_immediate" "0")
10178    (set_attr "mode" "QI")])
10179
10180 (define_insn "*xorqi_ext_1_rex64"
10181   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10182                          (const_int 8)
10183                          (const_int 8))
10184         (xor:SI
10185           (zero_extract:SI
10186             (match_operand 1 "ext_register_operand" "0")
10187             (const_int 8)
10188             (const_int 8))
10189           (zero_extend:SI
10190             (match_operand 2 "ext_register_operand" "Q"))))
10191    (clobber (reg:CC FLAGS_REG))]
10192   "TARGET_64BIT
10193    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10194   "xor{b}\t{%2, %h0|%h0, %2}"
10195   [(set_attr "type" "alu")
10196    (set_attr "length_immediate" "0")
10197    (set_attr "mode" "QI")])
10198
10199 (define_insn "*xorqi_ext_2"
10200   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10201                          (const_int 8)
10202                          (const_int 8))
10203         (xor:SI
10204           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10205                            (const_int 8)
10206                            (const_int 8))
10207           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10208                            (const_int 8)
10209                            (const_int 8))))
10210    (clobber (reg:CC FLAGS_REG))]
10211   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10212   "xor{b}\t{%h2, %h0|%h0, %h2}"
10213   [(set_attr "type" "alu")
10214    (set_attr "length_immediate" "0")
10215    (set_attr "mode" "QI")])
10216
10217 (define_insn "*xorqi_cc_1"
10218   [(set (reg FLAGS_REG)
10219         (compare
10220           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10221                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10222           (const_int 0)))
10223    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10224         (xor:QI (match_dup 1) (match_dup 2)))]
10225   "ix86_match_ccmode (insn, CCNOmode)
10226    && ix86_binary_operator_ok (XOR, QImode, operands)"
10227   "xor{b}\t{%2, %0|%0, %2}"
10228   [(set_attr "type" "alu")
10229    (set_attr "mode" "QI")])
10230
10231 (define_insn "*xorqi_2_slp"
10232   [(set (reg FLAGS_REG)
10233         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10234                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10235                  (const_int 0)))
10236    (set (strict_low_part (match_dup 0))
10237         (xor:QI (match_dup 0) (match_dup 1)))]
10238   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10239    && ix86_match_ccmode (insn, CCNOmode)
10240    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10241   "xor{b}\t{%1, %0|%0, %1}"
10242   [(set_attr "type" "alu1")
10243    (set_attr "mode" "QI")])
10244
10245 (define_insn "*xorqi_cc_2"
10246   [(set (reg FLAGS_REG)
10247         (compare
10248           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10249                   (match_operand:QI 2 "general_operand" "qmn"))
10250           (const_int 0)))
10251    (clobber (match_scratch:QI 0 "=q"))]
10252   "ix86_match_ccmode (insn, CCNOmode)
10253    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10254   "xor{b}\t{%2, %0|%0, %2}"
10255   [(set_attr "type" "alu")
10256    (set_attr "mode" "QI")])
10257
10258 (define_insn "*xorqi_cc_ext_1"
10259   [(set (reg FLAGS_REG)
10260         (compare
10261           (xor:SI
10262             (zero_extract:SI
10263               (match_operand 1 "ext_register_operand" "0")
10264               (const_int 8)
10265               (const_int 8))
10266             (match_operand:QI 2 "general_operand" "qmn"))
10267           (const_int 0)))
10268    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10269                          (const_int 8)
10270                          (const_int 8))
10271         (xor:SI
10272           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10273           (match_dup 2)))]
10274   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10275   "xor{b}\t{%2, %h0|%h0, %2}"
10276   [(set_attr "type" "alu")
10277    (set_attr "mode" "QI")])
10278
10279 (define_insn "*xorqi_cc_ext_1_rex64"
10280   [(set (reg FLAGS_REG)
10281         (compare
10282           (xor:SI
10283             (zero_extract:SI
10284               (match_operand 1 "ext_register_operand" "0")
10285               (const_int 8)
10286               (const_int 8))
10287             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10288           (const_int 0)))
10289    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10290                          (const_int 8)
10291                          (const_int 8))
10292         (xor:SI
10293           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10294           (match_dup 2)))]
10295   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10296   "xor{b}\t{%2, %h0|%h0, %2}"
10297   [(set_attr "type" "alu")
10298    (set_attr "mode" "QI")])
10299
10300 (define_expand "xorqi_cc_ext_1"
10301   [(parallel [
10302      (set (reg:CCNO FLAGS_REG)
10303           (compare:CCNO
10304             (xor:SI
10305               (zero_extract:SI
10306                 (match_operand 1 "ext_register_operand" "")
10307                 (const_int 8)
10308                 (const_int 8))
10309               (match_operand:QI 2 "general_operand" ""))
10310             (const_int 0)))
10311      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10312                            (const_int 8)
10313                            (const_int 8))
10314           (xor:SI
10315             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10316             (match_dup 2)))])]
10317   ""
10318   "")
10319
10320 (define_split
10321   [(set (match_operand 0 "register_operand" "")
10322         (xor (match_operand 1 "register_operand" "")
10323              (match_operand 2 "const_int_operand" "")))
10324    (clobber (reg:CC FLAGS_REG))]
10325    "reload_completed
10326     && QI_REG_P (operands[0])
10327     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10328     && !(INTVAL (operands[2]) & ~(255 << 8))
10329     && GET_MODE (operands[0]) != QImode"
10330   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10331                    (xor:SI (zero_extract:SI (match_dup 1)
10332                                             (const_int 8) (const_int 8))
10333                            (match_dup 2)))
10334               (clobber (reg:CC FLAGS_REG))])]
10335   "operands[0] = gen_lowpart (SImode, operands[0]);
10336    operands[1] = gen_lowpart (SImode, operands[1]);
10337    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10338
10339 ;; Since XOR can be encoded with sign extended immediate, this is only
10340 ;; profitable when 7th bit is set.
10341 (define_split
10342   [(set (match_operand 0 "register_operand" "")
10343         (xor (match_operand 1 "general_operand" "")
10344              (match_operand 2 "const_int_operand" "")))
10345    (clobber (reg:CC FLAGS_REG))]
10346    "reload_completed
10347     && ANY_QI_REG_P (operands[0])
10348     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10349     && !(INTVAL (operands[2]) & ~255)
10350     && (INTVAL (operands[2]) & 128)
10351     && GET_MODE (operands[0]) != QImode"
10352   [(parallel [(set (strict_low_part (match_dup 0))
10353                    (xor:QI (match_dup 1)
10354                            (match_dup 2)))
10355               (clobber (reg:CC FLAGS_REG))])]
10356   "operands[0] = gen_lowpart (QImode, operands[0]);
10357    operands[1] = gen_lowpart (QImode, operands[1]);
10358    operands[2] = gen_lowpart (QImode, operands[2]);")
10359 \f
10360 ;; Negation instructions
10361
10362 (define_expand "negti2"
10363   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10364         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10365   "TARGET_64BIT"
10366   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10367
10368 (define_insn "*negti2_1"
10369   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10370         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10371    (clobber (reg:CC FLAGS_REG))]
10372   "TARGET_64BIT
10373    && ix86_unary_operator_ok (NEG, TImode, operands)"
10374   "#")
10375
10376 (define_split
10377   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10378         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10379    (clobber (reg:CC FLAGS_REG))]
10380   "TARGET_64BIT && reload_completed"
10381   [(parallel
10382     [(set (reg:CCZ FLAGS_REG)
10383           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10384      (set (match_dup 0) (neg:DI (match_dup 1)))])
10385    (parallel
10386     [(set (match_dup 2)
10387           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10388                             (match_dup 3))
10389                    (const_int 0)))
10390      (clobber (reg:CC FLAGS_REG))])
10391    (parallel
10392     [(set (match_dup 2)
10393           (neg:DI (match_dup 2)))
10394      (clobber (reg:CC FLAGS_REG))])]
10395   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10396
10397 (define_expand "negdi2"
10398   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10399         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10400   ""
10401   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10402
10403 (define_insn "*negdi2_1"
10404   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10405         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10406    (clobber (reg:CC FLAGS_REG))]
10407   "!TARGET_64BIT
10408    && ix86_unary_operator_ok (NEG, DImode, operands)"
10409   "#")
10410
10411 (define_split
10412   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10413         (neg:DI (match_operand:DI 1 "general_operand" "")))
10414    (clobber (reg:CC FLAGS_REG))]
10415   "!TARGET_64BIT && reload_completed"
10416   [(parallel
10417     [(set (reg:CCZ FLAGS_REG)
10418           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10419      (set (match_dup 0) (neg:SI (match_dup 1)))])
10420    (parallel
10421     [(set (match_dup 2)
10422           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10423                             (match_dup 3))
10424                    (const_int 0)))
10425      (clobber (reg:CC FLAGS_REG))])
10426    (parallel
10427     [(set (match_dup 2)
10428           (neg:SI (match_dup 2)))
10429      (clobber (reg:CC FLAGS_REG))])]
10430   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10431
10432 (define_insn "*negdi2_1_rex64"
10433   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10434         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10437   "neg{q}\t%0"
10438   [(set_attr "type" "negnot")
10439    (set_attr "mode" "DI")])
10440
10441 ;; The problem with neg is that it does not perform (compare x 0),
10442 ;; it really performs (compare 0 x), which leaves us with the zero
10443 ;; flag being the only useful item.
10444
10445 (define_insn "*negdi2_cmpz_rex64"
10446   [(set (reg:CCZ FLAGS_REG)
10447         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10448                      (const_int 0)))
10449    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10450         (neg:DI (match_dup 1)))]
10451   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10452   "neg{q}\t%0"
10453   [(set_attr "type" "negnot")
10454    (set_attr "mode" "DI")])
10455
10456
10457 (define_expand "negsi2"
10458   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10459         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10460   ""
10461   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10462
10463 (define_insn "*negsi2_1"
10464   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10465         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10466    (clobber (reg:CC FLAGS_REG))]
10467   "ix86_unary_operator_ok (NEG, SImode, operands)"
10468   "neg{l}\t%0"
10469   [(set_attr "type" "negnot")
10470    (set_attr "mode" "SI")])
10471
10472 ;; Combine is quite creative about this pattern.
10473 (define_insn "*negsi2_1_zext"
10474   [(set (match_operand:DI 0 "register_operand" "=r")
10475         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10476                                         (const_int 32)))
10477                      (const_int 32)))
10478    (clobber (reg:CC FLAGS_REG))]
10479   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10480   "neg{l}\t%k0"
10481   [(set_attr "type" "negnot")
10482    (set_attr "mode" "SI")])
10483
10484 ;; The problem with neg is that it does not perform (compare x 0),
10485 ;; it really performs (compare 0 x), which leaves us with the zero
10486 ;; flag being the only useful item.
10487
10488 (define_insn "*negsi2_cmpz"
10489   [(set (reg:CCZ FLAGS_REG)
10490         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10491                      (const_int 0)))
10492    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10493         (neg:SI (match_dup 1)))]
10494   "ix86_unary_operator_ok (NEG, SImode, operands)"
10495   "neg{l}\t%0"
10496   [(set_attr "type" "negnot")
10497    (set_attr "mode" "SI")])
10498
10499 (define_insn "*negsi2_cmpz_zext"
10500   [(set (reg:CCZ FLAGS_REG)
10501         (compare:CCZ (lshiftrt:DI
10502                        (neg:DI (ashift:DI
10503                                  (match_operand:DI 1 "register_operand" "0")
10504                                  (const_int 32)))
10505                        (const_int 32))
10506                      (const_int 0)))
10507    (set (match_operand:DI 0 "register_operand" "=r")
10508         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10509                                         (const_int 32)))
10510                      (const_int 32)))]
10511   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10512   "neg{l}\t%k0"
10513   [(set_attr "type" "negnot")
10514    (set_attr "mode" "SI")])
10515
10516 (define_expand "neghi2"
10517   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10518         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10519   "TARGET_HIMODE_MATH"
10520   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10521
10522 (define_insn "*neghi2_1"
10523   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10524         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10525    (clobber (reg:CC FLAGS_REG))]
10526   "ix86_unary_operator_ok (NEG, HImode, operands)"
10527   "neg{w}\t%0"
10528   [(set_attr "type" "negnot")
10529    (set_attr "mode" "HI")])
10530
10531 (define_insn "*neghi2_cmpz"
10532   [(set (reg:CCZ FLAGS_REG)
10533         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10534                      (const_int 0)))
10535    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10536         (neg:HI (match_dup 1)))]
10537   "ix86_unary_operator_ok (NEG, HImode, operands)"
10538   "neg{w}\t%0"
10539   [(set_attr "type" "negnot")
10540    (set_attr "mode" "HI")])
10541
10542 (define_expand "negqi2"
10543   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10544         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10545   "TARGET_QIMODE_MATH"
10546   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10547
10548 (define_insn "*negqi2_1"
10549   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10550         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10551    (clobber (reg:CC FLAGS_REG))]
10552   "ix86_unary_operator_ok (NEG, QImode, operands)"
10553   "neg{b}\t%0"
10554   [(set_attr "type" "negnot")
10555    (set_attr "mode" "QI")])
10556
10557 (define_insn "*negqi2_cmpz"
10558   [(set (reg:CCZ FLAGS_REG)
10559         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10560                      (const_int 0)))
10561    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10562         (neg:QI (match_dup 1)))]
10563   "ix86_unary_operator_ok (NEG, QImode, operands)"
10564   "neg{b}\t%0"
10565   [(set_attr "type" "negnot")
10566    (set_attr "mode" "QI")])
10567
10568 ;; Changing of sign for FP values is doable using integer unit too.
10569
10570 (define_expand "<code><mode>2"
10571   [(set (match_operand:X87MODEF 0 "register_operand" "")
10572         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10573   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10574   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10575
10576 (define_insn "*absneg<mode>2_mixed"
10577   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10578         (match_operator:MODEF 3 "absneg_operator"
10579           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10580    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10581    (clobber (reg:CC FLAGS_REG))]
10582   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10583   "#")
10584
10585 (define_insn "*absneg<mode>2_sse"
10586   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10587         (match_operator:MODEF 3 "absneg_operator"
10588           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10589    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10590    (clobber (reg:CC FLAGS_REG))]
10591   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10592   "#")
10593
10594 (define_insn "*absneg<mode>2_i387"
10595   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10596         (match_operator:X87MODEF 3 "absneg_operator"
10597           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10598    (use (match_operand 2 "" ""))
10599    (clobber (reg:CC FLAGS_REG))]
10600   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10601   "#")
10602
10603 (define_expand "<code>tf2"
10604   [(set (match_operand:TF 0 "register_operand" "")
10605         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10606   "TARGET_SSE2"
10607   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10608
10609 (define_insn "*absnegtf2_sse"
10610   [(set (match_operand:TF 0 "register_operand" "=x,x")
10611         (match_operator:TF 3 "absneg_operator"
10612           [(match_operand:TF 1 "register_operand" "0,x")]))
10613    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10614    (clobber (reg:CC FLAGS_REG))]
10615   "TARGET_SSE2"
10616   "#")
10617
10618 ;; Splitters for fp abs and neg.
10619
10620 (define_split
10621   [(set (match_operand 0 "fp_register_operand" "")
10622         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10623    (use (match_operand 2 "" ""))
10624    (clobber (reg:CC FLAGS_REG))]
10625   "reload_completed"
10626   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10627
10628 (define_split
10629   [(set (match_operand 0 "register_operand" "")
10630         (match_operator 3 "absneg_operator"
10631           [(match_operand 1 "register_operand" "")]))
10632    (use (match_operand 2 "nonimmediate_operand" ""))
10633    (clobber (reg:CC FLAGS_REG))]
10634   "reload_completed && SSE_REG_P (operands[0])"
10635   [(set (match_dup 0) (match_dup 3))]
10636 {
10637   enum machine_mode mode = GET_MODE (operands[0]);
10638   enum machine_mode vmode = GET_MODE (operands[2]);
10639   rtx tmp;
10640
10641   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10642   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10643   if (operands_match_p (operands[0], operands[2]))
10644     {
10645       tmp = operands[1];
10646       operands[1] = operands[2];
10647       operands[2] = tmp;
10648     }
10649   if (GET_CODE (operands[3]) == ABS)
10650     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10651   else
10652     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10653   operands[3] = tmp;
10654 })
10655
10656 (define_split
10657   [(set (match_operand:SF 0 "register_operand" "")
10658         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10659    (use (match_operand:V4SF 2 "" ""))
10660    (clobber (reg:CC FLAGS_REG))]
10661   "reload_completed"
10662   [(parallel [(set (match_dup 0) (match_dup 1))
10663               (clobber (reg:CC FLAGS_REG))])]
10664 {
10665   rtx tmp;
10666   operands[0] = gen_lowpart (SImode, operands[0]);
10667   if (GET_CODE (operands[1]) == ABS)
10668     {
10669       tmp = gen_int_mode (0x7fffffff, SImode);
10670       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10671     }
10672   else
10673     {
10674       tmp = gen_int_mode (0x80000000, SImode);
10675       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10676     }
10677   operands[1] = tmp;
10678 })
10679
10680 (define_split
10681   [(set (match_operand:DF 0 "register_operand" "")
10682         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10683    (use (match_operand 2 "" ""))
10684    (clobber (reg:CC FLAGS_REG))]
10685   "reload_completed"
10686   [(parallel [(set (match_dup 0) (match_dup 1))
10687               (clobber (reg:CC FLAGS_REG))])]
10688 {
10689   rtx tmp;
10690   if (TARGET_64BIT)
10691     {
10692       tmp = gen_lowpart (DImode, operands[0]);
10693       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10694       operands[0] = tmp;
10695
10696       if (GET_CODE (operands[1]) == ABS)
10697         tmp = const0_rtx;
10698       else
10699         tmp = gen_rtx_NOT (DImode, tmp);
10700     }
10701   else
10702     {
10703       operands[0] = gen_highpart (SImode, operands[0]);
10704       if (GET_CODE (operands[1]) == ABS)
10705         {
10706           tmp = gen_int_mode (0x7fffffff, SImode);
10707           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10708         }
10709       else
10710         {
10711           tmp = gen_int_mode (0x80000000, SImode);
10712           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10713         }
10714     }
10715   operands[1] = tmp;
10716 })
10717
10718 (define_split
10719   [(set (match_operand:XF 0 "register_operand" "")
10720         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10721    (use (match_operand 2 "" ""))
10722    (clobber (reg:CC FLAGS_REG))]
10723   "reload_completed"
10724   [(parallel [(set (match_dup 0) (match_dup 1))
10725               (clobber (reg:CC FLAGS_REG))])]
10726 {
10727   rtx tmp;
10728   operands[0] = gen_rtx_REG (SImode,
10729                              true_regnum (operands[0])
10730                              + (TARGET_64BIT ? 1 : 2));
10731   if (GET_CODE (operands[1]) == ABS)
10732     {
10733       tmp = GEN_INT (0x7fff);
10734       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10735     }
10736   else
10737     {
10738       tmp = GEN_INT (0x8000);
10739       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10740     }
10741   operands[1] = tmp;
10742 })
10743
10744 ;; Conditionalize these after reload. If they match before reload, we
10745 ;; lose the clobber and ability to use integer instructions.
10746
10747 (define_insn "*<code><mode>2_1"
10748   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10749         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10750   "TARGET_80387
10751    && (reload_completed
10752        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10753   "f<absnegprefix>"
10754   [(set_attr "type" "fsgn")
10755    (set_attr "mode" "<MODE>")])
10756
10757 (define_insn "*<code>extendsfdf2"
10758   [(set (match_operand:DF 0 "register_operand" "=f")
10759         (absneg:DF (float_extend:DF
10760                      (match_operand:SF 1 "register_operand" "0"))))]
10761   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10762   "f<absnegprefix>"
10763   [(set_attr "type" "fsgn")
10764    (set_attr "mode" "DF")])
10765
10766 (define_insn "*<code>extendsfxf2"
10767   [(set (match_operand:XF 0 "register_operand" "=f")
10768         (absneg:XF (float_extend:XF
10769                      (match_operand:SF 1 "register_operand" "0"))))]
10770   "TARGET_80387"
10771   "f<absnegprefix>"
10772   [(set_attr "type" "fsgn")
10773    (set_attr "mode" "XF")])
10774
10775 (define_insn "*<code>extenddfxf2"
10776   [(set (match_operand:XF 0 "register_operand" "=f")
10777         (absneg:XF (float_extend:XF
10778                       (match_operand:DF 1 "register_operand" "0"))))]
10779   "TARGET_80387"
10780   "f<absnegprefix>"
10781   [(set_attr "type" "fsgn")
10782    (set_attr "mode" "XF")])
10783
10784 ;; Copysign instructions
10785
10786 (define_mode_iterator CSGNMODE [SF DF TF])
10787 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10788
10789 (define_expand "copysign<mode>3"
10790   [(match_operand:CSGNMODE 0 "register_operand" "")
10791    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10792    (match_operand:CSGNMODE 2 "register_operand" "")]
10793   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10794    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10795 {
10796   ix86_expand_copysign (operands);
10797   DONE;
10798 })
10799
10800 (define_insn_and_split "copysign<mode>3_const"
10801   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10802         (unspec:CSGNMODE
10803           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10804            (match_operand:CSGNMODE 2 "register_operand" "0")
10805            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10806           UNSPEC_COPYSIGN))]
10807   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10808    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10809   "#"
10810   "&& reload_completed"
10811   [(const_int 0)]
10812 {
10813   ix86_split_copysign_const (operands);
10814   DONE;
10815 })
10816
10817 (define_insn "copysign<mode>3_var"
10818   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10819         (unspec:CSGNMODE
10820           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10821            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10822            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10823            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10824           UNSPEC_COPYSIGN))
10825    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10826   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10827    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10828   "#")
10829
10830 (define_split
10831   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10832         (unspec:CSGNMODE
10833           [(match_operand:CSGNMODE 2 "register_operand" "")
10834            (match_operand:CSGNMODE 3 "register_operand" "")
10835            (match_operand:<CSGNVMODE> 4 "" "")
10836            (match_operand:<CSGNVMODE> 5 "" "")]
10837           UNSPEC_COPYSIGN))
10838    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10839   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10840     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10841    && reload_completed"
10842   [(const_int 0)]
10843 {
10844   ix86_split_copysign_var (operands);
10845   DONE;
10846 })
10847 \f
10848 ;; One complement instructions
10849
10850 (define_expand "one_cmpldi2"
10851   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10852         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10853   "TARGET_64BIT"
10854   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10855
10856 (define_insn "*one_cmpldi2_1_rex64"
10857   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10858         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10859   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10860   "not{q}\t%0"
10861   [(set_attr "type" "negnot")
10862    (set_attr "mode" "DI")])
10863
10864 (define_insn "*one_cmpldi2_2_rex64"
10865   [(set (reg FLAGS_REG)
10866         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10867                  (const_int 0)))
10868    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10869         (not:DI (match_dup 1)))]
10870   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10871    && ix86_unary_operator_ok (NOT, DImode, operands)"
10872   "#"
10873   [(set_attr "type" "alu1")
10874    (set_attr "mode" "DI")])
10875
10876 (define_split
10877   [(set (match_operand 0 "flags_reg_operand" "")
10878         (match_operator 2 "compare_operator"
10879           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10880            (const_int 0)]))
10881    (set (match_operand:DI 1 "nonimmediate_operand" "")
10882         (not:DI (match_dup 3)))]
10883   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10884   [(parallel [(set (match_dup 0)
10885                    (match_op_dup 2
10886                      [(xor:DI (match_dup 3) (const_int -1))
10887                       (const_int 0)]))
10888               (set (match_dup 1)
10889                    (xor:DI (match_dup 3) (const_int -1)))])]
10890   "")
10891
10892 (define_expand "one_cmplsi2"
10893   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10894         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10895   ""
10896   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10897
10898 (define_insn "*one_cmplsi2_1"
10899   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10900         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10901   "ix86_unary_operator_ok (NOT, SImode, operands)"
10902   "not{l}\t%0"
10903   [(set_attr "type" "negnot")
10904    (set_attr "mode" "SI")])
10905
10906 ;; ??? Currently never generated - xor is used instead.
10907 (define_insn "*one_cmplsi2_1_zext"
10908   [(set (match_operand:DI 0 "register_operand" "=r")
10909         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10910   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10911   "not{l}\t%k0"
10912   [(set_attr "type" "negnot")
10913    (set_attr "mode" "SI")])
10914
10915 (define_insn "*one_cmplsi2_2"
10916   [(set (reg FLAGS_REG)
10917         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10918                  (const_int 0)))
10919    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10920         (not:SI (match_dup 1)))]
10921   "ix86_match_ccmode (insn, CCNOmode)
10922    && ix86_unary_operator_ok (NOT, SImode, operands)"
10923   "#"
10924   [(set_attr "type" "alu1")
10925    (set_attr "mode" "SI")])
10926
10927 (define_split
10928   [(set (match_operand 0 "flags_reg_operand" "")
10929         (match_operator 2 "compare_operator"
10930           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10931            (const_int 0)]))
10932    (set (match_operand:SI 1 "nonimmediate_operand" "")
10933         (not:SI (match_dup 3)))]
10934   "ix86_match_ccmode (insn, CCNOmode)"
10935   [(parallel [(set (match_dup 0)
10936                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10937                                     (const_int 0)]))
10938               (set (match_dup 1)
10939                    (xor:SI (match_dup 3) (const_int -1)))])]
10940   "")
10941
10942 ;; ??? Currently never generated - xor is used instead.
10943 (define_insn "*one_cmplsi2_2_zext"
10944   [(set (reg FLAGS_REG)
10945         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10946                  (const_int 0)))
10947    (set (match_operand:DI 0 "register_operand" "=r")
10948         (zero_extend:DI (not:SI (match_dup 1))))]
10949   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10950    && ix86_unary_operator_ok (NOT, SImode, operands)"
10951   "#"
10952   [(set_attr "type" "alu1")
10953    (set_attr "mode" "SI")])
10954
10955 (define_split
10956   [(set (match_operand 0 "flags_reg_operand" "")
10957         (match_operator 2 "compare_operator"
10958           [(not:SI (match_operand:SI 3 "register_operand" ""))
10959            (const_int 0)]))
10960    (set (match_operand:DI 1 "register_operand" "")
10961         (zero_extend:DI (not:SI (match_dup 3))))]
10962   "ix86_match_ccmode (insn, CCNOmode)"
10963   [(parallel [(set (match_dup 0)
10964                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10965                                     (const_int 0)]))
10966               (set (match_dup 1)
10967                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10968   "")
10969
10970 (define_expand "one_cmplhi2"
10971   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10972         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10973   "TARGET_HIMODE_MATH"
10974   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10975
10976 (define_insn "*one_cmplhi2_1"
10977   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10978         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10979   "ix86_unary_operator_ok (NOT, HImode, operands)"
10980   "not{w}\t%0"
10981   [(set_attr "type" "negnot")
10982    (set_attr "mode" "HI")])
10983
10984 (define_insn "*one_cmplhi2_2"
10985   [(set (reg FLAGS_REG)
10986         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10987                  (const_int 0)))
10988    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10989         (not:HI (match_dup 1)))]
10990   "ix86_match_ccmode (insn, CCNOmode)
10991    && ix86_unary_operator_ok (NEG, HImode, operands)"
10992   "#"
10993   [(set_attr "type" "alu1")
10994    (set_attr "mode" "HI")])
10995
10996 (define_split
10997   [(set (match_operand 0 "flags_reg_operand" "")
10998         (match_operator 2 "compare_operator"
10999           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11000            (const_int 0)]))
11001    (set (match_operand:HI 1 "nonimmediate_operand" "")
11002         (not:HI (match_dup 3)))]
11003   "ix86_match_ccmode (insn, CCNOmode)"
11004   [(parallel [(set (match_dup 0)
11005                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11006                                     (const_int 0)]))
11007               (set (match_dup 1)
11008                    (xor:HI (match_dup 3) (const_int -1)))])]
11009   "")
11010
11011 ;; %%% Potential partial reg stall on alternative 1.  What to do?
11012 (define_expand "one_cmplqi2"
11013   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11014         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11015   "TARGET_QIMODE_MATH"
11016   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11017
11018 (define_insn "*one_cmplqi2_1"
11019   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11020         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11021   "ix86_unary_operator_ok (NOT, QImode, operands)"
11022   "@
11023    not{b}\t%0
11024    not{l}\t%k0"
11025   [(set_attr "type" "negnot")
11026    (set_attr "mode" "QI,SI")])
11027
11028 (define_insn "*one_cmplqi2_2"
11029   [(set (reg FLAGS_REG)
11030         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11031                  (const_int 0)))
11032    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11033         (not:QI (match_dup 1)))]
11034   "ix86_match_ccmode (insn, CCNOmode)
11035    && ix86_unary_operator_ok (NOT, QImode, operands)"
11036   "#"
11037   [(set_attr "type" "alu1")
11038    (set_attr "mode" "QI")])
11039
11040 (define_split
11041   [(set (match_operand 0 "flags_reg_operand" "")
11042         (match_operator 2 "compare_operator"
11043           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11044            (const_int 0)]))
11045    (set (match_operand:QI 1 "nonimmediate_operand" "")
11046         (not:QI (match_dup 3)))]
11047   "ix86_match_ccmode (insn, CCNOmode)"
11048   [(parallel [(set (match_dup 0)
11049                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11050                                     (const_int 0)]))
11051               (set (match_dup 1)
11052                    (xor:QI (match_dup 3) (const_int -1)))])]
11053   "")
11054 \f
11055 ;; Arithmetic shift instructions
11056
11057 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11058 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11059 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11060 ;; from the assembler input.
11061 ;;
11062 ;; This instruction shifts the target reg/mem as usual, but instead of
11063 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11064 ;; is a left shift double, bits are taken from the high order bits of
11065 ;; reg, else if the insn is a shift right double, bits are taken from the
11066 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11067 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11068 ;;
11069 ;; Since sh[lr]d does not change the `reg' operand, that is done
11070 ;; separately, making all shifts emit pairs of shift double and normal
11071 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11072 ;; support a 63 bit shift, each shift where the count is in a reg expands
11073 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11074 ;;
11075 ;; If the shift count is a constant, we need never emit more than one
11076 ;; shift pair, instead using moves and sign extension for counts greater
11077 ;; than 31.
11078
11079 (define_expand "ashlti3"
11080   [(set (match_operand:TI 0 "register_operand" "")
11081         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11082                    (match_operand:QI 2 "nonmemory_operand" "")))]
11083   "TARGET_64BIT"
11084   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11085
11086 ;; This pattern must be defined before *ashlti3_1 to prevent
11087 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11088
11089 (define_insn "*avx_ashlti3"
11090   [(set (match_operand:TI 0 "register_operand" "=x")
11091         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11092                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11093   "TARGET_AVX"
11094 {
11095   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11096   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11097 }
11098   [(set_attr "type" "sseishft")
11099    (set_attr "prefix" "vex")
11100    (set_attr "mode" "TI")])
11101
11102 (define_insn "sse2_ashlti3"
11103   [(set (match_operand:TI 0 "register_operand" "=x")
11104         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11105                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11106   "TARGET_SSE2"
11107 {
11108   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11109   return "pslldq\t{%2, %0|%0, %2}";
11110 }
11111   [(set_attr "type" "sseishft")
11112    (set_attr "prefix_data16" "1")
11113    (set_attr "mode" "TI")])
11114
11115 (define_insn "*ashlti3_1"
11116   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11117         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11118                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11119    (clobber (reg:CC FLAGS_REG))]
11120   "TARGET_64BIT"
11121   "#"
11122   [(set_attr "type" "multi")])
11123
11124 (define_peephole2
11125   [(match_scratch:DI 3 "r")
11126    (parallel [(set (match_operand:TI 0 "register_operand" "")
11127                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11128                               (match_operand:QI 2 "nonmemory_operand" "")))
11129               (clobber (reg:CC FLAGS_REG))])
11130    (match_dup 3)]
11131   "TARGET_64BIT"
11132   [(const_int 0)]
11133   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11134
11135 (define_split
11136   [(set (match_operand:TI 0 "register_operand" "")
11137         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11138                    (match_operand:QI 2 "nonmemory_operand" "")))
11139    (clobber (reg:CC FLAGS_REG))]
11140   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11141                     ? epilogue_completed : reload_completed)"
11142   [(const_int 0)]
11143   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11144
11145 (define_insn "x86_64_shld"
11146   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11147         (ior:DI (ashift:DI (match_dup 0)
11148                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11149                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11150                   (minus:QI (const_int 64) (match_dup 2)))))
11151    (clobber (reg:CC FLAGS_REG))]
11152   "TARGET_64BIT"
11153   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11154   [(set_attr "type" "ishift")
11155    (set_attr "prefix_0f" "1")
11156    (set_attr "mode" "DI")
11157    (set_attr "athlon_decode" "vector")
11158    (set_attr "amdfam10_decode" "vector")])
11159
11160 (define_expand "x86_64_shift_adj_1"
11161   [(set (reg:CCZ FLAGS_REG)
11162         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11163                              (const_int 64))
11164                      (const_int 0)))
11165    (set (match_operand:DI 0 "register_operand" "")
11166         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11167                          (match_operand:DI 1 "register_operand" "")
11168                          (match_dup 0)))
11169    (set (match_dup 1)
11170         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11171                          (match_operand:DI 3 "register_operand" "r")
11172                          (match_dup 1)))]
11173   "TARGET_64BIT"
11174   "")
11175
11176 (define_expand "x86_64_shift_adj_2"
11177   [(use (match_operand:DI 0 "register_operand" ""))
11178    (use (match_operand:DI 1 "register_operand" ""))
11179    (use (match_operand:QI 2 "register_operand" ""))]
11180   "TARGET_64BIT"
11181 {
11182   rtx label = gen_label_rtx ();
11183   rtx tmp;
11184
11185   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11186
11187   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11188   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11189   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11190                               gen_rtx_LABEL_REF (VOIDmode, label),
11191                               pc_rtx);
11192   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11193   JUMP_LABEL (tmp) = label;
11194
11195   emit_move_insn (operands[0], operands[1]);
11196   ix86_expand_clear (operands[1]);
11197
11198   emit_label (label);
11199   LABEL_NUSES (label) = 1;
11200
11201   DONE;
11202 })
11203
11204 (define_expand "ashldi3"
11205   [(set (match_operand:DI 0 "shiftdi_operand" "")
11206         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11207                    (match_operand:QI 2 "nonmemory_operand" "")))]
11208   ""
11209   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11210
11211 (define_insn "*ashldi3_1_rex64"
11212   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11213         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11214                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11215    (clobber (reg:CC FLAGS_REG))]
11216   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11217 {
11218   switch (get_attr_type (insn))
11219     {
11220     case TYPE_ALU:
11221       gcc_assert (operands[2] == const1_rtx);
11222       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11223       return "add{q}\t%0, %0";
11224
11225     case TYPE_LEA:
11226       gcc_assert (CONST_INT_P (operands[2]));
11227       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11228       operands[1] = gen_rtx_MULT (DImode, operands[1],
11229                                   GEN_INT (1 << INTVAL (operands[2])));
11230       return "lea{q}\t{%a1, %0|%0, %a1}";
11231
11232     default:
11233       if (REG_P (operands[2]))
11234         return "sal{q}\t{%b2, %0|%0, %b2}";
11235       else if (operands[2] == const1_rtx
11236                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11237         return "sal{q}\t%0";
11238       else
11239         return "sal{q}\t{%2, %0|%0, %2}";
11240     }
11241 }
11242   [(set (attr "type")
11243      (cond [(eq_attr "alternative" "1")
11244               (const_string "lea")
11245             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11246                           (const_int 0))
11247                       (match_operand 0 "register_operand" ""))
11248                  (match_operand 2 "const1_operand" ""))
11249               (const_string "alu")
11250            ]
11251            (const_string "ishift")))
11252    (set_attr "mode" "DI")])
11253
11254 ;; Convert lea to the lea pattern to avoid flags dependency.
11255 (define_split
11256   [(set (match_operand:DI 0 "register_operand" "")
11257         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11258                    (match_operand:QI 2 "immediate_operand" "")))
11259    (clobber (reg:CC FLAGS_REG))]
11260   "TARGET_64BIT && reload_completed
11261    && true_regnum (operands[0]) != true_regnum (operands[1])"
11262   [(set (match_dup 0)
11263         (mult:DI (match_dup 1)
11264                  (match_dup 2)))]
11265   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11266
11267 ;; This pattern can't accept a variable shift count, since shifts by
11268 ;; zero don't affect the flags.  We assume that shifts by constant
11269 ;; zero are optimized away.
11270 (define_insn "*ashldi3_cmp_rex64"
11271   [(set (reg FLAGS_REG)
11272         (compare
11273           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11274                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11275           (const_int 0)))
11276    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11277         (ashift:DI (match_dup 1) (match_dup 2)))]
11278   "TARGET_64BIT
11279    && (optimize_function_for_size_p (cfun)
11280        || !TARGET_PARTIAL_FLAG_REG_STALL
11281        || (operands[2] == const1_rtx
11282            && (TARGET_SHIFT1
11283                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11284    && ix86_match_ccmode (insn, CCGOCmode)
11285    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11286 {
11287   switch (get_attr_type (insn))
11288     {
11289     case TYPE_ALU:
11290       gcc_assert (operands[2] == const1_rtx);
11291       return "add{q}\t%0, %0";
11292
11293     default:
11294       if (REG_P (operands[2]))
11295         return "sal{q}\t{%b2, %0|%0, %b2}";
11296       else if (operands[2] == const1_rtx
11297                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11298         return "sal{q}\t%0";
11299       else
11300         return "sal{q}\t{%2, %0|%0, %2}";
11301     }
11302 }
11303   [(set (attr "type")
11304      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11305                           (const_int 0))
11306                       (match_operand 0 "register_operand" ""))
11307                  (match_operand 2 "const1_operand" ""))
11308               (const_string "alu")
11309            ]
11310            (const_string "ishift")))
11311    (set_attr "mode" "DI")])
11312
11313 (define_insn "*ashldi3_cconly_rex64"
11314   [(set (reg FLAGS_REG)
11315         (compare
11316           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11317                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11318           (const_int 0)))
11319    (clobber (match_scratch:DI 0 "=r"))]
11320   "TARGET_64BIT
11321    && (optimize_function_for_size_p (cfun)
11322        || !TARGET_PARTIAL_FLAG_REG_STALL
11323        || (operands[2] == const1_rtx
11324            && (TARGET_SHIFT1
11325                || TARGET_DOUBLE_WITH_ADD)))
11326    && ix86_match_ccmode (insn, CCGOCmode)
11327    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11328 {
11329   switch (get_attr_type (insn))
11330     {
11331     case TYPE_ALU:
11332       gcc_assert (operands[2] == const1_rtx);
11333       return "add{q}\t%0, %0";
11334
11335     default:
11336       if (REG_P (operands[2]))
11337         return "sal{q}\t{%b2, %0|%0, %b2}";
11338       else if (operands[2] == const1_rtx
11339                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11340         return "sal{q}\t%0";
11341       else
11342         return "sal{q}\t{%2, %0|%0, %2}";
11343     }
11344 }
11345   [(set (attr "type")
11346      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11347                           (const_int 0))
11348                       (match_operand 0 "register_operand" ""))
11349                  (match_operand 2 "const1_operand" ""))
11350               (const_string "alu")
11351            ]
11352            (const_string "ishift")))
11353    (set_attr "mode" "DI")])
11354
11355 (define_insn "*ashldi3_1"
11356   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11357         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11358                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11359    (clobber (reg:CC FLAGS_REG))]
11360   "!TARGET_64BIT"
11361   "#"
11362   [(set_attr "type" "multi")])
11363
11364 ;; By default we don't ask for a scratch register, because when DImode
11365 ;; values are manipulated, registers are already at a premium.  But if
11366 ;; we have one handy, we won't turn it away.
11367 (define_peephole2
11368   [(match_scratch:SI 3 "r")
11369    (parallel [(set (match_operand:DI 0 "register_operand" "")
11370                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11371                               (match_operand:QI 2 "nonmemory_operand" "")))
11372               (clobber (reg:CC FLAGS_REG))])
11373    (match_dup 3)]
11374   "!TARGET_64BIT && TARGET_CMOVE"
11375   [(const_int 0)]
11376   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11377
11378 (define_split
11379   [(set (match_operand:DI 0 "register_operand" "")
11380         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11381                    (match_operand:QI 2 "nonmemory_operand" "")))
11382    (clobber (reg:CC FLAGS_REG))]
11383   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11384                      ? epilogue_completed : reload_completed)"
11385   [(const_int 0)]
11386   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11387
11388 (define_insn "x86_shld"
11389   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11390         (ior:SI (ashift:SI (match_dup 0)
11391                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11392                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11393                   (minus:QI (const_int 32) (match_dup 2)))))
11394    (clobber (reg:CC FLAGS_REG))]
11395   ""
11396   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11397   [(set_attr "type" "ishift")
11398    (set_attr "prefix_0f" "1")
11399    (set_attr "mode" "SI")
11400    (set_attr "pent_pair" "np")
11401    (set_attr "athlon_decode" "vector")
11402    (set_attr "amdfam10_decode" "vector")])
11403
11404 (define_expand "x86_shift_adj_1"
11405   [(set (reg:CCZ FLAGS_REG)
11406         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11407                              (const_int 32))
11408                      (const_int 0)))
11409    (set (match_operand:SI 0 "register_operand" "")
11410         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11411                          (match_operand:SI 1 "register_operand" "")
11412                          (match_dup 0)))
11413    (set (match_dup 1)
11414         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11415                          (match_operand:SI 3 "register_operand" "r")
11416                          (match_dup 1)))]
11417   "TARGET_CMOVE"
11418   "")
11419
11420 (define_expand "x86_shift_adj_2"
11421   [(use (match_operand:SI 0 "register_operand" ""))
11422    (use (match_operand:SI 1 "register_operand" ""))
11423    (use (match_operand:QI 2 "register_operand" ""))]
11424   ""
11425 {
11426   rtx label = gen_label_rtx ();
11427   rtx tmp;
11428
11429   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11430
11431   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11432   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11433   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11434                               gen_rtx_LABEL_REF (VOIDmode, label),
11435                               pc_rtx);
11436   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11437   JUMP_LABEL (tmp) = label;
11438
11439   emit_move_insn (operands[0], operands[1]);
11440   ix86_expand_clear (operands[1]);
11441
11442   emit_label (label);
11443   LABEL_NUSES (label) = 1;
11444
11445   DONE;
11446 })
11447
11448 (define_expand "ashlsi3"
11449   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11450         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11451                    (match_operand:QI 2 "nonmemory_operand" "")))]
11452   ""
11453   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11454
11455 (define_insn "*ashlsi3_1"
11456   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11457         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11458                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11461 {
11462   switch (get_attr_type (insn))
11463     {
11464     case TYPE_ALU:
11465       gcc_assert (operands[2] == const1_rtx);
11466       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11467       return "add{l}\t%0, %0";
11468
11469     case TYPE_LEA:
11470       return "#";
11471
11472     default:
11473       if (REG_P (operands[2]))
11474         return "sal{l}\t{%b2, %0|%0, %b2}";
11475       else if (operands[2] == const1_rtx
11476                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11477         return "sal{l}\t%0";
11478       else
11479         return "sal{l}\t{%2, %0|%0, %2}";
11480     }
11481 }
11482   [(set (attr "type")
11483      (cond [(eq_attr "alternative" "1")
11484               (const_string "lea")
11485             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11486                           (const_int 0))
11487                       (match_operand 0 "register_operand" ""))
11488                  (match_operand 2 "const1_operand" ""))
11489               (const_string "alu")
11490            ]
11491            (const_string "ishift")))
11492    (set_attr "mode" "SI")])
11493
11494 ;; Convert lea to the lea pattern to avoid flags dependency.
11495 (define_split
11496   [(set (match_operand 0 "register_operand" "")
11497         (ashift (match_operand 1 "index_register_operand" "")
11498                 (match_operand:QI 2 "const_int_operand" "")))
11499    (clobber (reg:CC FLAGS_REG))]
11500   "reload_completed
11501    && true_regnum (operands[0]) != true_regnum (operands[1])
11502    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11503   [(const_int 0)]
11504 {
11505   rtx pat;
11506   enum machine_mode mode = GET_MODE (operands[0]);
11507
11508   if (GET_MODE_SIZE (mode) < 4)
11509     operands[0] = gen_lowpart (SImode, operands[0]);
11510   if (mode != Pmode)
11511     operands[1] = gen_lowpart (Pmode, operands[1]);
11512   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11513
11514   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11515   if (Pmode != SImode)
11516     pat = gen_rtx_SUBREG (SImode, pat, 0);
11517   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11518   DONE;
11519 })
11520
11521 ;; Rare case of shifting RSP is handled by generating move and shift
11522 (define_split
11523   [(set (match_operand 0 "register_operand" "")
11524         (ashift (match_operand 1 "register_operand" "")
11525                 (match_operand:QI 2 "const_int_operand" "")))
11526    (clobber (reg:CC FLAGS_REG))]
11527   "reload_completed
11528    && true_regnum (operands[0]) != true_regnum (operands[1])"
11529   [(const_int 0)]
11530 {
11531   rtx pat, clob;
11532   emit_move_insn (operands[0], operands[1]);
11533   pat = gen_rtx_SET (VOIDmode, operands[0],
11534                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11535                                      operands[0], operands[2]));
11536   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11537   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11538   DONE;
11539 })
11540
11541 (define_insn "*ashlsi3_1_zext"
11542   [(set (match_operand:DI 0 "register_operand" "=r,r")
11543         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11544                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11545    (clobber (reg:CC FLAGS_REG))]
11546   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11547 {
11548   switch (get_attr_type (insn))
11549     {
11550     case TYPE_ALU:
11551       gcc_assert (operands[2] == const1_rtx);
11552       return "add{l}\t%k0, %k0";
11553
11554     case TYPE_LEA:
11555       return "#";
11556
11557     default:
11558       if (REG_P (operands[2]))
11559         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11560       else if (operands[2] == const1_rtx
11561                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11562         return "sal{l}\t%k0";
11563       else
11564         return "sal{l}\t{%2, %k0|%k0, %2}";
11565     }
11566 }
11567   [(set (attr "type")
11568      (cond [(eq_attr "alternative" "1")
11569               (const_string "lea")
11570             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11571                      (const_int 0))
11572                  (match_operand 2 "const1_operand" ""))
11573               (const_string "alu")
11574            ]
11575            (const_string "ishift")))
11576    (set_attr "mode" "SI")])
11577
11578 ;; Convert lea to the lea pattern to avoid flags dependency.
11579 (define_split
11580   [(set (match_operand:DI 0 "register_operand" "")
11581         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11582                                 (match_operand:QI 2 "const_int_operand" ""))))
11583    (clobber (reg:CC FLAGS_REG))]
11584   "TARGET_64BIT && reload_completed
11585    && true_regnum (operands[0]) != true_regnum (operands[1])"
11586   [(set (match_dup 0) (zero_extend:DI
11587                         (subreg:SI (mult:SI (match_dup 1)
11588                                             (match_dup 2)) 0)))]
11589 {
11590   operands[1] = gen_lowpart (Pmode, operands[1]);
11591   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11592 })
11593
11594 ;; This pattern can't accept a variable shift count, since shifts by
11595 ;; zero don't affect the flags.  We assume that shifts by constant
11596 ;; zero are optimized away.
11597 (define_insn "*ashlsi3_cmp"
11598   [(set (reg FLAGS_REG)
11599         (compare
11600           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11601                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11602           (const_int 0)))
11603    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11604         (ashift:SI (match_dup 1) (match_dup 2)))]
11605    "(optimize_function_for_size_p (cfun)
11606      || !TARGET_PARTIAL_FLAG_REG_STALL
11607      || (operands[2] == const1_rtx
11608          && (TARGET_SHIFT1
11609              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11610    && ix86_match_ccmode (insn, CCGOCmode)
11611    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11612 {
11613   switch (get_attr_type (insn))
11614     {
11615     case TYPE_ALU:
11616       gcc_assert (operands[2] == const1_rtx);
11617       return "add{l}\t%0, %0";
11618
11619     default:
11620       if (REG_P (operands[2]))
11621         return "sal{l}\t{%b2, %0|%0, %b2}";
11622       else if (operands[2] == const1_rtx
11623                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11624         return "sal{l}\t%0";
11625       else
11626         return "sal{l}\t{%2, %0|%0, %2}";
11627     }
11628 }
11629   [(set (attr "type")
11630      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11631                           (const_int 0))
11632                       (match_operand 0 "register_operand" ""))
11633                  (match_operand 2 "const1_operand" ""))
11634               (const_string "alu")
11635            ]
11636            (const_string "ishift")))
11637    (set_attr "mode" "SI")])
11638
11639 (define_insn "*ashlsi3_cconly"
11640   [(set (reg FLAGS_REG)
11641         (compare
11642           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11643                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11644           (const_int 0)))
11645    (clobber (match_scratch:SI 0 "=r"))]
11646   "(optimize_function_for_size_p (cfun)
11647     || !TARGET_PARTIAL_FLAG_REG_STALL
11648     || (operands[2] == const1_rtx
11649         && (TARGET_SHIFT1
11650             || TARGET_DOUBLE_WITH_ADD)))
11651    && ix86_match_ccmode (insn, CCGOCmode)
11652    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11653 {
11654   switch (get_attr_type (insn))
11655     {
11656     case TYPE_ALU:
11657       gcc_assert (operands[2] == const1_rtx);
11658       return "add{l}\t%0, %0";
11659
11660     default:
11661       if (REG_P (operands[2]))
11662         return "sal{l}\t{%b2, %0|%0, %b2}";
11663       else if (operands[2] == const1_rtx
11664                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11665         return "sal{l}\t%0";
11666       else
11667         return "sal{l}\t{%2, %0|%0, %2}";
11668     }
11669 }
11670   [(set (attr "type")
11671      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11672                           (const_int 0))
11673                       (match_operand 0 "register_operand" ""))
11674                  (match_operand 2 "const1_operand" ""))
11675               (const_string "alu")
11676            ]
11677            (const_string "ishift")))
11678    (set_attr "mode" "SI")])
11679
11680 (define_insn "*ashlsi3_cmp_zext"
11681   [(set (reg FLAGS_REG)
11682         (compare
11683           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11684                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11685           (const_int 0)))
11686    (set (match_operand:DI 0 "register_operand" "=r")
11687         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11688   "TARGET_64BIT
11689    && (optimize_function_for_size_p (cfun)
11690        || !TARGET_PARTIAL_FLAG_REG_STALL
11691        || (operands[2] == const1_rtx
11692            && (TARGET_SHIFT1
11693                || TARGET_DOUBLE_WITH_ADD)))
11694    && ix86_match_ccmode (insn, CCGOCmode)
11695    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11696 {
11697   switch (get_attr_type (insn))
11698     {
11699     case TYPE_ALU:
11700       gcc_assert (operands[2] == const1_rtx);
11701       return "add{l}\t%k0, %k0";
11702
11703     default:
11704       if (REG_P (operands[2]))
11705         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11706       else if (operands[2] == const1_rtx
11707                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11708         return "sal{l}\t%k0";
11709       else
11710         return "sal{l}\t{%2, %k0|%k0, %2}";
11711     }
11712 }
11713   [(set (attr "type")
11714      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11715                      (const_int 0))
11716                  (match_operand 2 "const1_operand" ""))
11717               (const_string "alu")
11718            ]
11719            (const_string "ishift")))
11720    (set_attr "mode" "SI")])
11721
11722 (define_expand "ashlhi3"
11723   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11724         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11725                    (match_operand:QI 2 "nonmemory_operand" "")))]
11726   "TARGET_HIMODE_MATH"
11727   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11728
11729 (define_insn "*ashlhi3_1_lea"
11730   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11731         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11732                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11733    (clobber (reg:CC FLAGS_REG))]
11734   "!TARGET_PARTIAL_REG_STALL
11735    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11736 {
11737   switch (get_attr_type (insn))
11738     {
11739     case TYPE_LEA:
11740       return "#";
11741     case TYPE_ALU:
11742       gcc_assert (operands[2] == const1_rtx);
11743       return "add{w}\t%0, %0";
11744
11745     default:
11746       if (REG_P (operands[2]))
11747         return "sal{w}\t{%b2, %0|%0, %b2}";
11748       else if (operands[2] == const1_rtx
11749                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11750         return "sal{w}\t%0";
11751       else
11752         return "sal{w}\t{%2, %0|%0, %2}";
11753     }
11754 }
11755   [(set (attr "type")
11756      (cond [(eq_attr "alternative" "1")
11757               (const_string "lea")
11758             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11759                           (const_int 0))
11760                       (match_operand 0 "register_operand" ""))
11761                  (match_operand 2 "const1_operand" ""))
11762               (const_string "alu")
11763            ]
11764            (const_string "ishift")))
11765    (set_attr "mode" "HI,SI")])
11766
11767 (define_insn "*ashlhi3_1"
11768   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11769         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11770                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11771    (clobber (reg:CC FLAGS_REG))]
11772   "TARGET_PARTIAL_REG_STALL
11773    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11774 {
11775   switch (get_attr_type (insn))
11776     {
11777     case TYPE_ALU:
11778       gcc_assert (operands[2] == const1_rtx);
11779       return "add{w}\t%0, %0";
11780
11781     default:
11782       if (REG_P (operands[2]))
11783         return "sal{w}\t{%b2, %0|%0, %b2}";
11784       else if (operands[2] == const1_rtx
11785                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11786         return "sal{w}\t%0";
11787       else
11788         return "sal{w}\t{%2, %0|%0, %2}";
11789     }
11790 }
11791   [(set (attr "type")
11792      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11793                           (const_int 0))
11794                       (match_operand 0 "register_operand" ""))
11795                  (match_operand 2 "const1_operand" ""))
11796               (const_string "alu")
11797            ]
11798            (const_string "ishift")))
11799    (set_attr "mode" "HI")])
11800
11801 ;; This pattern can't accept a variable shift count, since shifts by
11802 ;; zero don't affect the flags.  We assume that shifts by constant
11803 ;; zero are optimized away.
11804 (define_insn "*ashlhi3_cmp"
11805   [(set (reg FLAGS_REG)
11806         (compare
11807           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11808                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11809           (const_int 0)))
11810    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11811         (ashift:HI (match_dup 1) (match_dup 2)))]
11812   "(optimize_function_for_size_p (cfun)
11813     || !TARGET_PARTIAL_FLAG_REG_STALL
11814     || (operands[2] == const1_rtx
11815         && (TARGET_SHIFT1
11816             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11817    && ix86_match_ccmode (insn, CCGOCmode)
11818    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11819 {
11820   switch (get_attr_type (insn))
11821     {
11822     case TYPE_ALU:
11823       gcc_assert (operands[2] == const1_rtx);
11824       return "add{w}\t%0, %0";
11825
11826     default:
11827       if (REG_P (operands[2]))
11828         return "sal{w}\t{%b2, %0|%0, %b2}";
11829       else if (operands[2] == const1_rtx
11830                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11831         return "sal{w}\t%0";
11832       else
11833         return "sal{w}\t{%2, %0|%0, %2}";
11834     }
11835 }
11836   [(set (attr "type")
11837      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11838                           (const_int 0))
11839                       (match_operand 0 "register_operand" ""))
11840                  (match_operand 2 "const1_operand" ""))
11841               (const_string "alu")
11842            ]
11843            (const_string "ishift")))
11844    (set_attr "mode" "HI")])
11845
11846 (define_insn "*ashlhi3_cconly"
11847   [(set (reg FLAGS_REG)
11848         (compare
11849           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11850                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11851           (const_int 0)))
11852    (clobber (match_scratch:HI 0 "=r"))]
11853   "(optimize_function_for_size_p (cfun)
11854     || !TARGET_PARTIAL_FLAG_REG_STALL
11855     || (operands[2] == const1_rtx
11856         && (TARGET_SHIFT1
11857             || TARGET_DOUBLE_WITH_ADD)))
11858    && ix86_match_ccmode (insn, CCGOCmode)
11859    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11860 {
11861   switch (get_attr_type (insn))
11862     {
11863     case TYPE_ALU:
11864       gcc_assert (operands[2] == const1_rtx);
11865       return "add{w}\t%0, %0";
11866
11867     default:
11868       if (REG_P (operands[2]))
11869         return "sal{w}\t{%b2, %0|%0, %b2}";
11870       else if (operands[2] == const1_rtx
11871                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11872         return "sal{w}\t%0";
11873       else
11874         return "sal{w}\t{%2, %0|%0, %2}";
11875     }
11876 }
11877   [(set (attr "type")
11878      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11879                           (const_int 0))
11880                       (match_operand 0 "register_operand" ""))
11881                  (match_operand 2 "const1_operand" ""))
11882               (const_string "alu")
11883            ]
11884            (const_string "ishift")))
11885    (set_attr "mode" "HI")])
11886
11887 (define_expand "ashlqi3"
11888   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11889         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11890                    (match_operand:QI 2 "nonmemory_operand" "")))]
11891   "TARGET_QIMODE_MATH"
11892   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11893
11894 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11895
11896 (define_insn "*ashlqi3_1_lea"
11897   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11898         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11899                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "!TARGET_PARTIAL_REG_STALL
11902    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11903 {
11904   switch (get_attr_type (insn))
11905     {
11906     case TYPE_LEA:
11907       return "#";
11908     case TYPE_ALU:
11909       gcc_assert (operands[2] == const1_rtx);
11910       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11911         return "add{l}\t%k0, %k0";
11912       else
11913         return "add{b}\t%0, %0";
11914
11915     default:
11916       if (REG_P (operands[2]))
11917         {
11918           if (get_attr_mode (insn) == MODE_SI)
11919             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11920           else
11921             return "sal{b}\t{%b2, %0|%0, %b2}";
11922         }
11923       else if (operands[2] == const1_rtx
11924                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11925         {
11926           if (get_attr_mode (insn) == MODE_SI)
11927             return "sal{l}\t%0";
11928           else
11929             return "sal{b}\t%0";
11930         }
11931       else
11932         {
11933           if (get_attr_mode (insn) == MODE_SI)
11934             return "sal{l}\t{%2, %k0|%k0, %2}";
11935           else
11936             return "sal{b}\t{%2, %0|%0, %2}";
11937         }
11938     }
11939 }
11940   [(set (attr "type")
11941      (cond [(eq_attr "alternative" "2")
11942               (const_string "lea")
11943             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11944                           (const_int 0))
11945                       (match_operand 0 "register_operand" ""))
11946                  (match_operand 2 "const1_operand" ""))
11947               (const_string "alu")
11948            ]
11949            (const_string "ishift")))
11950    (set_attr "mode" "QI,SI,SI")])
11951
11952 (define_insn "*ashlqi3_1"
11953   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11954         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11955                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11956    (clobber (reg:CC FLAGS_REG))]
11957   "TARGET_PARTIAL_REG_STALL
11958    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11959 {
11960   switch (get_attr_type (insn))
11961     {
11962     case TYPE_ALU:
11963       gcc_assert (operands[2] == const1_rtx);
11964       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11965         return "add{l}\t%k0, %k0";
11966       else
11967         return "add{b}\t%0, %0";
11968
11969     default:
11970       if (REG_P (operands[2]))
11971         {
11972           if (get_attr_mode (insn) == MODE_SI)
11973             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11974           else
11975             return "sal{b}\t{%b2, %0|%0, %b2}";
11976         }
11977       else if (operands[2] == const1_rtx
11978                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11979         {
11980           if (get_attr_mode (insn) == MODE_SI)
11981             return "sal{l}\t%0";
11982           else
11983             return "sal{b}\t%0";
11984         }
11985       else
11986         {
11987           if (get_attr_mode (insn) == MODE_SI)
11988             return "sal{l}\t{%2, %k0|%k0, %2}";
11989           else
11990             return "sal{b}\t{%2, %0|%0, %2}";
11991         }
11992     }
11993 }
11994   [(set (attr "type")
11995      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11996                           (const_int 0))
11997                       (match_operand 0 "register_operand" ""))
11998                  (match_operand 2 "const1_operand" ""))
11999               (const_string "alu")
12000            ]
12001            (const_string "ishift")))
12002    (set_attr "mode" "QI,SI")])
12003
12004 ;; This pattern can't accept a variable shift count, since shifts by
12005 ;; zero don't affect the flags.  We assume that shifts by constant
12006 ;; zero are optimized away.
12007 (define_insn "*ashlqi3_cmp"
12008   [(set (reg FLAGS_REG)
12009         (compare
12010           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12011                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12012           (const_int 0)))
12013    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12014         (ashift:QI (match_dup 1) (match_dup 2)))]
12015   "(optimize_function_for_size_p (cfun)
12016     || !TARGET_PARTIAL_FLAG_REG_STALL
12017     || (operands[2] == const1_rtx
12018         && (TARGET_SHIFT1
12019             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12020    && ix86_match_ccmode (insn, CCGOCmode)
12021    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12022 {
12023   switch (get_attr_type (insn))
12024     {
12025     case TYPE_ALU:
12026       gcc_assert (operands[2] == const1_rtx);
12027       return "add{b}\t%0, %0";
12028
12029     default:
12030       if (REG_P (operands[2]))
12031         return "sal{b}\t{%b2, %0|%0, %b2}";
12032       else if (operands[2] == const1_rtx
12033                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12034         return "sal{b}\t%0";
12035       else
12036         return "sal{b}\t{%2, %0|%0, %2}";
12037     }
12038 }
12039   [(set (attr "type")
12040      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12041                           (const_int 0))
12042                       (match_operand 0 "register_operand" ""))
12043                  (match_operand 2 "const1_operand" ""))
12044               (const_string "alu")
12045            ]
12046            (const_string "ishift")))
12047    (set_attr "mode" "QI")])
12048
12049 (define_insn "*ashlqi3_cconly"
12050   [(set (reg FLAGS_REG)
12051         (compare
12052           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12053                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12054           (const_int 0)))
12055    (clobber (match_scratch:QI 0 "=q"))]
12056   "(optimize_function_for_size_p (cfun)
12057     || !TARGET_PARTIAL_FLAG_REG_STALL
12058     || (operands[2] == const1_rtx
12059         && (TARGET_SHIFT1
12060             || TARGET_DOUBLE_WITH_ADD)))
12061    && ix86_match_ccmode (insn, CCGOCmode)
12062    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12063 {
12064   switch (get_attr_type (insn))
12065     {
12066     case TYPE_ALU:
12067       gcc_assert (operands[2] == const1_rtx);
12068       return "add{b}\t%0, %0";
12069
12070     default:
12071       if (REG_P (operands[2]))
12072         return "sal{b}\t{%b2, %0|%0, %b2}";
12073       else if (operands[2] == const1_rtx
12074                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12075         return "sal{b}\t%0";
12076       else
12077         return "sal{b}\t{%2, %0|%0, %2}";
12078     }
12079 }
12080   [(set (attr "type")
12081      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12082                           (const_int 0))
12083                       (match_operand 0 "register_operand" ""))
12084                  (match_operand 2 "const1_operand" ""))
12085               (const_string "alu")
12086            ]
12087            (const_string "ishift")))
12088    (set_attr "mode" "QI")])
12089
12090 ;; See comment above `ashldi3' about how this works.
12091
12092 (define_expand "ashrti3"
12093   [(set (match_operand:TI 0 "register_operand" "")
12094         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12095                      (match_operand:QI 2 "nonmemory_operand" "")))]
12096   "TARGET_64BIT"
12097   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12098
12099 (define_insn "*ashrti3_1"
12100   [(set (match_operand:TI 0 "register_operand" "=r")
12101         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12102                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12103    (clobber (reg:CC FLAGS_REG))]
12104   "TARGET_64BIT"
12105   "#"
12106   [(set_attr "type" "multi")])
12107
12108 (define_peephole2
12109   [(match_scratch:DI 3 "r")
12110    (parallel [(set (match_operand:TI 0 "register_operand" "")
12111                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12112                                 (match_operand:QI 2 "nonmemory_operand" "")))
12113               (clobber (reg:CC FLAGS_REG))])
12114    (match_dup 3)]
12115   "TARGET_64BIT"
12116   [(const_int 0)]
12117   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12118
12119 (define_split
12120   [(set (match_operand:TI 0 "register_operand" "")
12121         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12122                      (match_operand:QI 2 "nonmemory_operand" "")))
12123    (clobber (reg:CC FLAGS_REG))]
12124   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12125                     ? epilogue_completed : reload_completed)"
12126   [(const_int 0)]
12127   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12128
12129 (define_insn "x86_64_shrd"
12130   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12131         (ior:DI (ashiftrt:DI (match_dup 0)
12132                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12133                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12134                   (minus:QI (const_int 64) (match_dup 2)))))
12135    (clobber (reg:CC FLAGS_REG))]
12136   "TARGET_64BIT"
12137   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12138   [(set_attr "type" "ishift")
12139    (set_attr "prefix_0f" "1")
12140    (set_attr "mode" "DI")
12141    (set_attr "athlon_decode" "vector")
12142    (set_attr "amdfam10_decode" "vector")])
12143
12144 (define_expand "ashrdi3"
12145   [(set (match_operand:DI 0 "shiftdi_operand" "")
12146         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12147                      (match_operand:QI 2 "nonmemory_operand" "")))]
12148   ""
12149   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12150
12151 (define_expand "x86_64_shift_adj_3"
12152   [(use (match_operand:DI 0 "register_operand" ""))
12153    (use (match_operand:DI 1 "register_operand" ""))
12154    (use (match_operand:QI 2 "register_operand" ""))]
12155   ""
12156 {
12157   rtx label = gen_label_rtx ();
12158   rtx tmp;
12159
12160   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12161
12162   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12163   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12164   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12165                               gen_rtx_LABEL_REF (VOIDmode, label),
12166                               pc_rtx);
12167   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12168   JUMP_LABEL (tmp) = label;
12169
12170   emit_move_insn (operands[0], operands[1]);
12171   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12172
12173   emit_label (label);
12174   LABEL_NUSES (label) = 1;
12175
12176   DONE;
12177 })
12178
12179 (define_insn "ashrdi3_63_rex64"
12180   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12181         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12182                      (match_operand:DI 2 "const_int_operand" "i,i")))
12183    (clobber (reg:CC FLAGS_REG))]
12184   "TARGET_64BIT && INTVAL (operands[2]) == 63
12185    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12186    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12187   "@
12188    {cqto|cqo}
12189    sar{q}\t{%2, %0|%0, %2}"
12190   [(set_attr "type" "imovx,ishift")
12191    (set_attr "prefix_0f" "0,*")
12192    (set_attr "length_immediate" "0,*")
12193    (set_attr "modrm" "0,1")
12194    (set_attr "mode" "DI")])
12195
12196 (define_insn "*ashrdi3_1_one_bit_rex64"
12197   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12198         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12199                      (match_operand:QI 2 "const1_operand" "")))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "TARGET_64BIT
12202    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12203    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12204   "sar{q}\t%0"
12205   [(set_attr "type" "ishift")
12206    (set (attr "length")
12207      (if_then_else (match_operand:DI 0 "register_operand" "")
12208         (const_string "2")
12209         (const_string "*")))])
12210
12211 (define_insn "*ashrdi3_1_rex64"
12212   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12213         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12214                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12217   "@
12218    sar{q}\t{%2, %0|%0, %2}
12219    sar{q}\t{%b2, %0|%0, %b2}"
12220   [(set_attr "type" "ishift")
12221    (set_attr "mode" "DI")])
12222
12223 ;; This pattern can't accept a variable shift count, since shifts by
12224 ;; zero don't affect the flags.  We assume that shifts by constant
12225 ;; zero are optimized away.
12226 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12227   [(set (reg FLAGS_REG)
12228         (compare
12229           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12230                        (match_operand:QI 2 "const1_operand" ""))
12231           (const_int 0)))
12232    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12233         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12234   "TARGET_64BIT
12235    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12236    && ix86_match_ccmode (insn, CCGOCmode)
12237    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12238   "sar{q}\t%0"
12239   [(set_attr "type" "ishift")
12240    (set (attr "length")
12241      (if_then_else (match_operand:DI 0 "register_operand" "")
12242         (const_string "2")
12243         (const_string "*")))])
12244
12245 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12246   [(set (reg FLAGS_REG)
12247         (compare
12248           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12249                        (match_operand:QI 2 "const1_operand" ""))
12250           (const_int 0)))
12251    (clobber (match_scratch:DI 0 "=r"))]
12252   "TARGET_64BIT
12253    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12254    && ix86_match_ccmode (insn, CCGOCmode)
12255    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12256   "sar{q}\t%0"
12257   [(set_attr "type" "ishift")
12258    (set_attr "length" "2")])
12259
12260 ;; This pattern can't accept a variable shift count, since shifts by
12261 ;; zero don't affect the flags.  We assume that shifts by constant
12262 ;; zero are optimized away.
12263 (define_insn "*ashrdi3_cmp_rex64"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12268           (const_int 0)))
12269    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12270         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12271   "TARGET_64BIT
12272    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12273    && ix86_match_ccmode (insn, CCGOCmode)
12274    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12275   "sar{q}\t{%2, %0|%0, %2}"
12276   [(set_attr "type" "ishift")
12277    (set_attr "mode" "DI")])
12278
12279 (define_insn "*ashrdi3_cconly_rex64"
12280   [(set (reg FLAGS_REG)
12281         (compare
12282           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12283                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12284           (const_int 0)))
12285    (clobber (match_scratch:DI 0 "=r"))]
12286   "TARGET_64BIT
12287    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12288    && ix86_match_ccmode (insn, CCGOCmode)
12289    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12290   "sar{q}\t{%2, %0|%0, %2}"
12291   [(set_attr "type" "ishift")
12292    (set_attr "mode" "DI")])
12293
12294 (define_insn "*ashrdi3_1"
12295   [(set (match_operand:DI 0 "register_operand" "=r")
12296         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12297                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12298    (clobber (reg:CC FLAGS_REG))]
12299   "!TARGET_64BIT"
12300   "#"
12301   [(set_attr "type" "multi")])
12302
12303 ;; By default we don't ask for a scratch register, because when DImode
12304 ;; values are manipulated, registers are already at a premium.  But if
12305 ;; we have one handy, we won't turn it away.
12306 (define_peephole2
12307   [(match_scratch:SI 3 "r")
12308    (parallel [(set (match_operand:DI 0 "register_operand" "")
12309                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12310                                 (match_operand:QI 2 "nonmemory_operand" "")))
12311               (clobber (reg:CC FLAGS_REG))])
12312    (match_dup 3)]
12313   "!TARGET_64BIT && TARGET_CMOVE"
12314   [(const_int 0)]
12315   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12316
12317 (define_split
12318   [(set (match_operand:DI 0 "register_operand" "")
12319         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12320                      (match_operand:QI 2 "nonmemory_operand" "")))
12321    (clobber (reg:CC FLAGS_REG))]
12322   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12323                      ? epilogue_completed : reload_completed)"
12324   [(const_int 0)]
12325   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12326
12327 (define_insn "x86_shrd"
12328   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12329         (ior:SI (ashiftrt:SI (match_dup 0)
12330                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12331                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12332                   (minus:QI (const_int 32) (match_dup 2)))))
12333    (clobber (reg:CC FLAGS_REG))]
12334   ""
12335   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12336   [(set_attr "type" "ishift")
12337    (set_attr "prefix_0f" "1")
12338    (set_attr "pent_pair" "np")
12339    (set_attr "mode" "SI")])
12340
12341 (define_expand "x86_shift_adj_3"
12342   [(use (match_operand:SI 0 "register_operand" ""))
12343    (use (match_operand:SI 1 "register_operand" ""))
12344    (use (match_operand:QI 2 "register_operand" ""))]
12345   ""
12346 {
12347   rtx label = gen_label_rtx ();
12348   rtx tmp;
12349
12350   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12351
12352   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12353   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12354   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12355                               gen_rtx_LABEL_REF (VOIDmode, label),
12356                               pc_rtx);
12357   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12358   JUMP_LABEL (tmp) = label;
12359
12360   emit_move_insn (operands[0], operands[1]);
12361   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12362
12363   emit_label (label);
12364   LABEL_NUSES (label) = 1;
12365
12366   DONE;
12367 })
12368
12369 (define_expand "ashrsi3_31"
12370   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12371                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12372                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12373               (clobber (reg:CC FLAGS_REG))])]
12374   "")
12375
12376 (define_insn "*ashrsi3_31"
12377   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12378         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12379                      (match_operand:SI 2 "const_int_operand" "i,i")))
12380    (clobber (reg:CC FLAGS_REG))]
12381   "INTVAL (operands[2]) == 31
12382    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12383    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12384   "@
12385    {cltd|cdq}
12386    sar{l}\t{%2, %0|%0, %2}"
12387   [(set_attr "type" "imovx,ishift")
12388    (set_attr "prefix_0f" "0,*")
12389    (set_attr "length_immediate" "0,*")
12390    (set_attr "modrm" "0,1")
12391    (set_attr "mode" "SI")])
12392
12393 (define_insn "*ashrsi3_31_zext"
12394   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12395         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12396                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12397    (clobber (reg:CC FLAGS_REG))]
12398   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12399    && INTVAL (operands[2]) == 31
12400    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12401   "@
12402    {cltd|cdq}
12403    sar{l}\t{%2, %k0|%k0, %2}"
12404   [(set_attr "type" "imovx,ishift")
12405    (set_attr "prefix_0f" "0,*")
12406    (set_attr "length_immediate" "0,*")
12407    (set_attr "modrm" "0,1")
12408    (set_attr "mode" "SI")])
12409
12410 (define_expand "ashrsi3"
12411   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12412         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12413                      (match_operand:QI 2 "nonmemory_operand" "")))]
12414   ""
12415   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12416
12417 (define_insn "*ashrsi3_1_one_bit"
12418   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12419         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12420                      (match_operand:QI 2 "const1_operand" "")))
12421    (clobber (reg:CC FLAGS_REG))]
12422   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12423    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12424   "sar{l}\t%0"
12425   [(set_attr "type" "ishift")
12426    (set (attr "length")
12427      (if_then_else (match_operand:SI 0 "register_operand" "")
12428         (const_string "2")
12429         (const_string "*")))])
12430
12431 (define_insn "*ashrsi3_1_one_bit_zext"
12432   [(set (match_operand:DI 0 "register_operand" "=r")
12433         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12434                                      (match_operand:QI 2 "const1_operand" ""))))
12435    (clobber (reg:CC FLAGS_REG))]
12436   "TARGET_64BIT
12437    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12438    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12439   "sar{l}\t%k0"
12440   [(set_attr "type" "ishift")
12441    (set_attr "length" "2")])
12442
12443 (define_insn "*ashrsi3_1"
12444   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12445         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12446                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12447    (clobber (reg:CC FLAGS_REG))]
12448   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12449   "@
12450    sar{l}\t{%2, %0|%0, %2}
12451    sar{l}\t{%b2, %0|%0, %b2}"
12452   [(set_attr "type" "ishift")
12453    (set_attr "mode" "SI")])
12454
12455 (define_insn "*ashrsi3_1_zext"
12456   [(set (match_operand:DI 0 "register_operand" "=r,r")
12457         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12458                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12459    (clobber (reg:CC FLAGS_REG))]
12460   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12461   "@
12462    sar{l}\t{%2, %k0|%k0, %2}
12463    sar{l}\t{%b2, %k0|%k0, %b2}"
12464   [(set_attr "type" "ishift")
12465    (set_attr "mode" "SI")])
12466
12467 ;; This pattern can't accept a variable shift count, since shifts by
12468 ;; zero don't affect the flags.  We assume that shifts by constant
12469 ;; zero are optimized away.
12470 (define_insn "*ashrsi3_one_bit_cmp"
12471   [(set (reg FLAGS_REG)
12472         (compare
12473           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12474                        (match_operand:QI 2 "const1_operand" ""))
12475           (const_int 0)))
12476    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12477         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12478   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12479    && ix86_match_ccmode (insn, CCGOCmode)
12480    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12481   "sar{l}\t%0"
12482   [(set_attr "type" "ishift")
12483    (set (attr "length")
12484      (if_then_else (match_operand:SI 0 "register_operand" "")
12485         (const_string "2")
12486         (const_string "*")))])
12487
12488 (define_insn "*ashrsi3_one_bit_cconly"
12489   [(set (reg FLAGS_REG)
12490         (compare
12491           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12492                        (match_operand:QI 2 "const1_operand" ""))
12493           (const_int 0)))
12494    (clobber (match_scratch:SI 0 "=r"))]
12495   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12496    && ix86_match_ccmode (insn, CCGOCmode)
12497    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12498   "sar{l}\t%0"
12499   [(set_attr "type" "ishift")
12500    (set_attr "length" "2")])
12501
12502 (define_insn "*ashrsi3_one_bit_cmp_zext"
12503   [(set (reg FLAGS_REG)
12504         (compare
12505           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12506                        (match_operand:QI 2 "const1_operand" ""))
12507           (const_int 0)))
12508    (set (match_operand:DI 0 "register_operand" "=r")
12509         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12510   "TARGET_64BIT
12511    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12512    && ix86_match_ccmode (insn, CCmode)
12513    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12514   "sar{l}\t%k0"
12515   [(set_attr "type" "ishift")
12516    (set_attr "length" "2")])
12517
12518 ;; This pattern can't accept a variable shift count, since shifts by
12519 ;; zero don't affect the flags.  We assume that shifts by constant
12520 ;; zero are optimized away.
12521 (define_insn "*ashrsi3_cmp"
12522   [(set (reg FLAGS_REG)
12523         (compare
12524           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12525                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12526           (const_int 0)))
12527    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12528         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12529   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12530    && ix86_match_ccmode (insn, CCGOCmode)
12531    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12532   "sar{l}\t{%2, %0|%0, %2}"
12533   [(set_attr "type" "ishift")
12534    (set_attr "mode" "SI")])
12535
12536 (define_insn "*ashrsi3_cconly"
12537   [(set (reg FLAGS_REG)
12538         (compare
12539           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12540                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12541           (const_int 0)))
12542    (clobber (match_scratch:SI 0 "=r"))]
12543   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12544    && ix86_match_ccmode (insn, CCGOCmode)
12545    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12546   "sar{l}\t{%2, %0|%0, %2}"
12547   [(set_attr "type" "ishift")
12548    (set_attr "mode" "SI")])
12549
12550 (define_insn "*ashrsi3_cmp_zext"
12551   [(set (reg FLAGS_REG)
12552         (compare
12553           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12554                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12555           (const_int 0)))
12556    (set (match_operand:DI 0 "register_operand" "=r")
12557         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12558   "TARGET_64BIT
12559    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12560    && ix86_match_ccmode (insn, CCGOCmode)
12561    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12562   "sar{l}\t{%2, %k0|%k0, %2}"
12563   [(set_attr "type" "ishift")
12564    (set_attr "mode" "SI")])
12565
12566 (define_expand "ashrhi3"
12567   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12568         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12569                      (match_operand:QI 2 "nonmemory_operand" "")))]
12570   "TARGET_HIMODE_MATH"
12571   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12572
12573 (define_insn "*ashrhi3_1_one_bit"
12574   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12575         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12576                      (match_operand:QI 2 "const1_operand" "")))
12577    (clobber (reg:CC FLAGS_REG))]
12578   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12579    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12580   "sar{w}\t%0"
12581   [(set_attr "type" "ishift")
12582    (set (attr "length")
12583      (if_then_else (match_operand 0 "register_operand" "")
12584         (const_string "2")
12585         (const_string "*")))])
12586
12587 (define_insn "*ashrhi3_1"
12588   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12589         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12590                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12591    (clobber (reg:CC FLAGS_REG))]
12592   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12593   "@
12594    sar{w}\t{%2, %0|%0, %2}
12595    sar{w}\t{%b2, %0|%0, %b2}"
12596   [(set_attr "type" "ishift")
12597    (set_attr "mode" "HI")])
12598
12599 ;; This pattern can't accept a variable shift count, since shifts by
12600 ;; zero don't affect the flags.  We assume that shifts by constant
12601 ;; zero are optimized away.
12602 (define_insn "*ashrhi3_one_bit_cmp"
12603   [(set (reg FLAGS_REG)
12604         (compare
12605           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12606                        (match_operand:QI 2 "const1_operand" ""))
12607           (const_int 0)))
12608    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12609         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12610   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12611    && ix86_match_ccmode (insn, CCGOCmode)
12612    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12613   "sar{w}\t%0"
12614   [(set_attr "type" "ishift")
12615    (set (attr "length")
12616      (if_then_else (match_operand 0 "register_operand" "")
12617         (const_string "2")
12618         (const_string "*")))])
12619
12620 (define_insn "*ashrhi3_one_bit_cconly"
12621   [(set (reg FLAGS_REG)
12622         (compare
12623           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12624                        (match_operand:QI 2 "const1_operand" ""))
12625           (const_int 0)))
12626    (clobber (match_scratch:HI 0 "=r"))]
12627   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12628    && ix86_match_ccmode (insn, CCGOCmode)
12629    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12630   "sar{w}\t%0"
12631   [(set_attr "type" "ishift")
12632    (set_attr "length" "2")])
12633
12634 ;; This pattern can't accept a variable shift count, since shifts by
12635 ;; zero don't affect the flags.  We assume that shifts by constant
12636 ;; zero are optimized away.
12637 (define_insn "*ashrhi3_cmp"
12638   [(set (reg FLAGS_REG)
12639         (compare
12640           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12641                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12642           (const_int 0)))
12643    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12644         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12645   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12646    && ix86_match_ccmode (insn, CCGOCmode)
12647    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12648   "sar{w}\t{%2, %0|%0, %2}"
12649   [(set_attr "type" "ishift")
12650    (set_attr "mode" "HI")])
12651
12652 (define_insn "*ashrhi3_cconly"
12653   [(set (reg FLAGS_REG)
12654         (compare
12655           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12656                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12657           (const_int 0)))
12658    (clobber (match_scratch:HI 0 "=r"))]
12659   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12660    && ix86_match_ccmode (insn, CCGOCmode)
12661    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12662   "sar{w}\t{%2, %0|%0, %2}"
12663   [(set_attr "type" "ishift")
12664    (set_attr "mode" "HI")])
12665
12666 (define_expand "ashrqi3"
12667   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12668         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12669                      (match_operand:QI 2 "nonmemory_operand" "")))]
12670   "TARGET_QIMODE_MATH"
12671   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12672
12673 (define_insn "*ashrqi3_1_one_bit"
12674   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12675         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12676                      (match_operand:QI 2 "const1_operand" "")))
12677    (clobber (reg:CC FLAGS_REG))]
12678   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12679    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12680   "sar{b}\t%0"
12681   [(set_attr "type" "ishift")
12682    (set (attr "length")
12683      (if_then_else (match_operand 0 "register_operand" "")
12684         (const_string "2")
12685         (const_string "*")))])
12686
12687 (define_insn "*ashrqi3_1_one_bit_slp"
12688   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12689         (ashiftrt:QI (match_dup 0)
12690                      (match_operand:QI 1 "const1_operand" "")))
12691    (clobber (reg:CC FLAGS_REG))]
12692   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12693    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12694    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12695   "sar{b}\t%0"
12696   [(set_attr "type" "ishift1")
12697    (set (attr "length")
12698      (if_then_else (match_operand 0 "register_operand" "")
12699         (const_string "2")
12700         (const_string "*")))])
12701
12702 (define_insn "*ashrqi3_1"
12703   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12704         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12705                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12706    (clobber (reg:CC FLAGS_REG))]
12707   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12708   "@
12709    sar{b}\t{%2, %0|%0, %2}
12710    sar{b}\t{%b2, %0|%0, %b2}"
12711   [(set_attr "type" "ishift")
12712    (set_attr "mode" "QI")])
12713
12714 (define_insn "*ashrqi3_1_slp"
12715   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12716         (ashiftrt:QI (match_dup 0)
12717                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12718    (clobber (reg:CC FLAGS_REG))]
12719   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12720    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12721   "@
12722    sar{b}\t{%1, %0|%0, %1}
12723    sar{b}\t{%b1, %0|%0, %b1}"
12724   [(set_attr "type" "ishift1")
12725    (set_attr "mode" "QI")])
12726
12727 ;; This pattern can't accept a variable shift count, since shifts by
12728 ;; zero don't affect the flags.  We assume that shifts by constant
12729 ;; zero are optimized away.
12730 (define_insn "*ashrqi3_one_bit_cmp"
12731   [(set (reg FLAGS_REG)
12732         (compare
12733           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12734                        (match_operand:QI 2 "const1_operand" "I"))
12735           (const_int 0)))
12736    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12737         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12738   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12739    && ix86_match_ccmode (insn, CCGOCmode)
12740    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12741   "sar{b}\t%0"
12742   [(set_attr "type" "ishift")
12743    (set (attr "length")
12744      (if_then_else (match_operand 0 "register_operand" "")
12745         (const_string "2")
12746         (const_string "*")))])
12747
12748 (define_insn "*ashrqi3_one_bit_cconly"
12749   [(set (reg FLAGS_REG)
12750         (compare
12751           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12752                        (match_operand:QI 2 "const1_operand" ""))
12753           (const_int 0)))
12754    (clobber (match_scratch:QI 0 "=q"))]
12755   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12756    && ix86_match_ccmode (insn, CCGOCmode)
12757    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12758   "sar{b}\t%0"
12759   [(set_attr "type" "ishift")
12760    (set_attr "length" "2")])
12761
12762 ;; This pattern can't accept a variable shift count, since shifts by
12763 ;; zero don't affect the flags.  We assume that shifts by constant
12764 ;; zero are optimized away.
12765 (define_insn "*ashrqi3_cmp"
12766   [(set (reg FLAGS_REG)
12767         (compare
12768           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12769                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12770           (const_int 0)))
12771    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12772         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12773   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12774    && ix86_match_ccmode (insn, CCGOCmode)
12775    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12776   "sar{b}\t{%2, %0|%0, %2}"
12777   [(set_attr "type" "ishift")
12778    (set_attr "mode" "QI")])
12779
12780 (define_insn "*ashrqi3_cconly"
12781   [(set (reg FLAGS_REG)
12782         (compare
12783           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12784                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12785           (const_int 0)))
12786    (clobber (match_scratch:QI 0 "=q"))]
12787   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12788    && ix86_match_ccmode (insn, CCGOCmode)
12789    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12790   "sar{b}\t{%2, %0|%0, %2}"
12791   [(set_attr "type" "ishift")
12792    (set_attr "mode" "QI")])
12793
12794 \f
12795 ;; Logical shift instructions
12796
12797 ;; See comment above `ashldi3' about how this works.
12798
12799 (define_expand "lshrti3"
12800   [(set (match_operand:TI 0 "register_operand" "")
12801         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12802                      (match_operand:QI 2 "nonmemory_operand" "")))]
12803   "TARGET_64BIT"
12804   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12805
12806 ;; This pattern must be defined before *lshrti3_1 to prevent
12807 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12808
12809 (define_insn "*avx_lshrti3"
12810   [(set (match_operand:TI 0 "register_operand" "=x")
12811         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12812                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12813   "TARGET_AVX"
12814 {
12815   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12816   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12817 }
12818   [(set_attr "type" "sseishft")
12819    (set_attr "prefix" "vex")
12820    (set_attr "mode" "TI")])
12821
12822 (define_insn "sse2_lshrti3"
12823   [(set (match_operand:TI 0 "register_operand" "=x")
12824         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12825                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12826   "TARGET_SSE2"
12827 {
12828   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12829   return "psrldq\t{%2, %0|%0, %2}";
12830 }
12831   [(set_attr "type" "sseishft")
12832    (set_attr "prefix_data16" "1")
12833    (set_attr "mode" "TI")])
12834
12835 (define_insn "*lshrti3_1"
12836   [(set (match_operand:TI 0 "register_operand" "=r")
12837         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12838                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12839    (clobber (reg:CC FLAGS_REG))]
12840   "TARGET_64BIT"
12841   "#"
12842   [(set_attr "type" "multi")])
12843
12844 (define_peephole2
12845   [(match_scratch:DI 3 "r")
12846    (parallel [(set (match_operand:TI 0 "register_operand" "")
12847                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12848                                 (match_operand:QI 2 "nonmemory_operand" "")))
12849               (clobber (reg:CC FLAGS_REG))])
12850    (match_dup 3)]
12851   "TARGET_64BIT"
12852   [(const_int 0)]
12853   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12854
12855 (define_split
12856   [(set (match_operand:TI 0 "register_operand" "")
12857         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12858                      (match_operand:QI 2 "nonmemory_operand" "")))
12859    (clobber (reg:CC FLAGS_REG))]
12860   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12861                     ? epilogue_completed : reload_completed)"
12862   [(const_int 0)]
12863   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12864
12865 (define_expand "lshrdi3"
12866   [(set (match_operand:DI 0 "shiftdi_operand" "")
12867         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12868                      (match_operand:QI 2 "nonmemory_operand" "")))]
12869   ""
12870   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12871
12872 (define_insn "*lshrdi3_1_one_bit_rex64"
12873   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12874         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12875                      (match_operand:QI 2 "const1_operand" "")))
12876    (clobber (reg:CC FLAGS_REG))]
12877   "TARGET_64BIT
12878    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12879    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12880   "shr{q}\t%0"
12881   [(set_attr "type" "ishift")
12882    (set (attr "length")
12883      (if_then_else (match_operand:DI 0 "register_operand" "")
12884         (const_string "2")
12885         (const_string "*")))])
12886
12887 (define_insn "*lshrdi3_1_rex64"
12888   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12889         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12890                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12891    (clobber (reg:CC FLAGS_REG))]
12892   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12893   "@
12894    shr{q}\t{%2, %0|%0, %2}
12895    shr{q}\t{%b2, %0|%0, %b2}"
12896   [(set_attr "type" "ishift")
12897    (set_attr "mode" "DI")])
12898
12899 ;; This pattern can't accept a variable shift count, since shifts by
12900 ;; zero don't affect the flags.  We assume that shifts by constant
12901 ;; zero are optimized away.
12902 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12903   [(set (reg FLAGS_REG)
12904         (compare
12905           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12906                        (match_operand:QI 2 "const1_operand" ""))
12907           (const_int 0)))
12908    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12909         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12910   "TARGET_64BIT
12911    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12912    && ix86_match_ccmode (insn, CCGOCmode)
12913    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12914   "shr{q}\t%0"
12915   [(set_attr "type" "ishift")
12916    (set (attr "length")
12917      (if_then_else (match_operand:DI 0 "register_operand" "")
12918         (const_string "2")
12919         (const_string "*")))])
12920
12921 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12922   [(set (reg FLAGS_REG)
12923         (compare
12924           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12925                        (match_operand:QI 2 "const1_operand" ""))
12926           (const_int 0)))
12927    (clobber (match_scratch:DI 0 "=r"))]
12928   "TARGET_64BIT
12929    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12930    && ix86_match_ccmode (insn, CCGOCmode)
12931    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12932   "shr{q}\t%0"
12933   [(set_attr "type" "ishift")
12934    (set_attr "length" "2")])
12935
12936 ;; This pattern can't accept a variable shift count, since shifts by
12937 ;; zero don't affect the flags.  We assume that shifts by constant
12938 ;; zero are optimized away.
12939 (define_insn "*lshrdi3_cmp_rex64"
12940   [(set (reg FLAGS_REG)
12941         (compare
12942           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12943                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12944           (const_int 0)))
12945    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12946         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12947   "TARGET_64BIT
12948    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12949    && ix86_match_ccmode (insn, CCGOCmode)
12950    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12951   "shr{q}\t{%2, %0|%0, %2}"
12952   [(set_attr "type" "ishift")
12953    (set_attr "mode" "DI")])
12954
12955 (define_insn "*lshrdi3_cconly_rex64"
12956   [(set (reg FLAGS_REG)
12957         (compare
12958           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12959                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12960           (const_int 0)))
12961    (clobber (match_scratch:DI 0 "=r"))]
12962   "TARGET_64BIT
12963    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12964    && ix86_match_ccmode (insn, CCGOCmode)
12965    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12966   "shr{q}\t{%2, %0|%0, %2}"
12967   [(set_attr "type" "ishift")
12968    (set_attr "mode" "DI")])
12969
12970 (define_insn "*lshrdi3_1"
12971   [(set (match_operand:DI 0 "register_operand" "=r")
12972         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12973                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12974    (clobber (reg:CC FLAGS_REG))]
12975   "!TARGET_64BIT"
12976   "#"
12977   [(set_attr "type" "multi")])
12978
12979 ;; By default we don't ask for a scratch register, because when DImode
12980 ;; values are manipulated, registers are already at a premium.  But if
12981 ;; we have one handy, we won't turn it away.
12982 (define_peephole2
12983   [(match_scratch:SI 3 "r")
12984    (parallel [(set (match_operand:DI 0 "register_operand" "")
12985                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12986                                 (match_operand:QI 2 "nonmemory_operand" "")))
12987               (clobber (reg:CC FLAGS_REG))])
12988    (match_dup 3)]
12989   "!TARGET_64BIT && TARGET_CMOVE"
12990   [(const_int 0)]
12991   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12992
12993 (define_split
12994   [(set (match_operand:DI 0 "register_operand" "")
12995         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12996                      (match_operand:QI 2 "nonmemory_operand" "")))
12997    (clobber (reg:CC FLAGS_REG))]
12998   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12999                      ? epilogue_completed : reload_completed)"
13000   [(const_int 0)]
13001   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13002
13003 (define_expand "lshrsi3"
13004   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13005         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13006                      (match_operand:QI 2 "nonmemory_operand" "")))]
13007   ""
13008   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13009
13010 (define_insn "*lshrsi3_1_one_bit"
13011   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13012         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13013                      (match_operand:QI 2 "const1_operand" "")))
13014    (clobber (reg:CC FLAGS_REG))]
13015   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13016    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13017   "shr{l}\t%0"
13018   [(set_attr "type" "ishift")
13019    (set (attr "length")
13020      (if_then_else (match_operand:SI 0 "register_operand" "")
13021         (const_string "2")
13022         (const_string "*")))])
13023
13024 (define_insn "*lshrsi3_1_one_bit_zext"
13025   [(set (match_operand:DI 0 "register_operand" "=r")
13026         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13027                      (match_operand:QI 2 "const1_operand" "")))
13028    (clobber (reg:CC FLAGS_REG))]
13029   "TARGET_64BIT
13030    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13031    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13032   "shr{l}\t%k0"
13033   [(set_attr "type" "ishift")
13034    (set_attr "length" "2")])
13035
13036 (define_insn "*lshrsi3_1"
13037   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13038         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13039                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13040    (clobber (reg:CC FLAGS_REG))]
13041   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13042   "@
13043    shr{l}\t{%2, %0|%0, %2}
13044    shr{l}\t{%b2, %0|%0, %b2}"
13045   [(set_attr "type" "ishift")
13046    (set_attr "mode" "SI")])
13047
13048 (define_insn "*lshrsi3_1_zext"
13049   [(set (match_operand:DI 0 "register_operand" "=r,r")
13050         (zero_extend:DI
13051           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13052                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13053    (clobber (reg:CC FLAGS_REG))]
13054   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13055   "@
13056    shr{l}\t{%2, %k0|%k0, %2}
13057    shr{l}\t{%b2, %k0|%k0, %b2}"
13058   [(set_attr "type" "ishift")
13059    (set_attr "mode" "SI")])
13060
13061 ;; This pattern can't accept a variable shift count, since shifts by
13062 ;; zero don't affect the flags.  We assume that shifts by constant
13063 ;; zero are optimized away.
13064 (define_insn "*lshrsi3_one_bit_cmp"
13065   [(set (reg FLAGS_REG)
13066         (compare
13067           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13068                        (match_operand:QI 2 "const1_operand" ""))
13069           (const_int 0)))
13070    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13071         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13072   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13073    && ix86_match_ccmode (insn, CCGOCmode)
13074    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13075   "shr{l}\t%0"
13076   [(set_attr "type" "ishift")
13077    (set (attr "length")
13078      (if_then_else (match_operand:SI 0 "register_operand" "")
13079         (const_string "2")
13080         (const_string "*")))])
13081
13082 (define_insn "*lshrsi3_one_bit_cconly"
13083   [(set (reg FLAGS_REG)
13084         (compare
13085           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13086                        (match_operand:QI 2 "const1_operand" ""))
13087           (const_int 0)))
13088    (clobber (match_scratch:SI 0 "=r"))]
13089   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13090    && ix86_match_ccmode (insn, CCGOCmode)
13091    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13092   "shr{l}\t%0"
13093   [(set_attr "type" "ishift")
13094    (set_attr "length" "2")])
13095
13096 (define_insn "*lshrsi3_cmp_one_bit_zext"
13097   [(set (reg FLAGS_REG)
13098         (compare
13099           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13100                        (match_operand:QI 2 "const1_operand" ""))
13101           (const_int 0)))
13102    (set (match_operand:DI 0 "register_operand" "=r")
13103         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13104   "TARGET_64BIT
13105    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13106    && ix86_match_ccmode (insn, CCGOCmode)
13107    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13108   "shr{l}\t%k0"
13109   [(set_attr "type" "ishift")
13110    (set_attr "length" "2")])
13111
13112 ;; This pattern can't accept a variable shift count, since shifts by
13113 ;; zero don't affect the flags.  We assume that shifts by constant
13114 ;; zero are optimized away.
13115 (define_insn "*lshrsi3_cmp"
13116   [(set (reg FLAGS_REG)
13117         (compare
13118           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13119                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13120           (const_int 0)))
13121    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13122         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13123   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13124    && ix86_match_ccmode (insn, CCGOCmode)
13125    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13126   "shr{l}\t{%2, %0|%0, %2}"
13127   [(set_attr "type" "ishift")
13128    (set_attr "mode" "SI")])
13129
13130 (define_insn "*lshrsi3_cconly"
13131   [(set (reg FLAGS_REG)
13132       (compare
13133         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13134                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13135         (const_int 0)))
13136    (clobber (match_scratch:SI 0 "=r"))]
13137   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13138    && ix86_match_ccmode (insn, CCGOCmode)
13139    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13140   "shr{l}\t{%2, %0|%0, %2}"
13141   [(set_attr "type" "ishift")
13142    (set_attr "mode" "SI")])
13143
13144 (define_insn "*lshrsi3_cmp_zext"
13145   [(set (reg FLAGS_REG)
13146         (compare
13147           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13148                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13149           (const_int 0)))
13150    (set (match_operand:DI 0 "register_operand" "=r")
13151         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13152   "TARGET_64BIT
13153    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13154    && ix86_match_ccmode (insn, CCGOCmode)
13155    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13156   "shr{l}\t{%2, %k0|%k0, %2}"
13157   [(set_attr "type" "ishift")
13158    (set_attr "mode" "SI")])
13159
13160 (define_expand "lshrhi3"
13161   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13162         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13163                      (match_operand:QI 2 "nonmemory_operand" "")))]
13164   "TARGET_HIMODE_MATH"
13165   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13166
13167 (define_insn "*lshrhi3_1_one_bit"
13168   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13169         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13170                      (match_operand:QI 2 "const1_operand" "")))
13171    (clobber (reg:CC FLAGS_REG))]
13172   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13173    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13174   "shr{w}\t%0"
13175   [(set_attr "type" "ishift")
13176    (set (attr "length")
13177      (if_then_else (match_operand 0 "register_operand" "")
13178         (const_string "2")
13179         (const_string "*")))])
13180
13181 (define_insn "*lshrhi3_1"
13182   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13183         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13184                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13185    (clobber (reg:CC FLAGS_REG))]
13186   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13187   "@
13188    shr{w}\t{%2, %0|%0, %2}
13189    shr{w}\t{%b2, %0|%0, %b2}"
13190   [(set_attr "type" "ishift")
13191    (set_attr "mode" "HI")])
13192
13193 ;; This pattern can't accept a variable shift count, since shifts by
13194 ;; zero don't affect the flags.  We assume that shifts by constant
13195 ;; zero are optimized away.
13196 (define_insn "*lshrhi3_one_bit_cmp"
13197   [(set (reg FLAGS_REG)
13198         (compare
13199           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13200                        (match_operand:QI 2 "const1_operand" ""))
13201           (const_int 0)))
13202    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13203         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13204   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13205    && ix86_match_ccmode (insn, CCGOCmode)
13206    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13207   "shr{w}\t%0"
13208   [(set_attr "type" "ishift")
13209    (set (attr "length")
13210      (if_then_else (match_operand:SI 0 "register_operand" "")
13211         (const_string "2")
13212         (const_string "*")))])
13213
13214 (define_insn "*lshrhi3_one_bit_cconly"
13215   [(set (reg FLAGS_REG)
13216         (compare
13217           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13218                        (match_operand:QI 2 "const1_operand" ""))
13219           (const_int 0)))
13220    (clobber (match_scratch:HI 0 "=r"))]
13221   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13222    && ix86_match_ccmode (insn, CCGOCmode)
13223    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13224   "shr{w}\t%0"
13225   [(set_attr "type" "ishift")
13226    (set_attr "length" "2")])
13227
13228 ;; This pattern can't accept a variable shift count, since shifts by
13229 ;; zero don't affect the flags.  We assume that shifts by constant
13230 ;; zero are optimized away.
13231 (define_insn "*lshrhi3_cmp"
13232   [(set (reg FLAGS_REG)
13233         (compare
13234           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13235                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13236           (const_int 0)))
13237    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13238         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13239   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13240    && ix86_match_ccmode (insn, CCGOCmode)
13241    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13242   "shr{w}\t{%2, %0|%0, %2}"
13243   [(set_attr "type" "ishift")
13244    (set_attr "mode" "HI")])
13245
13246 (define_insn "*lshrhi3_cconly"
13247   [(set (reg FLAGS_REG)
13248         (compare
13249           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13250                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13251           (const_int 0)))
13252    (clobber (match_scratch:HI 0 "=r"))]
13253   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13254    && ix86_match_ccmode (insn, CCGOCmode)
13255    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13256   "shr{w}\t{%2, %0|%0, %2}"
13257   [(set_attr "type" "ishift")
13258    (set_attr "mode" "HI")])
13259
13260 (define_expand "lshrqi3"
13261   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13262         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13263                      (match_operand:QI 2 "nonmemory_operand" "")))]
13264   "TARGET_QIMODE_MATH"
13265   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13266
13267 (define_insn "*lshrqi3_1_one_bit"
13268   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13269         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13270                      (match_operand:QI 2 "const1_operand" "")))
13271    (clobber (reg:CC FLAGS_REG))]
13272   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13273    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13274   "shr{b}\t%0"
13275   [(set_attr "type" "ishift")
13276    (set (attr "length")
13277      (if_then_else (match_operand 0 "register_operand" "")
13278         (const_string "2")
13279         (const_string "*")))])
13280
13281 (define_insn "*lshrqi3_1_one_bit_slp"
13282   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13283         (lshiftrt:QI (match_dup 0)
13284                      (match_operand:QI 1 "const1_operand" "")))
13285    (clobber (reg:CC FLAGS_REG))]
13286   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13287    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13288   "shr{b}\t%0"
13289   [(set_attr "type" "ishift1")
13290    (set (attr "length")
13291      (if_then_else (match_operand 0 "register_operand" "")
13292         (const_string "2")
13293         (const_string "*")))])
13294
13295 (define_insn "*lshrqi3_1"
13296   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13297         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13298                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13299    (clobber (reg:CC FLAGS_REG))]
13300   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13301   "@
13302    shr{b}\t{%2, %0|%0, %2}
13303    shr{b}\t{%b2, %0|%0, %b2}"
13304   [(set_attr "type" "ishift")
13305    (set_attr "mode" "QI")])
13306
13307 (define_insn "*lshrqi3_1_slp"
13308   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13309         (lshiftrt:QI (match_dup 0)
13310                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13311    (clobber (reg:CC FLAGS_REG))]
13312   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13313    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13314   "@
13315    shr{b}\t{%1, %0|%0, %1}
13316    shr{b}\t{%b1, %0|%0, %b1}"
13317   [(set_attr "type" "ishift1")
13318    (set_attr "mode" "QI")])
13319
13320 ;; This pattern can't accept a variable shift count, since shifts by
13321 ;; zero don't affect the flags.  We assume that shifts by constant
13322 ;; zero are optimized away.
13323 (define_insn "*lshrqi2_one_bit_cmp"
13324   [(set (reg FLAGS_REG)
13325         (compare
13326           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13327                        (match_operand:QI 2 "const1_operand" ""))
13328           (const_int 0)))
13329    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13330         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13331   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13332    && ix86_match_ccmode (insn, CCGOCmode)
13333    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13334   "shr{b}\t%0"
13335   [(set_attr "type" "ishift")
13336    (set (attr "length")
13337      (if_then_else (match_operand:SI 0 "register_operand" "")
13338         (const_string "2")
13339         (const_string "*")))])
13340
13341 (define_insn "*lshrqi2_one_bit_cconly"
13342   [(set (reg FLAGS_REG)
13343         (compare
13344           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13345                        (match_operand:QI 2 "const1_operand" ""))
13346           (const_int 0)))
13347    (clobber (match_scratch:QI 0 "=q"))]
13348   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13349    && ix86_match_ccmode (insn, CCGOCmode)
13350    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13351   "shr{b}\t%0"
13352   [(set_attr "type" "ishift")
13353    (set_attr "length" "2")])
13354
13355 ;; This pattern can't accept a variable shift count, since shifts by
13356 ;; zero don't affect the flags.  We assume that shifts by constant
13357 ;; zero are optimized away.
13358 (define_insn "*lshrqi2_cmp"
13359   [(set (reg FLAGS_REG)
13360         (compare
13361           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13362                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13363           (const_int 0)))
13364    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13365         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13366   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13367    && ix86_match_ccmode (insn, CCGOCmode)
13368    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13369   "shr{b}\t{%2, %0|%0, %2}"
13370   [(set_attr "type" "ishift")
13371    (set_attr "mode" "QI")])
13372
13373 (define_insn "*lshrqi2_cconly"
13374   [(set (reg FLAGS_REG)
13375         (compare
13376           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13377                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13378           (const_int 0)))
13379    (clobber (match_scratch:QI 0 "=q"))]
13380   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13381    && ix86_match_ccmode (insn, CCGOCmode)
13382    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13383   "shr{b}\t{%2, %0|%0, %2}"
13384   [(set_attr "type" "ishift")
13385    (set_attr "mode" "QI")])
13386 \f
13387 ;; Rotate instructions
13388
13389 (define_expand "rotldi3"
13390   [(set (match_operand:DI 0 "shiftdi_operand" "")
13391         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13392                    (match_operand:QI 2 "nonmemory_operand" "")))]
13393  ""
13394 {
13395   if (TARGET_64BIT)
13396     {
13397       ix86_expand_binary_operator (ROTATE, DImode, operands);
13398       DONE;
13399     }
13400   if (!const_1_to_31_operand (operands[2], VOIDmode))
13401     FAIL;
13402   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13403   DONE;
13404 })
13405
13406 ;; Implement rotation using two double-precision shift instructions
13407 ;; and a scratch register.
13408 (define_insn_and_split "ix86_rotldi3"
13409  [(set (match_operand:DI 0 "register_operand" "=r")
13410        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13411                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13412   (clobber (reg:CC FLAGS_REG))
13413   (clobber (match_scratch:SI 3 "=&r"))]
13414  "!TARGET_64BIT"
13415  ""
13416  "&& reload_completed"
13417  [(set (match_dup 3) (match_dup 4))
13418   (parallel
13419    [(set (match_dup 4)
13420          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13421                  (lshiftrt:SI (match_dup 5)
13422                               (minus:QI (const_int 32) (match_dup 2)))))
13423     (clobber (reg:CC FLAGS_REG))])
13424   (parallel
13425    [(set (match_dup 5)
13426          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13427                  (lshiftrt:SI (match_dup 3)
13428                               (minus:QI (const_int 32) (match_dup 2)))))
13429     (clobber (reg:CC FLAGS_REG))])]
13430  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13431
13432 (define_insn "*rotlsi3_1_one_bit_rex64"
13433   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13434         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13435                    (match_operand:QI 2 "const1_operand" "")))
13436    (clobber (reg:CC FLAGS_REG))]
13437   "TARGET_64BIT
13438    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13439    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13440   "rol{q}\t%0"
13441   [(set_attr "type" "rotate")
13442    (set (attr "length")
13443      (if_then_else (match_operand:DI 0 "register_operand" "")
13444         (const_string "2")
13445         (const_string "*")))])
13446
13447 (define_insn "*rotldi3_1_rex64"
13448   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13449         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13450                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13451    (clobber (reg:CC FLAGS_REG))]
13452   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13453   "@
13454    rol{q}\t{%2, %0|%0, %2}
13455    rol{q}\t{%b2, %0|%0, %b2}"
13456   [(set_attr "type" "rotate")
13457    (set_attr "mode" "DI")])
13458
13459 (define_expand "rotlsi3"
13460   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13461         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13462                    (match_operand:QI 2 "nonmemory_operand" "")))]
13463   ""
13464   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13465
13466 (define_insn "*rotlsi3_1_one_bit"
13467   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13468         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13469                    (match_operand:QI 2 "const1_operand" "")))
13470    (clobber (reg:CC FLAGS_REG))]
13471   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13472    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13473   "rol{l}\t%0"
13474   [(set_attr "type" "rotate")
13475    (set (attr "length")
13476      (if_then_else (match_operand:SI 0 "register_operand" "")
13477         (const_string "2")
13478         (const_string "*")))])
13479
13480 (define_insn "*rotlsi3_1_one_bit_zext"
13481   [(set (match_operand:DI 0 "register_operand" "=r")
13482         (zero_extend:DI
13483           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13484                      (match_operand:QI 2 "const1_operand" ""))))
13485    (clobber (reg:CC FLAGS_REG))]
13486   "TARGET_64BIT
13487    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13488    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13489   "rol{l}\t%k0"
13490   [(set_attr "type" "rotate")
13491    (set_attr "length" "2")])
13492
13493 (define_insn "*rotlsi3_1"
13494   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13495         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13496                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13497    (clobber (reg:CC FLAGS_REG))]
13498   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13499   "@
13500    rol{l}\t{%2, %0|%0, %2}
13501    rol{l}\t{%b2, %0|%0, %b2}"
13502   [(set_attr "type" "rotate")
13503    (set_attr "mode" "SI")])
13504
13505 (define_insn "*rotlsi3_1_zext"
13506   [(set (match_operand:DI 0 "register_operand" "=r,r")
13507         (zero_extend:DI
13508           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13509                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13510    (clobber (reg:CC FLAGS_REG))]
13511   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13512   "@
13513    rol{l}\t{%2, %k0|%k0, %2}
13514    rol{l}\t{%b2, %k0|%k0, %b2}"
13515   [(set_attr "type" "rotate")
13516    (set_attr "mode" "SI")])
13517
13518 (define_expand "rotlhi3"
13519   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13520         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13521                    (match_operand:QI 2 "nonmemory_operand" "")))]
13522   "TARGET_HIMODE_MATH"
13523   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13524
13525 (define_insn "*rotlhi3_1_one_bit"
13526   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13527         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13528                    (match_operand:QI 2 "const1_operand" "")))
13529    (clobber (reg:CC FLAGS_REG))]
13530   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13531    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13532   "rol{w}\t%0"
13533   [(set_attr "type" "rotate")
13534    (set (attr "length")
13535      (if_then_else (match_operand 0 "register_operand" "")
13536         (const_string "2")
13537         (const_string "*")))])
13538
13539 (define_insn "*rotlhi3_1"
13540   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13541         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13542                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13543    (clobber (reg:CC FLAGS_REG))]
13544   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13545   "@
13546    rol{w}\t{%2, %0|%0, %2}
13547    rol{w}\t{%b2, %0|%0, %b2}"
13548   [(set_attr "type" "rotate")
13549    (set_attr "mode" "HI")])
13550
13551 (define_split
13552  [(set (match_operand:HI 0 "register_operand" "")
13553        (rotate:HI (match_dup 0) (const_int 8)))
13554   (clobber (reg:CC FLAGS_REG))]
13555  "reload_completed"
13556  [(parallel [(set (strict_low_part (match_dup 0))
13557                   (bswap:HI (match_dup 0)))
13558              (clobber (reg:CC FLAGS_REG))])]
13559  "")
13560
13561 (define_expand "rotlqi3"
13562   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13563         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13564                    (match_operand:QI 2 "nonmemory_operand" "")))]
13565   "TARGET_QIMODE_MATH"
13566   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13567
13568 (define_insn "*rotlqi3_1_one_bit_slp"
13569   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13570         (rotate:QI (match_dup 0)
13571                    (match_operand:QI 1 "const1_operand" "")))
13572    (clobber (reg:CC FLAGS_REG))]
13573   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13574    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13575   "rol{b}\t%0"
13576   [(set_attr "type" "rotate1")
13577    (set (attr "length")
13578      (if_then_else (match_operand 0 "register_operand" "")
13579         (const_string "2")
13580         (const_string "*")))])
13581
13582 (define_insn "*rotlqi3_1_one_bit"
13583   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13584         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13585                    (match_operand:QI 2 "const1_operand" "")))
13586    (clobber (reg:CC FLAGS_REG))]
13587   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13588    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13589   "rol{b}\t%0"
13590   [(set_attr "type" "rotate")
13591    (set (attr "length")
13592      (if_then_else (match_operand 0 "register_operand" "")
13593         (const_string "2")
13594         (const_string "*")))])
13595
13596 (define_insn "*rotlqi3_1_slp"
13597   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13598         (rotate:QI (match_dup 0)
13599                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13600    (clobber (reg:CC FLAGS_REG))]
13601   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13602    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13603   "@
13604    rol{b}\t{%1, %0|%0, %1}
13605    rol{b}\t{%b1, %0|%0, %b1}"
13606   [(set_attr "type" "rotate1")
13607    (set_attr "mode" "QI")])
13608
13609 (define_insn "*rotlqi3_1"
13610   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13611         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13612                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13613    (clobber (reg:CC FLAGS_REG))]
13614   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13615   "@
13616    rol{b}\t{%2, %0|%0, %2}
13617    rol{b}\t{%b2, %0|%0, %b2}"
13618   [(set_attr "type" "rotate")
13619    (set_attr "mode" "QI")])
13620
13621 (define_expand "rotrdi3"
13622   [(set (match_operand:DI 0 "shiftdi_operand" "")
13623         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13624                    (match_operand:QI 2 "nonmemory_operand" "")))]
13625  ""
13626 {
13627   if (TARGET_64BIT)
13628     {
13629       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13630       DONE;
13631     }
13632   if (!const_1_to_31_operand (operands[2], VOIDmode))
13633     FAIL;
13634   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13635   DONE;
13636 })
13637
13638 ;; Implement rotation using two double-precision shift instructions
13639 ;; and a scratch register.
13640 (define_insn_and_split "ix86_rotrdi3"
13641  [(set (match_operand:DI 0 "register_operand" "=r")
13642        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13643                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13644   (clobber (reg:CC FLAGS_REG))
13645   (clobber (match_scratch:SI 3 "=&r"))]
13646  "!TARGET_64BIT"
13647  ""
13648  "&& reload_completed"
13649  [(set (match_dup 3) (match_dup 4))
13650   (parallel
13651    [(set (match_dup 4)
13652          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13653                  (ashift:SI (match_dup 5)
13654                             (minus:QI (const_int 32) (match_dup 2)))))
13655     (clobber (reg:CC FLAGS_REG))])
13656   (parallel
13657    [(set (match_dup 5)
13658          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13659                  (ashift:SI (match_dup 3)
13660                             (minus:QI (const_int 32) (match_dup 2)))))
13661     (clobber (reg:CC FLAGS_REG))])]
13662  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13663
13664 (define_insn "*rotrdi3_1_one_bit_rex64"
13665   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13666         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13667                      (match_operand:QI 2 "const1_operand" "")))
13668    (clobber (reg:CC FLAGS_REG))]
13669   "TARGET_64BIT
13670    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13671    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13672   "ror{q}\t%0"
13673   [(set_attr "type" "rotate")
13674    (set (attr "length")
13675      (if_then_else (match_operand:DI 0 "register_operand" "")
13676         (const_string "2")
13677         (const_string "*")))])
13678
13679 (define_insn "*rotrdi3_1_rex64"
13680   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13681         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13682                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13683    (clobber (reg:CC FLAGS_REG))]
13684   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13685   "@
13686    ror{q}\t{%2, %0|%0, %2}
13687    ror{q}\t{%b2, %0|%0, %b2}"
13688   [(set_attr "type" "rotate")
13689    (set_attr "mode" "DI")])
13690
13691 (define_expand "rotrsi3"
13692   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13693         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13694                      (match_operand:QI 2 "nonmemory_operand" "")))]
13695   ""
13696   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13697
13698 (define_insn "*rotrsi3_1_one_bit"
13699   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13700         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13701                      (match_operand:QI 2 "const1_operand" "")))
13702    (clobber (reg:CC FLAGS_REG))]
13703   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13704    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13705   "ror{l}\t%0"
13706   [(set_attr "type" "rotate")
13707    (set (attr "length")
13708      (if_then_else (match_operand:SI 0 "register_operand" "")
13709         (const_string "2")
13710         (const_string "*")))])
13711
13712 (define_insn "*rotrsi3_1_one_bit_zext"
13713   [(set (match_operand:DI 0 "register_operand" "=r")
13714         (zero_extend:DI
13715           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13716                        (match_operand:QI 2 "const1_operand" ""))))
13717    (clobber (reg:CC FLAGS_REG))]
13718   "TARGET_64BIT
13719    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13720    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13721   "ror{l}\t%k0"
13722   [(set_attr "type" "rotate")
13723    (set (attr "length")
13724      (if_then_else (match_operand:SI 0 "register_operand" "")
13725         (const_string "2")
13726         (const_string "*")))])
13727
13728 (define_insn "*rotrsi3_1"
13729   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13730         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13731                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13732    (clobber (reg:CC FLAGS_REG))]
13733   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13734   "@
13735    ror{l}\t{%2, %0|%0, %2}
13736    ror{l}\t{%b2, %0|%0, %b2}"
13737   [(set_attr "type" "rotate")
13738    (set_attr "mode" "SI")])
13739
13740 (define_insn "*rotrsi3_1_zext"
13741   [(set (match_operand:DI 0 "register_operand" "=r,r")
13742         (zero_extend:DI
13743           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13744                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13745    (clobber (reg:CC FLAGS_REG))]
13746   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13747   "@
13748    ror{l}\t{%2, %k0|%k0, %2}
13749    ror{l}\t{%b2, %k0|%k0, %b2}"
13750   [(set_attr "type" "rotate")
13751    (set_attr "mode" "SI")])
13752
13753 (define_expand "rotrhi3"
13754   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13755         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13756                      (match_operand:QI 2 "nonmemory_operand" "")))]
13757   "TARGET_HIMODE_MATH"
13758   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13759
13760 (define_insn "*rotrhi3_one_bit"
13761   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13762         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13763                      (match_operand:QI 2 "const1_operand" "")))
13764    (clobber (reg:CC FLAGS_REG))]
13765   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13766    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13767   "ror{w}\t%0"
13768   [(set_attr "type" "rotate")
13769    (set (attr "length")
13770      (if_then_else (match_operand 0 "register_operand" "")
13771         (const_string "2")
13772         (const_string "*")))])
13773
13774 (define_insn "*rotrhi3_1"
13775   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13776         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13777                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13778    (clobber (reg:CC FLAGS_REG))]
13779   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13780   "@
13781    ror{w}\t{%2, %0|%0, %2}
13782    ror{w}\t{%b2, %0|%0, %b2}"
13783   [(set_attr "type" "rotate")
13784    (set_attr "mode" "HI")])
13785
13786 (define_split
13787  [(set (match_operand:HI 0 "register_operand" "")
13788        (rotatert:HI (match_dup 0) (const_int 8)))
13789   (clobber (reg:CC FLAGS_REG))]
13790  "reload_completed"
13791  [(parallel [(set (strict_low_part (match_dup 0))
13792                   (bswap:HI (match_dup 0)))
13793              (clobber (reg:CC FLAGS_REG))])]
13794  "")
13795
13796 (define_expand "rotrqi3"
13797   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13798         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13799                      (match_operand:QI 2 "nonmemory_operand" "")))]
13800   "TARGET_QIMODE_MATH"
13801   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13802
13803 (define_insn "*rotrqi3_1_one_bit"
13804   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13805         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13806                      (match_operand:QI 2 "const1_operand" "")))
13807    (clobber (reg:CC FLAGS_REG))]
13808   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13809    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13810   "ror{b}\t%0"
13811   [(set_attr "type" "rotate")
13812    (set (attr "length")
13813      (if_then_else (match_operand 0 "register_operand" "")
13814         (const_string "2")
13815         (const_string "*")))])
13816
13817 (define_insn "*rotrqi3_1_one_bit_slp"
13818   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13819         (rotatert:QI (match_dup 0)
13820                      (match_operand:QI 1 "const1_operand" "")))
13821    (clobber (reg:CC FLAGS_REG))]
13822   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13823    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13824   "ror{b}\t%0"
13825   [(set_attr "type" "rotate1")
13826    (set (attr "length")
13827      (if_then_else (match_operand 0 "register_operand" "")
13828         (const_string "2")
13829         (const_string "*")))])
13830
13831 (define_insn "*rotrqi3_1"
13832   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13833         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13834                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13835    (clobber (reg:CC FLAGS_REG))]
13836   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13837   "@
13838    ror{b}\t{%2, %0|%0, %2}
13839    ror{b}\t{%b2, %0|%0, %b2}"
13840   [(set_attr "type" "rotate")
13841    (set_attr "mode" "QI")])
13842
13843 (define_insn "*rotrqi3_1_slp"
13844   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13845         (rotatert:QI (match_dup 0)
13846                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13847    (clobber (reg:CC FLAGS_REG))]
13848   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13849    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13850   "@
13851    ror{b}\t{%1, %0|%0, %1}
13852    ror{b}\t{%b1, %0|%0, %b1}"
13853   [(set_attr "type" "rotate1")
13854    (set_attr "mode" "QI")])
13855 \f
13856 ;; Bit set / bit test instructions
13857
13858 (define_expand "extv"
13859   [(set (match_operand:SI 0 "register_operand" "")
13860         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13861                          (match_operand:SI 2 "const8_operand" "")
13862                          (match_operand:SI 3 "const8_operand" "")))]
13863   ""
13864 {
13865   /* Handle extractions from %ah et al.  */
13866   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13867     FAIL;
13868
13869   /* From mips.md: extract_bit_field doesn't verify that our source
13870      matches the predicate, so check it again here.  */
13871   if (! ext_register_operand (operands[1], VOIDmode))
13872     FAIL;
13873 })
13874
13875 (define_expand "extzv"
13876   [(set (match_operand:SI 0 "register_operand" "")
13877         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13878                          (match_operand:SI 2 "const8_operand" "")
13879                          (match_operand:SI 3 "const8_operand" "")))]
13880   ""
13881 {
13882   /* Handle extractions from %ah et al.  */
13883   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13884     FAIL;
13885
13886   /* From mips.md: extract_bit_field doesn't verify that our source
13887      matches the predicate, so check it again here.  */
13888   if (! ext_register_operand (operands[1], VOIDmode))
13889     FAIL;
13890 })
13891
13892 (define_expand "insv"
13893   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13894                       (match_operand 1 "const8_operand" "")
13895                       (match_operand 2 "const8_operand" ""))
13896         (match_operand 3 "register_operand" ""))]
13897   ""
13898 {
13899   /* Handle insertions to %ah et al.  */
13900   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13901     FAIL;
13902
13903   /* From mips.md: insert_bit_field doesn't verify that our source
13904      matches the predicate, so check it again here.  */
13905   if (! ext_register_operand (operands[0], VOIDmode))
13906     FAIL;
13907
13908   if (TARGET_64BIT)
13909     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13910   else
13911     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13912
13913   DONE;
13914 })
13915
13916 ;; %%% bts, btr, btc, bt.
13917 ;; In general these instructions are *slow* when applied to memory,
13918 ;; since they enforce atomic operation.  When applied to registers,
13919 ;; it depends on the cpu implementation.  They're never faster than
13920 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13921 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13922 ;; within the instruction itself, so operating on bits in the high
13923 ;; 32-bits of a register becomes easier.
13924 ;;
13925 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13926 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13927 ;; negdf respectively, so they can never be disabled entirely.
13928
13929 (define_insn "*btsq"
13930   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13931                          (const_int 1)
13932                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13933         (const_int 1))
13934    (clobber (reg:CC FLAGS_REG))]
13935   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13936   "bts{q}\t{%1, %0|%0, %1}"
13937   [(set_attr "type" "alu1")])
13938
13939 (define_insn "*btrq"
13940   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13941                          (const_int 1)
13942                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13943         (const_int 0))
13944    (clobber (reg:CC FLAGS_REG))]
13945   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13946   "btr{q}\t{%1, %0|%0, %1}"
13947   [(set_attr "type" "alu1")])
13948
13949 (define_insn "*btcq"
13950   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13951                          (const_int 1)
13952                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13953         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13954    (clobber (reg:CC FLAGS_REG))]
13955   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13956   "btc{q}\t{%1, %0|%0, %1}"
13957   [(set_attr "type" "alu1")])
13958
13959 ;; Allow Nocona to avoid these instructions if a register is available.
13960
13961 (define_peephole2
13962   [(match_scratch:DI 2 "r")
13963    (parallel [(set (zero_extract:DI
13964                      (match_operand:DI 0 "register_operand" "")
13965                      (const_int 1)
13966                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13967                    (const_int 1))
13968               (clobber (reg:CC FLAGS_REG))])]
13969   "TARGET_64BIT && !TARGET_USE_BT"
13970   [(const_int 0)]
13971 {
13972   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13973   rtx op1;
13974
13975   if (HOST_BITS_PER_WIDE_INT >= 64)
13976     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13977   else if (i < HOST_BITS_PER_WIDE_INT)
13978     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13979   else
13980     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13981
13982   op1 = immed_double_const (lo, hi, DImode);
13983   if (i >= 31)
13984     {
13985       emit_move_insn (operands[2], op1);
13986       op1 = operands[2];
13987     }
13988
13989   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13990   DONE;
13991 })
13992
13993 (define_peephole2
13994   [(match_scratch:DI 2 "r")
13995    (parallel [(set (zero_extract:DI
13996                      (match_operand:DI 0 "register_operand" "")
13997                      (const_int 1)
13998                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13999                    (const_int 0))
14000               (clobber (reg:CC FLAGS_REG))])]
14001   "TARGET_64BIT && !TARGET_USE_BT"
14002   [(const_int 0)]
14003 {
14004   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14005   rtx op1;
14006
14007   if (HOST_BITS_PER_WIDE_INT >= 64)
14008     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14009   else if (i < HOST_BITS_PER_WIDE_INT)
14010     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14011   else
14012     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14013
14014   op1 = immed_double_const (~lo, ~hi, DImode);
14015   if (i >= 32)
14016     {
14017       emit_move_insn (operands[2], op1);
14018       op1 = operands[2];
14019     }
14020
14021   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14022   DONE;
14023 })
14024
14025 (define_peephole2
14026   [(match_scratch:DI 2 "r")
14027    (parallel [(set (zero_extract:DI
14028                      (match_operand:DI 0 "register_operand" "")
14029                      (const_int 1)
14030                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14031               (not:DI (zero_extract:DI
14032                         (match_dup 0) (const_int 1) (match_dup 1))))
14033               (clobber (reg:CC FLAGS_REG))])]
14034   "TARGET_64BIT && !TARGET_USE_BT"
14035   [(const_int 0)]
14036 {
14037   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14038   rtx op1;
14039
14040   if (HOST_BITS_PER_WIDE_INT >= 64)
14041     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14042   else if (i < HOST_BITS_PER_WIDE_INT)
14043     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14044   else
14045     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14046
14047   op1 = immed_double_const (lo, hi, DImode);
14048   if (i >= 31)
14049     {
14050       emit_move_insn (operands[2], op1);
14051       op1 = operands[2];
14052     }
14053
14054   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14055   DONE;
14056 })
14057
14058 (define_insn "*btdi_rex64"
14059   [(set (reg:CCC FLAGS_REG)
14060         (compare:CCC
14061           (zero_extract:DI
14062             (match_operand:DI 0 "register_operand" "r")
14063             (const_int 1)
14064             (match_operand:DI 1 "nonmemory_operand" "rN"))
14065           (const_int 0)))]
14066   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14067   "bt{q}\t{%1, %0|%0, %1}"
14068   [(set_attr "type" "alu1")])
14069
14070 (define_insn "*btsi"
14071   [(set (reg:CCC FLAGS_REG)
14072         (compare:CCC
14073           (zero_extract:SI
14074             (match_operand:SI 0 "register_operand" "r")
14075             (const_int 1)
14076             (match_operand:SI 1 "nonmemory_operand" "rN"))
14077           (const_int 0)))]
14078   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14079   "bt{l}\t{%1, %0|%0, %1}"
14080   [(set_attr "type" "alu1")])
14081 \f
14082 ;; Store-flag instructions.
14083
14084 ;; For all sCOND expanders, also expand the compare or test insn that
14085 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14086
14087 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14088 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14089 ;; way, which can later delete the movzx if only QImode is needed.
14090
14091 (define_expand "s<code>"
14092   [(set (match_operand:QI 0 "register_operand" "")
14093         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14094   ""
14095   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14096
14097 (define_expand "s<code>"
14098   [(set (match_operand:QI 0 "register_operand" "")
14099         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14100   "TARGET_80387 || TARGET_SSE"
14101   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14102
14103 (define_insn "*setcc_1"
14104   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14105         (match_operator:QI 1 "ix86_comparison_operator"
14106           [(reg FLAGS_REG) (const_int 0)]))]
14107   ""
14108   "set%C1\t%0"
14109   [(set_attr "type" "setcc")
14110    (set_attr "mode" "QI")])
14111
14112 (define_insn "*setcc_2"
14113   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14114         (match_operator:QI 1 "ix86_comparison_operator"
14115           [(reg FLAGS_REG) (const_int 0)]))]
14116   ""
14117   "set%C1\t%0"
14118   [(set_attr "type" "setcc")
14119    (set_attr "mode" "QI")])
14120
14121 ;; In general it is not safe to assume too much about CCmode registers,
14122 ;; so simplify-rtx stops when it sees a second one.  Under certain
14123 ;; conditions this is safe on x86, so help combine not create
14124 ;;
14125 ;;      seta    %al
14126 ;;      testb   %al, %al
14127 ;;      sete    %al
14128
14129 (define_split
14130   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14131         (ne:QI (match_operator 1 "ix86_comparison_operator"
14132                  [(reg FLAGS_REG) (const_int 0)])
14133             (const_int 0)))]
14134   ""
14135   [(set (match_dup 0) (match_dup 1))]
14136 {
14137   PUT_MODE (operands[1], QImode);
14138 })
14139
14140 (define_split
14141   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14142         (ne:QI (match_operator 1 "ix86_comparison_operator"
14143                  [(reg FLAGS_REG) (const_int 0)])
14144             (const_int 0)))]
14145   ""
14146   [(set (match_dup 0) (match_dup 1))]
14147 {
14148   PUT_MODE (operands[1], QImode);
14149 })
14150
14151 (define_split
14152   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14153         (eq:QI (match_operator 1 "ix86_comparison_operator"
14154                  [(reg FLAGS_REG) (const_int 0)])
14155             (const_int 0)))]
14156   ""
14157   [(set (match_dup 0) (match_dup 1))]
14158 {
14159   rtx new_op1 = copy_rtx (operands[1]);
14160   operands[1] = new_op1;
14161   PUT_MODE (new_op1, QImode);
14162   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14163                                              GET_MODE (XEXP (new_op1, 0))));
14164
14165   /* Make sure that (a) the CCmode we have for the flags is strong
14166      enough for the reversed compare or (b) we have a valid FP compare.  */
14167   if (! ix86_comparison_operator (new_op1, VOIDmode))
14168     FAIL;
14169 })
14170
14171 (define_split
14172   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14173         (eq: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   rtx new_op1 = copy_rtx (operands[1]);
14180   operands[1] = new_op1;
14181   PUT_MODE (new_op1, QImode);
14182   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14183                                              GET_MODE (XEXP (new_op1, 0))));
14184
14185   /* Make sure that (a) the CCmode we have for the flags is strong
14186      enough for the reversed compare or (b) we have a valid FP compare.  */
14187   if (! ix86_comparison_operator (new_op1, VOIDmode))
14188     FAIL;
14189 })
14190
14191 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14192 ;; subsequent logical operations are used to imitate conditional moves.
14193 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14194 ;; it directly.
14195
14196 (define_insn "*avx_setcc<mode>"
14197   [(set (match_operand:MODEF 0 "register_operand" "=x")
14198         (match_operator:MODEF 1 "avx_comparison_float_operator"
14199           [(match_operand:MODEF 2 "register_operand" "x")
14200            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14201   "TARGET_AVX"
14202   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14203   [(set_attr "type" "ssecmp")
14204    (set_attr "prefix" "vex")
14205    (set_attr "mode" "<MODE>")])
14206
14207 (define_insn "*sse_setcc<mode>"
14208   [(set (match_operand:MODEF 0 "register_operand" "=x")
14209         (match_operator:MODEF 1 "sse_comparison_operator"
14210           [(match_operand:MODEF 2 "register_operand" "0")
14211            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14212   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14213   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14214   [(set_attr "type" "ssecmp")
14215    (set_attr "mode" "<MODE>")])
14216
14217 (define_insn "*sse5_setcc<mode>"
14218   [(set (match_operand:MODEF 0 "register_operand" "=x")
14219         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14220           [(match_operand:MODEF 2 "register_operand" "x")
14221            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14222   "TARGET_SSE5"
14223   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14224   [(set_attr "type" "sse4arg")
14225    (set_attr "mode" "<MODE>")])
14226
14227 \f
14228 ;; Basic conditional jump instructions.
14229 ;; We ignore the overflow flag for signed branch instructions.
14230
14231 ;; For all bCOND expanders, also expand the compare or test insn that
14232 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14233
14234 (define_expand "b<code>"
14235   [(set (pc)
14236         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14237                                    (const_int 0))
14238                       (label_ref (match_operand 0 ""))
14239                       (pc)))]
14240   ""
14241   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14242
14243 (define_expand "b<code>"
14244   [(set (pc)
14245         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14246                                   (const_int 0))
14247                       (label_ref (match_operand 0 ""))
14248                       (pc)))]
14249   "TARGET_80387 || TARGET_SSE_MATH"
14250   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14251
14252 (define_insn "*jcc_1"
14253   [(set (pc)
14254         (if_then_else (match_operator 1 "ix86_comparison_operator"
14255                                       [(reg FLAGS_REG) (const_int 0)])
14256                       (label_ref (match_operand 0 "" ""))
14257                       (pc)))]
14258   ""
14259   "%+j%C1\t%l0"
14260   [(set_attr "type" "ibr")
14261    (set_attr "modrm" "0")
14262    (set (attr "length")
14263            (if_then_else (and (ge (minus (match_dup 0) (pc))
14264                                   (const_int -126))
14265                               (lt (minus (match_dup 0) (pc))
14266                                   (const_int 128)))
14267              (const_int 2)
14268              (const_int 6)))])
14269
14270 (define_insn "*jcc_2"
14271   [(set (pc)
14272         (if_then_else (match_operator 1 "ix86_comparison_operator"
14273                                       [(reg FLAGS_REG) (const_int 0)])
14274                       (pc)
14275                       (label_ref (match_operand 0 "" ""))))]
14276   ""
14277   "%+j%c1\t%l0"
14278   [(set_attr "type" "ibr")
14279    (set_attr "modrm" "0")
14280    (set (attr "length")
14281            (if_then_else (and (ge (minus (match_dup 0) (pc))
14282                                   (const_int -126))
14283                               (lt (minus (match_dup 0) (pc))
14284                                   (const_int 128)))
14285              (const_int 2)
14286              (const_int 6)))])
14287
14288 ;; In general it is not safe to assume too much about CCmode registers,
14289 ;; so simplify-rtx stops when it sees a second one.  Under certain
14290 ;; conditions this is safe on x86, so help combine not create
14291 ;;
14292 ;;      seta    %al
14293 ;;      testb   %al, %al
14294 ;;      je      Lfoo
14295
14296 (define_split
14297   [(set (pc)
14298         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14299                                       [(reg FLAGS_REG) (const_int 0)])
14300                           (const_int 0))
14301                       (label_ref (match_operand 1 "" ""))
14302                       (pc)))]
14303   ""
14304   [(set (pc)
14305         (if_then_else (match_dup 0)
14306                       (label_ref (match_dup 1))
14307                       (pc)))]
14308 {
14309   PUT_MODE (operands[0], VOIDmode);
14310 })
14311
14312 (define_split
14313   [(set (pc)
14314         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14315                                       [(reg FLAGS_REG) (const_int 0)])
14316                           (const_int 0))
14317                       (label_ref (match_operand 1 "" ""))
14318                       (pc)))]
14319   ""
14320   [(set (pc)
14321         (if_then_else (match_dup 0)
14322                       (label_ref (match_dup 1))
14323                       (pc)))]
14324 {
14325   rtx new_op0 = copy_rtx (operands[0]);
14326   operands[0] = new_op0;
14327   PUT_MODE (new_op0, VOIDmode);
14328   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14329                                              GET_MODE (XEXP (new_op0, 0))));
14330
14331   /* Make sure that (a) the CCmode we have for the flags is strong
14332      enough for the reversed compare or (b) we have a valid FP compare.  */
14333   if (! ix86_comparison_operator (new_op0, VOIDmode))
14334     FAIL;
14335 })
14336
14337 ;; zero_extend in SImode is correct, since this is what combine pass
14338 ;; generates from shift insn with QImode operand.  Actually, the mode of
14339 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14340 ;; appropriate modulo of the bit offset value.
14341
14342 (define_insn_and_split "*jcc_btdi_rex64"
14343   [(set (pc)
14344         (if_then_else (match_operator 0 "bt_comparison_operator"
14345                         [(zero_extract:DI
14346                            (match_operand:DI 1 "register_operand" "r")
14347                            (const_int 1)
14348                            (zero_extend:SI
14349                              (match_operand:QI 2 "register_operand" "r")))
14350                          (const_int 0)])
14351                       (label_ref (match_operand 3 "" ""))
14352                       (pc)))
14353    (clobber (reg:CC FLAGS_REG))]
14354   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14355   "#"
14356   "&& 1"
14357   [(set (reg:CCC FLAGS_REG)
14358         (compare:CCC
14359           (zero_extract:DI
14360             (match_dup 1)
14361             (const_int 1)
14362             (match_dup 2))
14363           (const_int 0)))
14364    (set (pc)
14365         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14366                       (label_ref (match_dup 3))
14367                       (pc)))]
14368 {
14369   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14370
14371   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14372 })
14373
14374 ;; avoid useless masking of bit offset operand
14375 (define_insn_and_split "*jcc_btdi_mask_rex64"
14376   [(set (pc)
14377         (if_then_else (match_operator 0 "bt_comparison_operator"
14378                         [(zero_extract:DI
14379                            (match_operand:DI 1 "register_operand" "r")
14380                            (const_int 1)
14381                            (and:SI
14382                              (match_operand:SI 2 "register_operand" "r")
14383                              (match_operand:SI 3 "const_int_operand" "n")))])
14384                       (label_ref (match_operand 4 "" ""))
14385                       (pc)))
14386    (clobber (reg:CC FLAGS_REG))]
14387   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14388    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14389   "#"
14390   "&& 1"
14391   [(set (reg:CCC FLAGS_REG)
14392         (compare:CCC
14393           (zero_extract:DI
14394             (match_dup 1)
14395             (const_int 1)
14396             (match_dup 2))
14397           (const_int 0)))
14398    (set (pc)
14399         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14400                       (label_ref (match_dup 4))
14401                       (pc)))]
14402 {
14403   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14404
14405   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14406 })
14407
14408 (define_insn_and_split "*jcc_btsi"
14409   [(set (pc)
14410         (if_then_else (match_operator 0 "bt_comparison_operator"
14411                         [(zero_extract:SI
14412                            (match_operand:SI 1 "register_operand" "r")
14413                            (const_int 1)
14414                            (zero_extend:SI
14415                              (match_operand:QI 2 "register_operand" "r")))
14416                          (const_int 0)])
14417                       (label_ref (match_operand 3 "" ""))
14418                       (pc)))
14419    (clobber (reg:CC FLAGS_REG))]
14420   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14421   "#"
14422   "&& 1"
14423   [(set (reg:CCC FLAGS_REG)
14424         (compare:CCC
14425           (zero_extract:SI
14426             (match_dup 1)
14427             (const_int 1)
14428             (match_dup 2))
14429           (const_int 0)))
14430    (set (pc)
14431         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14432                       (label_ref (match_dup 3))
14433                       (pc)))]
14434 {
14435   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14436
14437   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14438 })
14439
14440 ;; avoid useless masking of bit offset operand
14441 (define_insn_and_split "*jcc_btsi_mask"
14442   [(set (pc)
14443         (if_then_else (match_operator 0 "bt_comparison_operator"
14444                         [(zero_extract:SI
14445                            (match_operand:SI 1 "register_operand" "r")
14446                            (const_int 1)
14447                            (and:SI
14448                              (match_operand:SI 2 "register_operand" "r")
14449                              (match_operand:SI 3 "const_int_operand" "n")))])
14450                       (label_ref (match_operand 4 "" ""))
14451                       (pc)))
14452    (clobber (reg:CC FLAGS_REG))]
14453   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14454    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14455   "#"
14456   "&& 1"
14457   [(set (reg:CCC FLAGS_REG)
14458         (compare:CCC
14459           (zero_extract:SI
14460             (match_dup 1)
14461             (const_int 1)
14462             (match_dup 2))
14463           (const_int 0)))
14464    (set (pc)
14465         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14466                       (label_ref (match_dup 4))
14467                       (pc)))]
14468   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14469
14470 (define_insn_and_split "*jcc_btsi_1"
14471   [(set (pc)
14472         (if_then_else (match_operator 0 "bt_comparison_operator"
14473                         [(and:SI
14474                            (lshiftrt:SI
14475                              (match_operand:SI 1 "register_operand" "r")
14476                              (match_operand:QI 2 "register_operand" "r"))
14477                            (const_int 1))
14478                          (const_int 0)])
14479                       (label_ref (match_operand 3 "" ""))
14480                       (pc)))
14481    (clobber (reg:CC FLAGS_REG))]
14482   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14483   "#"
14484   "&& 1"
14485   [(set (reg:CCC FLAGS_REG)
14486         (compare:CCC
14487           (zero_extract:SI
14488             (match_dup 1)
14489             (const_int 1)
14490             (match_dup 2))
14491           (const_int 0)))
14492    (set (pc)
14493         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14494                       (label_ref (match_dup 3))
14495                       (pc)))]
14496 {
14497   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14498
14499   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14500 })
14501
14502 ;; avoid useless masking of bit offset operand
14503 (define_insn_and_split "*jcc_btsi_mask_1"
14504   [(set (pc)
14505         (if_then_else
14506           (match_operator 0 "bt_comparison_operator"
14507             [(and:SI
14508                (lshiftrt:SI
14509                  (match_operand:SI 1 "register_operand" "r")
14510                  (subreg:QI
14511                    (and:SI
14512                      (match_operand:SI 2 "register_operand" "r")
14513                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14514                (const_int 1))
14515              (const_int 0)])
14516           (label_ref (match_operand 4 "" ""))
14517           (pc)))
14518    (clobber (reg:CC FLAGS_REG))]
14519   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14520    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14521   "#"
14522   "&& 1"
14523   [(set (reg:CCC FLAGS_REG)
14524         (compare:CCC
14525           (zero_extract:SI
14526             (match_dup 1)
14527             (const_int 1)
14528             (match_dup 2))
14529           (const_int 0)))
14530    (set (pc)
14531         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14532                       (label_ref (match_dup 4))
14533                       (pc)))]
14534   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14535
14536 ;; Define combination compare-and-branch fp compare instructions to use
14537 ;; during early optimization.  Splitting the operation apart early makes
14538 ;; for bad code when we want to reverse the operation.
14539
14540 (define_insn "*fp_jcc_1_mixed"
14541   [(set (pc)
14542         (if_then_else (match_operator 0 "comparison_operator"
14543                         [(match_operand 1 "register_operand" "f,x")
14544                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14545           (label_ref (match_operand 3 "" ""))
14546           (pc)))
14547    (clobber (reg:CCFP FPSR_REG))
14548    (clobber (reg:CCFP FLAGS_REG))]
14549   "TARGET_MIX_SSE_I387
14550    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14551    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14552    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14553   "#")
14554
14555 (define_insn "*fp_jcc_1_sse"
14556   [(set (pc)
14557         (if_then_else (match_operator 0 "comparison_operator"
14558                         [(match_operand 1 "register_operand" "x")
14559                          (match_operand 2 "nonimmediate_operand" "xm")])
14560           (label_ref (match_operand 3 "" ""))
14561           (pc)))
14562    (clobber (reg:CCFP FPSR_REG))
14563    (clobber (reg:CCFP FLAGS_REG))]
14564   "TARGET_SSE_MATH
14565    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14566    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14567    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14568   "#")
14569
14570 (define_insn "*fp_jcc_1_387"
14571   [(set (pc)
14572         (if_then_else (match_operator 0 "comparison_operator"
14573                         [(match_operand 1 "register_operand" "f")
14574                          (match_operand 2 "register_operand" "f")])
14575           (label_ref (match_operand 3 "" ""))
14576           (pc)))
14577    (clobber (reg:CCFP FPSR_REG))
14578    (clobber (reg:CCFP FLAGS_REG))]
14579   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14580    && TARGET_CMOVE
14581    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14582    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14583   "#")
14584
14585 (define_insn "*fp_jcc_2_mixed"
14586   [(set (pc)
14587         (if_then_else (match_operator 0 "comparison_operator"
14588                         [(match_operand 1 "register_operand" "f,x")
14589                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14590           (pc)
14591           (label_ref (match_operand 3 "" ""))))
14592    (clobber (reg:CCFP FPSR_REG))
14593    (clobber (reg:CCFP FLAGS_REG))]
14594   "TARGET_MIX_SSE_I387
14595    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14596    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14597    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14598   "#")
14599
14600 (define_insn "*fp_jcc_2_sse"
14601   [(set (pc)
14602         (if_then_else (match_operator 0 "comparison_operator"
14603                         [(match_operand 1 "register_operand" "x")
14604                          (match_operand 2 "nonimmediate_operand" "xm")])
14605           (pc)
14606           (label_ref (match_operand 3 "" ""))))
14607    (clobber (reg:CCFP FPSR_REG))
14608    (clobber (reg:CCFP FLAGS_REG))]
14609   "TARGET_SSE_MATH
14610    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14611    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14612    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14613   "#")
14614
14615 (define_insn "*fp_jcc_2_387"
14616   [(set (pc)
14617         (if_then_else (match_operator 0 "comparison_operator"
14618                         [(match_operand 1 "register_operand" "f")
14619                          (match_operand 2 "register_operand" "f")])
14620           (pc)
14621           (label_ref (match_operand 3 "" ""))))
14622    (clobber (reg:CCFP FPSR_REG))
14623    (clobber (reg:CCFP FLAGS_REG))]
14624   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14625    && TARGET_CMOVE
14626    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14627    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14628   "#")
14629
14630 (define_insn "*fp_jcc_3_387"
14631   [(set (pc)
14632         (if_then_else (match_operator 0 "comparison_operator"
14633                         [(match_operand 1 "register_operand" "f")
14634                          (match_operand 2 "nonimmediate_operand" "fm")])
14635           (label_ref (match_operand 3 "" ""))
14636           (pc)))
14637    (clobber (reg:CCFP FPSR_REG))
14638    (clobber (reg:CCFP FLAGS_REG))
14639    (clobber (match_scratch:HI 4 "=a"))]
14640   "TARGET_80387
14641    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14642    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14643    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14644    && SELECT_CC_MODE (GET_CODE (operands[0]),
14645                       operands[1], operands[2]) == CCFPmode
14646    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14647   "#")
14648
14649 (define_insn "*fp_jcc_4_387"
14650   [(set (pc)
14651         (if_then_else (match_operator 0 "comparison_operator"
14652                         [(match_operand 1 "register_operand" "f")
14653                          (match_operand 2 "nonimmediate_operand" "fm")])
14654           (pc)
14655           (label_ref (match_operand 3 "" ""))))
14656    (clobber (reg:CCFP FPSR_REG))
14657    (clobber (reg:CCFP FLAGS_REG))
14658    (clobber (match_scratch:HI 4 "=a"))]
14659   "TARGET_80387
14660    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14661    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14662    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14663    && SELECT_CC_MODE (GET_CODE (operands[0]),
14664                       operands[1], operands[2]) == CCFPmode
14665    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14666   "#")
14667
14668 (define_insn "*fp_jcc_5_387"
14669   [(set (pc)
14670         (if_then_else (match_operator 0 "comparison_operator"
14671                         [(match_operand 1 "register_operand" "f")
14672                          (match_operand 2 "register_operand" "f")])
14673           (label_ref (match_operand 3 "" ""))
14674           (pc)))
14675    (clobber (reg:CCFP FPSR_REG))
14676    (clobber (reg:CCFP FLAGS_REG))
14677    (clobber (match_scratch:HI 4 "=a"))]
14678   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14679    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14680    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14681   "#")
14682
14683 (define_insn "*fp_jcc_6_387"
14684   [(set (pc)
14685         (if_then_else (match_operator 0 "comparison_operator"
14686                         [(match_operand 1 "register_operand" "f")
14687                          (match_operand 2 "register_operand" "f")])
14688           (pc)
14689           (label_ref (match_operand 3 "" ""))))
14690    (clobber (reg:CCFP FPSR_REG))
14691    (clobber (reg:CCFP FLAGS_REG))
14692    (clobber (match_scratch:HI 4 "=a"))]
14693   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14694    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14695    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14696   "#")
14697
14698 (define_insn "*fp_jcc_7_387"
14699   [(set (pc)
14700         (if_then_else (match_operator 0 "comparison_operator"
14701                         [(match_operand 1 "register_operand" "f")
14702                          (match_operand 2 "const0_operand" "")])
14703           (label_ref (match_operand 3 "" ""))
14704           (pc)))
14705    (clobber (reg:CCFP FPSR_REG))
14706    (clobber (reg:CCFP FLAGS_REG))
14707    (clobber (match_scratch:HI 4 "=a"))]
14708   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14709    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14710    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14711    && SELECT_CC_MODE (GET_CODE (operands[0]),
14712                       operands[1], operands[2]) == CCFPmode
14713    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14714   "#")
14715
14716 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14717 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14718 ;; with a precedence over other operators and is always put in the first
14719 ;; place. Swap condition and operands to match ficom instruction.
14720
14721 (define_insn "*fp_jcc_8<mode>_387"
14722   [(set (pc)
14723         (if_then_else (match_operator 0 "comparison_operator"
14724                         [(match_operator 1 "float_operator"
14725                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14726                            (match_operand 3 "register_operand" "f,f")])
14727           (label_ref (match_operand 4 "" ""))
14728           (pc)))
14729    (clobber (reg:CCFP FPSR_REG))
14730    (clobber (reg:CCFP FLAGS_REG))
14731    (clobber (match_scratch:HI 5 "=a,a"))]
14732   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14733    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14734    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14735    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14736    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14737    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14738   "#")
14739
14740 (define_split
14741   [(set (pc)
14742         (if_then_else (match_operator 0 "comparison_operator"
14743                         [(match_operand 1 "register_operand" "")
14744                          (match_operand 2 "nonimmediate_operand" "")])
14745           (match_operand 3 "" "")
14746           (match_operand 4 "" "")))
14747    (clobber (reg:CCFP FPSR_REG))
14748    (clobber (reg:CCFP FLAGS_REG))]
14749   "reload_completed"
14750   [(const_int 0)]
14751 {
14752   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14753                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14754   DONE;
14755 })
14756
14757 (define_split
14758   [(set (pc)
14759         (if_then_else (match_operator 0 "comparison_operator"
14760                         [(match_operand 1 "register_operand" "")
14761                          (match_operand 2 "general_operand" "")])
14762           (match_operand 3 "" "")
14763           (match_operand 4 "" "")))
14764    (clobber (reg:CCFP FPSR_REG))
14765    (clobber (reg:CCFP FLAGS_REG))
14766    (clobber (match_scratch:HI 5 "=a"))]
14767   "reload_completed"
14768   [(const_int 0)]
14769 {
14770   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14771                         operands[3], operands[4], operands[5], NULL_RTX);
14772   DONE;
14773 })
14774
14775 (define_split
14776   [(set (pc)
14777         (if_then_else (match_operator 0 "comparison_operator"
14778                         [(match_operator 1 "float_operator"
14779                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14780                            (match_operand 3 "register_operand" "")])
14781           (match_operand 4 "" "")
14782           (match_operand 5 "" "")))
14783    (clobber (reg:CCFP FPSR_REG))
14784    (clobber (reg:CCFP FLAGS_REG))
14785    (clobber (match_scratch:HI 6 "=a"))]
14786   "reload_completed"
14787   [(const_int 0)]
14788 {
14789   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14790   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14791                         operands[3], operands[7],
14792                         operands[4], operands[5], operands[6], NULL_RTX);
14793   DONE;
14794 })
14795
14796 ;; %%% Kill this when reload knows how to do it.
14797 (define_split
14798   [(set (pc)
14799         (if_then_else (match_operator 0 "comparison_operator"
14800                         [(match_operator 1 "float_operator"
14801                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14802                            (match_operand 3 "register_operand" "")])
14803           (match_operand 4 "" "")
14804           (match_operand 5 "" "")))
14805    (clobber (reg:CCFP FPSR_REG))
14806    (clobber (reg:CCFP FLAGS_REG))
14807    (clobber (match_scratch:HI 6 "=a"))]
14808   "reload_completed"
14809   [(const_int 0)]
14810 {
14811   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14812   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14813   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14814                         operands[3], operands[7],
14815                         operands[4], operands[5], operands[6], operands[2]);
14816   DONE;
14817 })
14818 \f
14819 ;; Unconditional and other jump instructions
14820
14821 (define_insn "jump"
14822   [(set (pc)
14823         (label_ref (match_operand 0 "" "")))]
14824   ""
14825   "jmp\t%l0"
14826   [(set_attr "type" "ibr")
14827    (set (attr "length")
14828            (if_then_else (and (ge (minus (match_dup 0) (pc))
14829                                   (const_int -126))
14830                               (lt (minus (match_dup 0) (pc))
14831                                   (const_int 128)))
14832              (const_int 2)
14833              (const_int 5)))
14834    (set_attr "modrm" "0")])
14835
14836 (define_expand "indirect_jump"
14837   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14838   ""
14839   "")
14840
14841 (define_insn "*indirect_jump"
14842   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14843   ""
14844   "jmp\t%A0"
14845   [(set_attr "type" "ibr")
14846    (set_attr "length_immediate" "0")])
14847
14848 (define_expand "tablejump"
14849   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14850               (use (label_ref (match_operand 1 "" "")))])]
14851   ""
14852 {
14853   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14854      relative.  Convert the relative address to an absolute address.  */
14855   if (flag_pic)
14856     {
14857       rtx op0, op1;
14858       enum rtx_code code;
14859
14860       /* We can't use @GOTOFF for text labels on VxWorks;
14861          see gotoff_operand.  */
14862       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14863         {
14864           code = PLUS;
14865           op0 = operands[0];
14866           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14867         }
14868       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14869         {
14870           code = PLUS;
14871           op0 = operands[0];
14872           op1 = pic_offset_table_rtx;
14873         }
14874       else
14875         {
14876           code = MINUS;
14877           op0 = pic_offset_table_rtx;
14878           op1 = operands[0];
14879         }
14880
14881       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14882                                          OPTAB_DIRECT);
14883     }
14884 })
14885
14886 (define_insn "*tablejump_1"
14887   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14888    (use (label_ref (match_operand 1 "" "")))]
14889   ""
14890   "jmp\t%A0"
14891   [(set_attr "type" "ibr")
14892    (set_attr "length_immediate" "0")])
14893 \f
14894 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14895
14896 (define_peephole2
14897   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14898    (set (match_operand:QI 1 "register_operand" "")
14899         (match_operator:QI 2 "ix86_comparison_operator"
14900           [(reg FLAGS_REG) (const_int 0)]))
14901    (set (match_operand 3 "q_regs_operand" "")
14902         (zero_extend (match_dup 1)))]
14903   "(peep2_reg_dead_p (3, operands[1])
14904     || operands_match_p (operands[1], operands[3]))
14905    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14906   [(set (match_dup 4) (match_dup 0))
14907    (set (strict_low_part (match_dup 5))
14908         (match_dup 2))]
14909 {
14910   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14911   operands[5] = gen_lowpart (QImode, operands[3]);
14912   ix86_expand_clear (operands[3]);
14913 })
14914
14915 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14916
14917 (define_peephole2
14918   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14919    (set (match_operand:QI 1 "register_operand" "")
14920         (match_operator:QI 2 "ix86_comparison_operator"
14921           [(reg FLAGS_REG) (const_int 0)]))
14922    (parallel [(set (match_operand 3 "q_regs_operand" "")
14923                    (zero_extend (match_dup 1)))
14924               (clobber (reg:CC FLAGS_REG))])]
14925   "(peep2_reg_dead_p (3, operands[1])
14926     || operands_match_p (operands[1], operands[3]))
14927    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14928   [(set (match_dup 4) (match_dup 0))
14929    (set (strict_low_part (match_dup 5))
14930         (match_dup 2))]
14931 {
14932   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14933   operands[5] = gen_lowpart (QImode, operands[3]);
14934   ix86_expand_clear (operands[3]);
14935 })
14936 \f
14937 ;; Call instructions.
14938
14939 ;; The predicates normally associated with named expanders are not properly
14940 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14941 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14942
14943 ;; Call subroutine returning no value.
14944
14945 (define_expand "call_pop"
14946   [(parallel [(call (match_operand:QI 0 "" "")
14947                     (match_operand:SI 1 "" ""))
14948               (set (reg:SI SP_REG)
14949                    (plus:SI (reg:SI SP_REG)
14950                             (match_operand:SI 3 "" "")))])]
14951   "!TARGET_64BIT"
14952 {
14953   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14954   DONE;
14955 })
14956
14957 (define_insn "*call_pop_0"
14958   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14959          (match_operand:SI 1 "" ""))
14960    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14961                             (match_operand:SI 2 "immediate_operand" "")))]
14962   "!TARGET_64BIT"
14963 {
14964   if (SIBLING_CALL_P (insn))
14965     return "jmp\t%P0";
14966   else
14967     return "call\t%P0";
14968 }
14969   [(set_attr "type" "call")])
14970
14971 (define_insn "*call_pop_1"
14972   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14973          (match_operand:SI 1 "" ""))
14974    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14975                             (match_operand:SI 2 "immediate_operand" "i")))]
14976   "!TARGET_64BIT"
14977 {
14978   if (constant_call_address_operand (operands[0], Pmode))
14979     {
14980       if (SIBLING_CALL_P (insn))
14981         return "jmp\t%P0";
14982       else
14983         return "call\t%P0";
14984     }
14985   if (SIBLING_CALL_P (insn))
14986     return "jmp\t%A0";
14987   else
14988     return "call\t%A0";
14989 }
14990   [(set_attr "type" "call")])
14991
14992 (define_expand "call"
14993   [(call (match_operand:QI 0 "" "")
14994          (match_operand 1 "" ""))
14995    (use (match_operand 2 "" ""))]
14996   ""
14997 {
14998   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14999   DONE;
15000 })
15001
15002 (define_expand "sibcall"
15003   [(call (match_operand:QI 0 "" "")
15004          (match_operand 1 "" ""))
15005    (use (match_operand 2 "" ""))]
15006   ""
15007 {
15008   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15009   DONE;
15010 })
15011
15012 (define_insn "*call_0"
15013   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15014          (match_operand 1 "" ""))]
15015   ""
15016 {
15017   if (SIBLING_CALL_P (insn))
15018     return "jmp\t%P0";
15019   else
15020     return "call\t%P0";
15021 }
15022   [(set_attr "type" "call")])
15023
15024 (define_insn "*call_1"
15025   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15026          (match_operand 1 "" ""))]
15027   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15028 {
15029   if (constant_call_address_operand (operands[0], Pmode))
15030     return "call\t%P0";
15031   return "call\t%A0";
15032 }
15033   [(set_attr "type" "call")])
15034
15035 (define_insn "*sibcall_1"
15036   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
15037          (match_operand 1 "" ""))]
15038   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15039   "@
15040    jmp\t%P0
15041    jmp\t%A0"
15042   [(set_attr "type" "call")])
15043
15044 (define_insn "*call_1_rex64"
15045   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15046          (match_operand 1 "" ""))]
15047   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15048    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15049 {
15050   if (constant_call_address_operand (operands[0], Pmode))
15051     return "call\t%P0";
15052   return "call\t%A0";
15053 }
15054   [(set_attr "type" "call")])
15055
15056 (define_insn "*call_1_rex64_ms_sysv"
15057   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15058          (match_operand 1 "" ""))
15059    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15060    (clobber (reg:TI XMM6_REG))
15061    (clobber (reg:TI XMM7_REG))
15062    (clobber (reg:TI XMM8_REG))
15063    (clobber (reg:TI XMM9_REG))
15064    (clobber (reg:TI XMM10_REG))
15065    (clobber (reg:TI XMM11_REG))
15066    (clobber (reg:TI XMM12_REG))
15067    (clobber (reg:TI XMM13_REG))
15068    (clobber (reg:TI XMM14_REG))
15069    (clobber (reg:TI XMM15_REG))
15070    (clobber (reg:DI SI_REG))
15071    (clobber (reg:DI DI_REG))]
15072   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15073 {
15074   if (constant_call_address_operand (operands[0], Pmode))
15075     return "call\t%P0";
15076   return "call\t%A0";
15077 }
15078   [(set_attr "type" "call")])
15079
15080 (define_insn "*call_1_rex64_large"
15081   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15082          (match_operand 1 "" ""))]
15083   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15084   "call\t%A0"
15085   [(set_attr "type" "call")])
15086
15087 (define_insn "*sibcall_1_rex64"
15088   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
15089          (match_operand 1 "" ""))]
15090   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15091   "@
15092    jmp\t%P0
15093    jmp\t%A0"
15094   [(set_attr "type" "call")])
15095
15096 ;; Call subroutine, returning value in operand 0
15097 (define_expand "call_value_pop"
15098   [(parallel [(set (match_operand 0 "" "")
15099                    (call (match_operand:QI 1 "" "")
15100                          (match_operand:SI 2 "" "")))
15101               (set (reg:SI SP_REG)
15102                    (plus:SI (reg:SI SP_REG)
15103                             (match_operand:SI 4 "" "")))])]
15104   "!TARGET_64BIT"
15105 {
15106   ix86_expand_call (operands[0], operands[1], operands[2],
15107                     operands[3], operands[4], 0);
15108   DONE;
15109 })
15110
15111 (define_expand "call_value"
15112   [(set (match_operand 0 "" "")
15113         (call (match_operand:QI 1 "" "")
15114               (match_operand:SI 2 "" "")))
15115    (use (match_operand:SI 3 "" ""))]
15116   ;; Operand 2 not used on the i386.
15117   ""
15118 {
15119   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15120   DONE;
15121 })
15122
15123 (define_expand "sibcall_value"
15124   [(set (match_operand 0 "" "")
15125         (call (match_operand:QI 1 "" "")
15126               (match_operand:SI 2 "" "")))
15127    (use (match_operand:SI 3 "" ""))]
15128   ;; Operand 2 not used on the i386.
15129   ""
15130 {
15131   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15132   DONE;
15133 })
15134
15135 ;; Call subroutine returning any type.
15136
15137 (define_expand "untyped_call"
15138   [(parallel [(call (match_operand 0 "" "")
15139                     (const_int 0))
15140               (match_operand 1 "" "")
15141               (match_operand 2 "" "")])]
15142   ""
15143 {
15144   int i;
15145
15146   /* In order to give reg-stack an easier job in validating two
15147      coprocessor registers as containing a possible return value,
15148      simply pretend the untyped call returns a complex long double
15149      value. 
15150
15151      We can't use SSE_REGPARM_MAX here since callee is unprototyped
15152      and should have the default ABI.  */
15153
15154   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15155                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15156                     operands[0], const0_rtx,
15157                     GEN_INT ((TARGET_64BIT
15158                               ? (DEFAULT_ABI == SYSV_ABI
15159                                  ? X86_64_SSE_REGPARM_MAX
15160                                  : X64_SSE_REGPARM_MAX)
15161                               : X86_32_SSE_REGPARM_MAX)
15162                              - 1),
15163                     NULL, 0);
15164
15165   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15166     {
15167       rtx set = XVECEXP (operands[2], 0, i);
15168       emit_move_insn (SET_DEST (set), SET_SRC (set));
15169     }
15170
15171   /* The optimizer does not know that the call sets the function value
15172      registers we stored in the result block.  We avoid problems by
15173      claiming that all hard registers are used and clobbered at this
15174      point.  */
15175   emit_insn (gen_blockage ());
15176
15177   DONE;
15178 })
15179 \f
15180 ;; Prologue and epilogue instructions
15181
15182 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15183 ;; all of memory.  This blocks insns from being moved across this point.
15184
15185 (define_insn "blockage"
15186   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15187   ""
15188   ""
15189   [(set_attr "length" "0")])
15190
15191 ;; Do not schedule instructions accessing memory across this point.
15192
15193 (define_expand "memory_blockage"
15194   [(set (match_dup 0)
15195         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15196   ""
15197 {
15198   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15199   MEM_VOLATILE_P (operands[0]) = 1;
15200 })
15201
15202 (define_insn "*memory_blockage"
15203   [(set (match_operand:BLK 0 "" "")
15204         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15205   ""
15206   ""
15207   [(set_attr "length" "0")])
15208
15209 ;; As USE insns aren't meaningful after reload, this is used instead
15210 ;; to prevent deleting instructions setting registers for PIC code
15211 (define_insn "prologue_use"
15212   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15213   ""
15214   ""
15215   [(set_attr "length" "0")])
15216
15217 ;; Insn emitted into the body of a function to return from a function.
15218 ;; This is only done if the function's epilogue is known to be simple.
15219 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15220
15221 (define_expand "return"
15222   [(return)]
15223   "ix86_can_use_return_insn_p ()"
15224 {
15225   if (crtl->args.pops_args)
15226     {
15227       rtx popc = GEN_INT (crtl->args.pops_args);
15228       emit_jump_insn (gen_return_pop_internal (popc));
15229       DONE;
15230     }
15231 })
15232
15233 (define_insn "return_internal"
15234   [(return)]
15235   "reload_completed"
15236   "ret"
15237   [(set_attr "length" "1")
15238    (set_attr "length_immediate" "0")
15239    (set_attr "modrm" "0")])
15240
15241 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15242 ;; instruction Athlon and K8 have.
15243
15244 (define_insn "return_internal_long"
15245   [(return)
15246    (unspec [(const_int 0)] UNSPEC_REP)]
15247   "reload_completed"
15248   "rep\;ret"
15249   [(set_attr "length" "1")
15250    (set_attr "length_immediate" "0")
15251    (set_attr "prefix_rep" "1")
15252    (set_attr "modrm" "0")])
15253
15254 (define_insn "return_pop_internal"
15255   [(return)
15256    (use (match_operand:SI 0 "const_int_operand" ""))]
15257   "reload_completed"
15258   "ret\t%0"
15259   [(set_attr "length" "3")
15260    (set_attr "length_immediate" "2")
15261    (set_attr "modrm" "0")])
15262
15263 (define_insn "return_indirect_internal"
15264   [(return)
15265    (use (match_operand:SI 0 "register_operand" "r"))]
15266   "reload_completed"
15267   "jmp\t%A0"
15268   [(set_attr "type" "ibr")
15269    (set_attr "length_immediate" "0")])
15270
15271 (define_insn "nop"
15272   [(const_int 0)]
15273   ""
15274   "nop"
15275   [(set_attr "length" "1")
15276    (set_attr "length_immediate" "0")
15277    (set_attr "modrm" "0")])
15278
15279 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15280 ;; branch prediction penalty for the third jump in a 16-byte
15281 ;; block on K8.
15282
15283 (define_insn "align"
15284   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15285   ""
15286 {
15287 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15288   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15289 #else
15290   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15291      The align insn is used to avoid 3 jump instructions in the row to improve
15292      branch prediction and the benefits hardly outweigh the cost of extra 8
15293      nops on the average inserted by full alignment pseudo operation.  */
15294 #endif
15295   return "";
15296 }
15297   [(set_attr "length" "16")])
15298
15299 (define_expand "prologue"
15300   [(const_int 0)]
15301   ""
15302   "ix86_expand_prologue (); DONE;")
15303
15304 (define_insn "set_got"
15305   [(set (match_operand:SI 0 "register_operand" "=r")
15306         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15307    (clobber (reg:CC FLAGS_REG))]
15308   "!TARGET_64BIT"
15309   { return output_set_got (operands[0], NULL_RTX); }
15310   [(set_attr "type" "multi")
15311    (set_attr "length" "12")])
15312
15313 (define_insn "set_got_labelled"
15314   [(set (match_operand:SI 0 "register_operand" "=r")
15315         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15316          UNSPEC_SET_GOT))
15317    (clobber (reg:CC FLAGS_REG))]
15318   "!TARGET_64BIT"
15319   { return output_set_got (operands[0], operands[1]); }
15320   [(set_attr "type" "multi")
15321    (set_attr "length" "12")])
15322
15323 (define_insn "set_got_rex64"
15324   [(set (match_operand:DI 0 "register_operand" "=r")
15325         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15326   "TARGET_64BIT"
15327   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15328   [(set_attr "type" "lea")
15329    (set_attr "length" "6")])
15330
15331 (define_insn "set_rip_rex64"
15332   [(set (match_operand:DI 0 "register_operand" "=r")
15333         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15334   "TARGET_64BIT"
15335   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15336   [(set_attr "type" "lea")
15337    (set_attr "length" "6")])
15338
15339 (define_insn "set_got_offset_rex64"
15340   [(set (match_operand:DI 0 "register_operand" "=r")
15341         (unspec:DI
15342           [(label_ref (match_operand 1 "" ""))]
15343           UNSPEC_SET_GOT_OFFSET))]
15344   "TARGET_64BIT"
15345   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15346   [(set_attr "type" "imov")
15347    (set_attr "length" "11")])
15348
15349 (define_expand "epilogue"
15350   [(const_int 0)]
15351   ""
15352   "ix86_expand_epilogue (1); DONE;")
15353
15354 (define_expand "sibcall_epilogue"
15355   [(const_int 0)]
15356   ""
15357   "ix86_expand_epilogue (0); DONE;")
15358
15359 (define_expand "eh_return"
15360   [(use (match_operand 0 "register_operand" ""))]
15361   ""
15362 {
15363   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15364
15365   /* Tricky bit: we write the address of the handler to which we will
15366      be returning into someone else's stack frame, one word below the
15367      stack address we wish to restore.  */
15368   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15369   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15370   tmp = gen_rtx_MEM (Pmode, tmp);
15371   emit_move_insn (tmp, ra);
15372
15373   if (Pmode == SImode)
15374     emit_jump_insn (gen_eh_return_si (sa));
15375   else
15376     emit_jump_insn (gen_eh_return_di (sa));
15377   emit_barrier ();
15378   DONE;
15379 })
15380
15381 (define_insn_and_split "eh_return_<mode>"
15382   [(set (pc)
15383         (unspec [(match_operand:P 0 "register_operand" "c")]
15384                  UNSPEC_EH_RETURN))]
15385   ""
15386   "#"
15387   "reload_completed"
15388   [(const_int 0)]
15389   "ix86_expand_epilogue (2); DONE;")
15390
15391 (define_insn "leave"
15392   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15393    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15394    (clobber (mem:BLK (scratch)))]
15395   "!TARGET_64BIT"
15396   "leave"
15397   [(set_attr "type" "leave")])
15398
15399 (define_insn "leave_rex64"
15400   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15401    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15402    (clobber (mem:BLK (scratch)))]
15403   "TARGET_64BIT"
15404   "leave"
15405   [(set_attr "type" "leave")])
15406 \f
15407 (define_expand "ffssi2"
15408   [(parallel
15409      [(set (match_operand:SI 0 "register_operand" "")
15410            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15411       (clobber (match_scratch:SI 2 ""))
15412       (clobber (reg:CC FLAGS_REG))])]
15413   ""
15414 {
15415   if (TARGET_CMOVE)
15416     {
15417       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15418       DONE;
15419     }
15420 })
15421
15422 (define_expand "ffs_cmove"
15423   [(set (match_dup 2) (const_int -1))
15424    (parallel [(set (reg:CCZ FLAGS_REG)
15425                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15426                                 (const_int 0)))
15427               (set (match_operand:SI 0 "register_operand" "")
15428                    (ctz:SI (match_dup 1)))])
15429    (set (match_dup 0) (if_then_else:SI
15430                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15431                         (match_dup 2)
15432                         (match_dup 0)))
15433    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15434               (clobber (reg:CC FLAGS_REG))])]
15435   "TARGET_CMOVE"
15436   "operands[2] = gen_reg_rtx (SImode);")
15437
15438 (define_insn_and_split "*ffs_no_cmove"
15439   [(set (match_operand:SI 0 "register_operand" "=r")
15440         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15441    (clobber (match_scratch:SI 2 "=&q"))
15442    (clobber (reg:CC FLAGS_REG))]
15443   "!TARGET_CMOVE"
15444   "#"
15445   "&& reload_completed"
15446   [(parallel [(set (reg:CCZ FLAGS_REG)
15447                    (compare:CCZ (match_dup 1) (const_int 0)))
15448               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15449    (set (strict_low_part (match_dup 3))
15450         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15451    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15452               (clobber (reg:CC FLAGS_REG))])
15453    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15454               (clobber (reg:CC FLAGS_REG))])
15455    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15456               (clobber (reg:CC FLAGS_REG))])]
15457 {
15458   operands[3] = gen_lowpart (QImode, operands[2]);
15459   ix86_expand_clear (operands[2]);
15460 })
15461
15462 (define_insn "*ffssi_1"
15463   [(set (reg:CCZ FLAGS_REG)
15464         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15465                      (const_int 0)))
15466    (set (match_operand:SI 0 "register_operand" "=r")
15467         (ctz:SI (match_dup 1)))]
15468   ""
15469   "bsf{l}\t{%1, %0|%0, %1}"
15470   [(set_attr "prefix_0f" "1")])
15471
15472 (define_expand "ffsdi2"
15473   [(set (match_dup 2) (const_int -1))
15474    (parallel [(set (reg:CCZ FLAGS_REG)
15475                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15476                                 (const_int 0)))
15477               (set (match_operand:DI 0 "register_operand" "")
15478                    (ctz:DI (match_dup 1)))])
15479    (set (match_dup 0) (if_then_else:DI
15480                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15481                         (match_dup 2)
15482                         (match_dup 0)))
15483    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15484               (clobber (reg:CC FLAGS_REG))])]
15485   "TARGET_64BIT"
15486   "operands[2] = gen_reg_rtx (DImode);")
15487
15488 (define_insn "*ffsdi_1"
15489   [(set (reg:CCZ FLAGS_REG)
15490         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15491                      (const_int 0)))
15492    (set (match_operand:DI 0 "register_operand" "=r")
15493         (ctz:DI (match_dup 1)))]
15494   "TARGET_64BIT"
15495   "bsf{q}\t{%1, %0|%0, %1}"
15496   [(set_attr "prefix_0f" "1")])
15497
15498 (define_insn "ctzsi2"
15499   [(set (match_operand:SI 0 "register_operand" "=r")
15500         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15501    (clobber (reg:CC FLAGS_REG))]
15502   ""
15503   "bsf{l}\t{%1, %0|%0, %1}"
15504   [(set_attr "prefix_0f" "1")])
15505
15506 (define_insn "ctzdi2"
15507   [(set (match_operand:DI 0 "register_operand" "=r")
15508         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15509    (clobber (reg:CC FLAGS_REG))]
15510   "TARGET_64BIT"
15511   "bsf{q}\t{%1, %0|%0, %1}"
15512   [(set_attr "prefix_0f" "1")])
15513
15514 (define_expand "clzsi2"
15515   [(parallel
15516      [(set (match_operand:SI 0 "register_operand" "")
15517            (minus:SI (const_int 31)
15518                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15519       (clobber (reg:CC FLAGS_REG))])
15520    (parallel
15521      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15522       (clobber (reg:CC FLAGS_REG))])]
15523   ""
15524 {
15525   if (TARGET_ABM)
15526     {
15527       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15528       DONE;
15529     }
15530 })
15531
15532 (define_insn "clzsi2_abm"
15533   [(set (match_operand:SI 0 "register_operand" "=r")
15534         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15535    (clobber (reg:CC FLAGS_REG))]
15536   "TARGET_ABM"
15537   "lzcnt{l}\t{%1, %0|%0, %1}"
15538   [(set_attr "prefix_rep" "1")
15539    (set_attr "type" "bitmanip")
15540    (set_attr "mode" "SI")])
15541
15542 (define_insn "*bsr"
15543   [(set (match_operand:SI 0 "register_operand" "=r")
15544         (minus:SI (const_int 31)
15545                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15546    (clobber (reg:CC FLAGS_REG))]
15547   ""
15548   "bsr{l}\t{%1, %0|%0, %1}"
15549   [(set_attr "prefix_0f" "1")
15550    (set_attr "mode" "SI")])
15551
15552 (define_insn "popcount<mode>2"
15553   [(set (match_operand:SWI248 0 "register_operand" "=r")
15554         (popcount:SWI248
15555           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15556    (clobber (reg:CC FLAGS_REG))]
15557   "TARGET_POPCNT"
15558 {
15559 #if TARGET_MACHO
15560   return "popcnt\t{%1, %0|%0, %1}";
15561 #else
15562   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15563 #endif
15564 }
15565   [(set_attr "prefix_rep" "1")
15566    (set_attr "type" "bitmanip")
15567    (set_attr "mode" "<MODE>")])
15568
15569 (define_insn "*popcount<mode>2_cmp"
15570   [(set (reg FLAGS_REG)
15571         (compare
15572           (popcount:SWI248
15573             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15574           (const_int 0)))
15575    (set (match_operand:SWI248 0 "register_operand" "=r")
15576         (popcount:SWI248 (match_dup 1)))]
15577   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15578 {
15579 #if TARGET_MACHO
15580   return "popcnt\t{%1, %0|%0, %1}";
15581 #else
15582   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15583 #endif
15584 }
15585   [(set_attr "prefix_rep" "1")
15586    (set_attr "type" "bitmanip")
15587    (set_attr "mode" "<MODE>")])
15588
15589 (define_insn "*popcountsi2_cmp_zext"
15590   [(set (reg FLAGS_REG)
15591         (compare
15592           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15593           (const_int 0)))
15594    (set (match_operand:DI 0 "register_operand" "=r")
15595         (zero_extend:DI(popcount:SI (match_dup 1))))]
15596   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15597 {
15598 #if TARGET_MACHO
15599   return "popcnt\t{%1, %0|%0, %1}";
15600 #else
15601   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15602 #endif
15603 }
15604   [(set_attr "prefix_rep" "1")
15605    (set_attr "type" "bitmanip")
15606    (set_attr "mode" "SI")])
15607
15608 (define_expand "bswapsi2"
15609   [(set (match_operand:SI 0 "register_operand" "")
15610         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15611   ""
15612 {
15613   if (!TARGET_BSWAP)
15614     {
15615       rtx x = operands[0];
15616
15617       emit_move_insn (x, operands[1]);
15618       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15619       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15620       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15621       DONE;
15622     }
15623 })
15624
15625 (define_insn "*bswapsi_1"
15626   [(set (match_operand:SI 0 "register_operand" "=r")
15627         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15628   "TARGET_BSWAP"
15629   "bswap\t%0"
15630   [(set_attr "prefix_0f" "1")
15631    (set_attr "length" "2")])
15632
15633 (define_insn "*bswaphi_lowpart_1"
15634   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15635         (bswap:HI (match_dup 0)))
15636    (clobber (reg:CC FLAGS_REG))]
15637   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15638   "@
15639     xchg{b}\t{%h0, %b0|%b0, %h0}
15640     rol{w}\t{$8, %0|%0, 8}"
15641   [(set_attr "length" "2,4")
15642    (set_attr "mode" "QI,HI")])
15643
15644 (define_insn "bswaphi_lowpart"
15645   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15646         (bswap:HI (match_dup 0)))
15647    (clobber (reg:CC FLAGS_REG))]
15648   ""
15649   "rol{w}\t{$8, %0|%0, 8}"
15650   [(set_attr "length" "4")
15651    (set_attr "mode" "HI")])
15652
15653 (define_insn "bswapdi2"
15654   [(set (match_operand:DI 0 "register_operand" "=r")
15655         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15656   "TARGET_64BIT"
15657   "bswap\t%0"
15658   [(set_attr "prefix_0f" "1")
15659    (set_attr "length" "3")])
15660
15661 (define_expand "clzdi2"
15662   [(parallel
15663      [(set (match_operand:DI 0 "register_operand" "")
15664            (minus:DI (const_int 63)
15665                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15666       (clobber (reg:CC FLAGS_REG))])
15667    (parallel
15668      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15669       (clobber (reg:CC FLAGS_REG))])]
15670   "TARGET_64BIT"
15671 {
15672   if (TARGET_ABM)
15673     {
15674       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15675       DONE;
15676     }
15677 })
15678
15679 (define_insn "clzdi2_abm"
15680   [(set (match_operand:DI 0 "register_operand" "=r")
15681         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15682    (clobber (reg:CC FLAGS_REG))]
15683   "TARGET_64BIT && TARGET_ABM"
15684   "lzcnt{q}\t{%1, %0|%0, %1}"
15685   [(set_attr "prefix_rep" "1")
15686    (set_attr "type" "bitmanip")
15687    (set_attr "mode" "DI")])
15688
15689 (define_insn "*bsr_rex64"
15690   [(set (match_operand:DI 0 "register_operand" "=r")
15691         (minus:DI (const_int 63)
15692                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15693    (clobber (reg:CC FLAGS_REG))]
15694   "TARGET_64BIT"
15695   "bsr{q}\t{%1, %0|%0, %1}"
15696   [(set_attr "prefix_0f" "1")
15697    (set_attr "mode" "DI")])
15698
15699 (define_expand "clzhi2"
15700   [(parallel
15701      [(set (match_operand:HI 0 "register_operand" "")
15702            (minus:HI (const_int 15)
15703                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15704       (clobber (reg:CC FLAGS_REG))])
15705    (parallel
15706      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15707       (clobber (reg:CC FLAGS_REG))])]
15708   ""
15709 {
15710   if (TARGET_ABM)
15711     {
15712       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15713       DONE;
15714     }
15715 })
15716
15717 (define_insn "clzhi2_abm"
15718   [(set (match_operand:HI 0 "register_operand" "=r")
15719         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15720    (clobber (reg:CC FLAGS_REG))]
15721   "TARGET_ABM"
15722   "lzcnt{w}\t{%1, %0|%0, %1}"
15723   [(set_attr "prefix_rep" "1")
15724    (set_attr "type" "bitmanip")
15725    (set_attr "mode" "HI")])
15726
15727 (define_insn "*bsrhi"
15728   [(set (match_operand:HI 0 "register_operand" "=r")
15729         (minus:HI (const_int 15)
15730                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15731    (clobber (reg:CC FLAGS_REG))]
15732   ""
15733   "bsr{w}\t{%1, %0|%0, %1}"
15734   [(set_attr "prefix_0f" "1")
15735    (set_attr "mode" "HI")])
15736
15737 (define_expand "paritydi2"
15738   [(set (match_operand:DI 0 "register_operand" "")
15739         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15740   "! TARGET_POPCNT"
15741 {
15742   rtx scratch = gen_reg_rtx (QImode);
15743   rtx cond;
15744
15745   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15746                                 NULL_RTX, operands[1]));
15747
15748   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15749                          gen_rtx_REG (CCmode, FLAGS_REG),
15750                          const0_rtx);
15751   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15752
15753   if (TARGET_64BIT)
15754     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15755   else
15756     {
15757       rtx tmp = gen_reg_rtx (SImode);
15758
15759       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15760       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15761     }
15762   DONE;
15763 })
15764
15765 (define_insn_and_split "paritydi2_cmp"
15766   [(set (reg:CC FLAGS_REG)
15767         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15768    (clobber (match_scratch:DI 0 "=r"))
15769    (clobber (match_scratch:SI 1 "=&r"))
15770    (clobber (match_scratch:HI 2 "=Q"))]
15771   "! TARGET_POPCNT"
15772   "#"
15773   "&& reload_completed"
15774   [(parallel
15775      [(set (match_dup 1)
15776            (xor:SI (match_dup 1) (match_dup 4)))
15777       (clobber (reg:CC FLAGS_REG))])
15778    (parallel
15779      [(set (reg:CC FLAGS_REG)
15780            (parity:CC (match_dup 1)))
15781       (clobber (match_dup 1))
15782       (clobber (match_dup 2))])]
15783 {
15784   operands[4] = gen_lowpart (SImode, operands[3]);
15785
15786   if (TARGET_64BIT)
15787     {
15788       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15789       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15790     }
15791   else
15792     operands[1] = gen_highpart (SImode, operands[3]);
15793 })
15794
15795 (define_expand "paritysi2"
15796   [(set (match_operand:SI 0 "register_operand" "")
15797         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15798   "! TARGET_POPCNT"
15799 {
15800   rtx scratch = gen_reg_rtx (QImode);
15801   rtx cond;
15802
15803   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15804
15805   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15806                          gen_rtx_REG (CCmode, FLAGS_REG),
15807                          const0_rtx);
15808   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15809
15810   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15811   DONE;
15812 })
15813
15814 (define_insn_and_split "paritysi2_cmp"
15815   [(set (reg:CC FLAGS_REG)
15816         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15817    (clobber (match_scratch:SI 0 "=r"))
15818    (clobber (match_scratch:HI 1 "=&Q"))]
15819   "! TARGET_POPCNT"
15820   "#"
15821   "&& reload_completed"
15822   [(parallel
15823      [(set (match_dup 1)
15824            (xor:HI (match_dup 1) (match_dup 3)))
15825       (clobber (reg:CC FLAGS_REG))])
15826    (parallel
15827      [(set (reg:CC FLAGS_REG)
15828            (parity:CC (match_dup 1)))
15829       (clobber (match_dup 1))])]
15830 {
15831   operands[3] = gen_lowpart (HImode, operands[2]);
15832
15833   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15834   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15835 })
15836
15837 (define_insn "*parityhi2_cmp"
15838   [(set (reg:CC FLAGS_REG)
15839         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15840    (clobber (match_scratch:HI 0 "=Q"))]
15841   "! TARGET_POPCNT"
15842   "xor{b}\t{%h0, %b0|%b0, %h0}"
15843   [(set_attr "length" "2")
15844    (set_attr "mode" "HI")])
15845
15846 (define_insn "*parityqi2_cmp"
15847   [(set (reg:CC FLAGS_REG)
15848         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15849   "! TARGET_POPCNT"
15850   "test{b}\t%0, %0"
15851   [(set_attr "length" "2")
15852    (set_attr "mode" "QI")])
15853 \f
15854 ;; Thread-local storage patterns for ELF.
15855 ;;
15856 ;; Note that these code sequences must appear exactly as shown
15857 ;; in order to allow linker relaxation.
15858
15859 (define_insn "*tls_global_dynamic_32_gnu"
15860   [(set (match_operand:SI 0 "register_operand" "=a")
15861         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15862                     (match_operand:SI 2 "tls_symbolic_operand" "")
15863                     (match_operand:SI 3 "call_insn_operand" "")]
15864                     UNSPEC_TLS_GD))
15865    (clobber (match_scratch:SI 4 "=d"))
15866    (clobber (match_scratch:SI 5 "=c"))
15867    (clobber (reg:CC FLAGS_REG))]
15868   "!TARGET_64BIT && TARGET_GNU_TLS"
15869   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15870   [(set_attr "type" "multi")
15871    (set_attr "length" "12")])
15872
15873 (define_insn "*tls_global_dynamic_32_sun"
15874   [(set (match_operand:SI 0 "register_operand" "=a")
15875         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15876                     (match_operand:SI 2 "tls_symbolic_operand" "")
15877                     (match_operand:SI 3 "call_insn_operand" "")]
15878                     UNSPEC_TLS_GD))
15879    (clobber (match_scratch:SI 4 "=d"))
15880    (clobber (match_scratch:SI 5 "=c"))
15881    (clobber (reg:CC FLAGS_REG))]
15882   "!TARGET_64BIT && TARGET_SUN_TLS"
15883   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15884         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15885   [(set_attr "type" "multi")
15886    (set_attr "length" "14")])
15887
15888 (define_expand "tls_global_dynamic_32"
15889   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15890                    (unspec:SI
15891                     [(match_dup 2)
15892                      (match_operand:SI 1 "tls_symbolic_operand" "")
15893                      (match_dup 3)]
15894                     UNSPEC_TLS_GD))
15895               (clobber (match_scratch:SI 4 ""))
15896               (clobber (match_scratch:SI 5 ""))
15897               (clobber (reg:CC FLAGS_REG))])]
15898   ""
15899 {
15900   if (flag_pic)
15901     operands[2] = pic_offset_table_rtx;
15902   else
15903     {
15904       operands[2] = gen_reg_rtx (Pmode);
15905       emit_insn (gen_set_got (operands[2]));
15906     }
15907   if (TARGET_GNU2_TLS)
15908     {
15909        emit_insn (gen_tls_dynamic_gnu2_32
15910                   (operands[0], operands[1], operands[2]));
15911        DONE;
15912     }
15913   operands[3] = ix86_tls_get_addr ();
15914 })
15915
15916 (define_insn "*tls_global_dynamic_64"
15917   [(set (match_operand:DI 0 "register_operand" "=a")
15918         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15919                  (match_operand:DI 3 "" "")))
15920    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15921               UNSPEC_TLS_GD)]
15922   "TARGET_64BIT"
15923   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15924   [(set_attr "type" "multi")
15925    (set_attr "length" "16")])
15926
15927 (define_expand "tls_global_dynamic_64"
15928   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15929                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15930               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15931                          UNSPEC_TLS_GD)])]
15932   ""
15933 {
15934   if (TARGET_GNU2_TLS)
15935     {
15936        emit_insn (gen_tls_dynamic_gnu2_64
15937                   (operands[0], operands[1]));
15938        DONE;
15939     }
15940   operands[2] = ix86_tls_get_addr ();
15941 })
15942
15943 (define_insn "*tls_local_dynamic_base_32_gnu"
15944   [(set (match_operand:SI 0 "register_operand" "=a")
15945         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15946                     (match_operand:SI 2 "call_insn_operand" "")]
15947                    UNSPEC_TLS_LD_BASE))
15948    (clobber (match_scratch:SI 3 "=d"))
15949    (clobber (match_scratch:SI 4 "=c"))
15950    (clobber (reg:CC FLAGS_REG))]
15951   "!TARGET_64BIT && TARGET_GNU_TLS"
15952   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15953   [(set_attr "type" "multi")
15954    (set_attr "length" "11")])
15955
15956 (define_insn "*tls_local_dynamic_base_32_sun"
15957   [(set (match_operand:SI 0 "register_operand" "=a")
15958         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15959                     (match_operand:SI 2 "call_insn_operand" "")]
15960                    UNSPEC_TLS_LD_BASE))
15961    (clobber (match_scratch:SI 3 "=d"))
15962    (clobber (match_scratch:SI 4 "=c"))
15963    (clobber (reg:CC FLAGS_REG))]
15964   "!TARGET_64BIT && TARGET_SUN_TLS"
15965   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15966         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15967   [(set_attr "type" "multi")
15968    (set_attr "length" "13")])
15969
15970 (define_expand "tls_local_dynamic_base_32"
15971   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15972                    (unspec:SI [(match_dup 1) (match_dup 2)]
15973                               UNSPEC_TLS_LD_BASE))
15974               (clobber (match_scratch:SI 3 ""))
15975               (clobber (match_scratch:SI 4 ""))
15976               (clobber (reg:CC FLAGS_REG))])]
15977   ""
15978 {
15979   if (flag_pic)
15980     operands[1] = pic_offset_table_rtx;
15981   else
15982     {
15983       operands[1] = gen_reg_rtx (Pmode);
15984       emit_insn (gen_set_got (operands[1]));
15985     }
15986   if (TARGET_GNU2_TLS)
15987     {
15988        emit_insn (gen_tls_dynamic_gnu2_32
15989                   (operands[0], ix86_tls_module_base (), operands[1]));
15990        DONE;
15991     }
15992   operands[2] = ix86_tls_get_addr ();
15993 })
15994
15995 (define_insn "*tls_local_dynamic_base_64"
15996   [(set (match_operand:DI 0 "register_operand" "=a")
15997         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15998                  (match_operand:DI 2 "" "")))
15999    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16000   "TARGET_64BIT"
16001   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16002   [(set_attr "type" "multi")
16003    (set_attr "length" "12")])
16004
16005 (define_expand "tls_local_dynamic_base_64"
16006   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16007                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16008               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16009   ""
16010 {
16011   if (TARGET_GNU2_TLS)
16012     {
16013        emit_insn (gen_tls_dynamic_gnu2_64
16014                   (operands[0], ix86_tls_module_base ()));
16015        DONE;
16016     }
16017   operands[1] = ix86_tls_get_addr ();
16018 })
16019
16020 ;; Local dynamic of a single variable is a lose.  Show combine how
16021 ;; to convert that back to global dynamic.
16022
16023 (define_insn_and_split "*tls_local_dynamic_32_once"
16024   [(set (match_operand:SI 0 "register_operand" "=a")
16025         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16026                              (match_operand:SI 2 "call_insn_operand" "")]
16027                             UNSPEC_TLS_LD_BASE)
16028                  (const:SI (unspec:SI
16029                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16030                             UNSPEC_DTPOFF))))
16031    (clobber (match_scratch:SI 4 "=d"))
16032    (clobber (match_scratch:SI 5 "=c"))
16033    (clobber (reg:CC FLAGS_REG))]
16034   ""
16035   "#"
16036   ""
16037   [(parallel [(set (match_dup 0)
16038                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16039                               UNSPEC_TLS_GD))
16040               (clobber (match_dup 4))
16041               (clobber (match_dup 5))
16042               (clobber (reg:CC FLAGS_REG))])]
16043   "")
16044
16045 ;; Load and add the thread base pointer from %gs:0.
16046
16047 (define_insn "*load_tp_si"
16048   [(set (match_operand:SI 0 "register_operand" "=r")
16049         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16050   "!TARGET_64BIT"
16051   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16052   [(set_attr "type" "imov")
16053    (set_attr "modrm" "0")
16054    (set_attr "length" "7")
16055    (set_attr "memory" "load")
16056    (set_attr "imm_disp" "false")])
16057
16058 (define_insn "*add_tp_si"
16059   [(set (match_operand:SI 0 "register_operand" "=r")
16060         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16061                  (match_operand:SI 1 "register_operand" "0")))
16062    (clobber (reg:CC FLAGS_REG))]
16063   "!TARGET_64BIT"
16064   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16065   [(set_attr "type" "alu")
16066    (set_attr "modrm" "0")
16067    (set_attr "length" "7")
16068    (set_attr "memory" "load")
16069    (set_attr "imm_disp" "false")])
16070
16071 (define_insn "*load_tp_di"
16072   [(set (match_operand:DI 0 "register_operand" "=r")
16073         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16074   "TARGET_64BIT"
16075   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16076   [(set_attr "type" "imov")
16077    (set_attr "modrm" "0")
16078    (set_attr "length" "7")
16079    (set_attr "memory" "load")
16080    (set_attr "imm_disp" "false")])
16081
16082 (define_insn "*add_tp_di"
16083   [(set (match_operand:DI 0 "register_operand" "=r")
16084         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16085                  (match_operand:DI 1 "register_operand" "0")))
16086    (clobber (reg:CC FLAGS_REG))]
16087   "TARGET_64BIT"
16088   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16089   [(set_attr "type" "alu")
16090    (set_attr "modrm" "0")
16091    (set_attr "length" "7")
16092    (set_attr "memory" "load")
16093    (set_attr "imm_disp" "false")])
16094
16095 ;; GNU2 TLS patterns can be split.
16096
16097 (define_expand "tls_dynamic_gnu2_32"
16098   [(set (match_dup 3)
16099         (plus:SI (match_operand:SI 2 "register_operand" "")
16100                  (const:SI
16101                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16102                              UNSPEC_TLSDESC))))
16103    (parallel
16104     [(set (match_operand:SI 0 "register_operand" "")
16105           (unspec:SI [(match_dup 1) (match_dup 3)
16106                       (match_dup 2) (reg:SI SP_REG)]
16107                       UNSPEC_TLSDESC))
16108      (clobber (reg:CC FLAGS_REG))])]
16109   "!TARGET_64BIT && TARGET_GNU2_TLS"
16110 {
16111   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16112   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16113 })
16114
16115 (define_insn "*tls_dynamic_lea_32"
16116   [(set (match_operand:SI 0 "register_operand" "=r")
16117         (plus:SI (match_operand:SI 1 "register_operand" "b")
16118                  (const:SI
16119                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16120                               UNSPEC_TLSDESC))))]
16121   "!TARGET_64BIT && TARGET_GNU2_TLS"
16122   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16123   [(set_attr "type" "lea")
16124    (set_attr "mode" "SI")
16125    (set_attr "length" "6")
16126    (set_attr "length_address" "4")])
16127
16128 (define_insn "*tls_dynamic_call_32"
16129   [(set (match_operand:SI 0 "register_operand" "=a")
16130         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16131                     (match_operand:SI 2 "register_operand" "0")
16132                     ;; we have to make sure %ebx still points to the GOT
16133                     (match_operand:SI 3 "register_operand" "b")
16134                     (reg:SI SP_REG)]
16135                    UNSPEC_TLSDESC))
16136    (clobber (reg:CC FLAGS_REG))]
16137   "!TARGET_64BIT && TARGET_GNU2_TLS"
16138   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16139   [(set_attr "type" "call")
16140    (set_attr "length" "2")
16141    (set_attr "length_address" "0")])
16142
16143 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16144   [(set (match_operand:SI 0 "register_operand" "=&a")
16145         (plus:SI
16146          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16147                      (match_operand:SI 4 "" "")
16148                      (match_operand:SI 2 "register_operand" "b")
16149                      (reg:SI SP_REG)]
16150                     UNSPEC_TLSDESC)
16151          (const:SI (unspec:SI
16152                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16153                     UNSPEC_DTPOFF))))
16154    (clobber (reg:CC FLAGS_REG))]
16155   "!TARGET_64BIT && TARGET_GNU2_TLS"
16156   "#"
16157   ""
16158   [(set (match_dup 0) (match_dup 5))]
16159 {
16160   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16161   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16162 })
16163
16164 (define_expand "tls_dynamic_gnu2_64"
16165   [(set (match_dup 2)
16166         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16167                    UNSPEC_TLSDESC))
16168    (parallel
16169     [(set (match_operand:DI 0 "register_operand" "")
16170           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16171                      UNSPEC_TLSDESC))
16172      (clobber (reg:CC FLAGS_REG))])]
16173   "TARGET_64BIT && TARGET_GNU2_TLS"
16174 {
16175   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16176   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16177 })
16178
16179 (define_insn "*tls_dynamic_lea_64"
16180   [(set (match_operand:DI 0 "register_operand" "=r")
16181         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16182                    UNSPEC_TLSDESC))]
16183   "TARGET_64BIT && TARGET_GNU2_TLS"
16184   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16185   [(set_attr "type" "lea")
16186    (set_attr "mode" "DI")
16187    (set_attr "length" "7")
16188    (set_attr "length_address" "4")])
16189
16190 (define_insn "*tls_dynamic_call_64"
16191   [(set (match_operand:DI 0 "register_operand" "=a")
16192         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16193                     (match_operand:DI 2 "register_operand" "0")
16194                     (reg:DI SP_REG)]
16195                    UNSPEC_TLSDESC))
16196    (clobber (reg:CC FLAGS_REG))]
16197   "TARGET_64BIT && TARGET_GNU2_TLS"
16198   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16199   [(set_attr "type" "call")
16200    (set_attr "length" "2")
16201    (set_attr "length_address" "0")])
16202
16203 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16204   [(set (match_operand:DI 0 "register_operand" "=&a")
16205         (plus:DI
16206          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16207                      (match_operand:DI 3 "" "")
16208                      (reg:DI SP_REG)]
16209                     UNSPEC_TLSDESC)
16210          (const:DI (unspec:DI
16211                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16212                     UNSPEC_DTPOFF))))
16213    (clobber (reg:CC FLAGS_REG))]
16214   "TARGET_64BIT && TARGET_GNU2_TLS"
16215   "#"
16216   ""
16217   [(set (match_dup 0) (match_dup 4))]
16218 {
16219   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16220   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16221 })
16222
16223 ;;
16224 \f
16225 ;; These patterns match the binary 387 instructions for addM3, subM3,
16226 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16227 ;; SFmode.  The first is the normal insn, the second the same insn but
16228 ;; with one operand a conversion, and the third the same insn but with
16229 ;; the other operand a conversion.  The conversion may be SFmode or
16230 ;; SImode if the target mode DFmode, but only SImode if the target mode
16231 ;; is SFmode.
16232
16233 ;; Gcc is slightly more smart about handling normal two address instructions
16234 ;; so use special patterns for add and mull.
16235
16236 (define_insn "*fop_<mode>_comm_mixed_avx"
16237   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16238         (match_operator:MODEF 3 "binary_fp_operator"
16239           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16240            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16241   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16242    && COMMUTATIVE_ARITH_P (operands[3])
16243    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16244   "* return output_387_binary_op (insn, operands);"
16245   [(set (attr "type")
16246         (if_then_else (eq_attr "alternative" "1")
16247            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16248               (const_string "ssemul")
16249               (const_string "sseadd"))
16250            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16251               (const_string "fmul")
16252               (const_string "fop"))))
16253    (set_attr "prefix" "orig,maybe_vex")
16254    (set_attr "mode" "<MODE>")])
16255
16256 (define_insn "*fop_<mode>_comm_mixed"
16257   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16258         (match_operator:MODEF 3 "binary_fp_operator"
16259           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16260            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16261   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16262    && COMMUTATIVE_ARITH_P (operands[3])
16263    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16264   "* return output_387_binary_op (insn, operands);"
16265   [(set (attr "type")
16266         (if_then_else (eq_attr "alternative" "1")
16267            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16268               (const_string "ssemul")
16269               (const_string "sseadd"))
16270            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16271               (const_string "fmul")
16272               (const_string "fop"))))
16273    (set_attr "mode" "<MODE>")])
16274
16275 (define_insn "*fop_<mode>_comm_avx"
16276   [(set (match_operand:MODEF 0 "register_operand" "=x")
16277         (match_operator:MODEF 3 "binary_fp_operator"
16278           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16279            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16280   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16281    && COMMUTATIVE_ARITH_P (operands[3])
16282    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16283   "* return output_387_binary_op (insn, operands);"
16284   [(set (attr "type")
16285         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16286            (const_string "ssemul")
16287            (const_string "sseadd")))
16288    (set_attr "prefix" "vex")
16289    (set_attr "mode" "<MODE>")])
16290
16291 (define_insn "*fop_<mode>_comm_sse"
16292   [(set (match_operand:MODEF 0 "register_operand" "=x")
16293         (match_operator:MODEF 3 "binary_fp_operator"
16294           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16295            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16296   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16297    && COMMUTATIVE_ARITH_P (operands[3])
16298    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16299   "* return output_387_binary_op (insn, operands);"
16300   [(set (attr "type")
16301         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16302            (const_string "ssemul")
16303            (const_string "sseadd")))
16304    (set_attr "mode" "<MODE>")])
16305
16306 (define_insn "*fop_<mode>_comm_i387"
16307   [(set (match_operand:MODEF 0 "register_operand" "=f")
16308         (match_operator:MODEF 3 "binary_fp_operator"
16309           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16310            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16311   "TARGET_80387
16312    && COMMUTATIVE_ARITH_P (operands[3])
16313    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16314   "* return output_387_binary_op (insn, operands);"
16315   [(set (attr "type")
16316         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16317            (const_string "fmul")
16318            (const_string "fop")))
16319    (set_attr "mode" "<MODE>")])
16320
16321 (define_insn "*fop_<mode>_1_mixed_avx"
16322   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16323         (match_operator:MODEF 3 "binary_fp_operator"
16324           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16325            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16326   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16327    && !COMMUTATIVE_ARITH_P (operands[3])
16328    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16329   "* return output_387_binary_op (insn, operands);"
16330   [(set (attr "type")
16331         (cond [(and (eq_attr "alternative" "2")
16332                     (match_operand:MODEF 3 "mult_operator" ""))
16333                  (const_string "ssemul")
16334                (and (eq_attr "alternative" "2")
16335                     (match_operand:MODEF 3 "div_operator" ""))
16336                  (const_string "ssediv")
16337                (eq_attr "alternative" "2")
16338                  (const_string "sseadd")
16339                (match_operand:MODEF 3 "mult_operator" "")
16340                  (const_string "fmul")
16341                (match_operand:MODEF 3 "div_operator" "")
16342                  (const_string "fdiv")
16343               ]
16344               (const_string "fop")))
16345    (set_attr "prefix" "orig,orig,maybe_vex")
16346    (set_attr "mode" "<MODE>")])
16347
16348 (define_insn "*fop_<mode>_1_mixed"
16349   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16350         (match_operator:MODEF 3 "binary_fp_operator"
16351           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16352            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16353   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16354    && !COMMUTATIVE_ARITH_P (operands[3])
16355    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16356   "* return output_387_binary_op (insn, operands);"
16357   [(set (attr "type")
16358         (cond [(and (eq_attr "alternative" "2")
16359                     (match_operand:MODEF 3 "mult_operator" ""))
16360                  (const_string "ssemul")
16361                (and (eq_attr "alternative" "2")
16362                     (match_operand:MODEF 3 "div_operator" ""))
16363                  (const_string "ssediv")
16364                (eq_attr "alternative" "2")
16365                  (const_string "sseadd")
16366                (match_operand:MODEF 3 "mult_operator" "")
16367                  (const_string "fmul")
16368                (match_operand:MODEF 3 "div_operator" "")
16369                  (const_string "fdiv")
16370               ]
16371               (const_string "fop")))
16372    (set_attr "mode" "<MODE>")])
16373
16374 (define_insn "*rcpsf2_sse"
16375   [(set (match_operand:SF 0 "register_operand" "=x")
16376         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16377                    UNSPEC_RCP))]
16378   "TARGET_SSE_MATH"
16379   "%vrcpss\t{%1, %d0|%d0, %1}"
16380   [(set_attr "type" "sse")
16381    (set_attr "prefix" "maybe_vex")
16382    (set_attr "mode" "SF")])
16383
16384 (define_insn "*fop_<mode>_1_avx"
16385   [(set (match_operand:MODEF 0 "register_operand" "=x")
16386         (match_operator:MODEF 3 "binary_fp_operator"
16387           [(match_operand:MODEF 1 "register_operand" "x")
16388            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16389   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16390    && !COMMUTATIVE_ARITH_P (operands[3])"
16391   "* return output_387_binary_op (insn, operands);"
16392   [(set (attr "type")
16393         (cond [(match_operand:MODEF 3 "mult_operator" "")
16394                  (const_string "ssemul")
16395                (match_operand:MODEF 3 "div_operator" "")
16396                  (const_string "ssediv")
16397               ]
16398               (const_string "sseadd")))
16399    (set_attr "prefix" "vex")
16400    (set_attr "mode" "<MODE>")])
16401
16402 (define_insn "*fop_<mode>_1_sse"
16403   [(set (match_operand:MODEF 0 "register_operand" "=x")
16404         (match_operator:MODEF 3 "binary_fp_operator"
16405           [(match_operand:MODEF 1 "register_operand" "0")
16406            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16407   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16408    && !COMMUTATIVE_ARITH_P (operands[3])"
16409   "* return output_387_binary_op (insn, operands);"
16410   [(set (attr "type")
16411         (cond [(match_operand:MODEF 3 "mult_operator" "")
16412                  (const_string "ssemul")
16413                (match_operand:MODEF 3 "div_operator" "")
16414                  (const_string "ssediv")
16415               ]
16416               (const_string "sseadd")))
16417    (set_attr "mode" "<MODE>")])
16418
16419 ;; This pattern is not fully shadowed by the pattern above.
16420 (define_insn "*fop_<mode>_1_i387"
16421   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16422         (match_operator:MODEF 3 "binary_fp_operator"
16423           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16424            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16425   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16426    && !COMMUTATIVE_ARITH_P (operands[3])
16427    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16428   "* return output_387_binary_op (insn, operands);"
16429   [(set (attr "type")
16430         (cond [(match_operand:MODEF 3 "mult_operator" "")
16431                  (const_string "fmul")
16432                (match_operand:MODEF 3 "div_operator" "")
16433                  (const_string "fdiv")
16434               ]
16435               (const_string "fop")))
16436    (set_attr "mode" "<MODE>")])
16437
16438 ;; ??? Add SSE splitters for these!
16439 (define_insn "*fop_<MODEF:mode>_2_i387"
16440   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16441         (match_operator:MODEF 3 "binary_fp_operator"
16442           [(float:MODEF
16443              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16444            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16445   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16446    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16447   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16448   [(set (attr "type")
16449         (cond [(match_operand:MODEF 3 "mult_operator" "")
16450                  (const_string "fmul")
16451                (match_operand:MODEF 3 "div_operator" "")
16452                  (const_string "fdiv")
16453               ]
16454               (const_string "fop")))
16455    (set_attr "fp_int_src" "true")
16456    (set_attr "mode" "<X87MODEI12:MODE>")])
16457
16458 (define_insn "*fop_<MODEF:mode>_3_i387"
16459   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16460         (match_operator:MODEF 3 "binary_fp_operator"
16461           [(match_operand:MODEF 1 "register_operand" "0,0")
16462            (float:MODEF
16463              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16464   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16465    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16466   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16467   [(set (attr "type")
16468         (cond [(match_operand:MODEF 3 "mult_operator" "")
16469                  (const_string "fmul")
16470                (match_operand:MODEF 3 "div_operator" "")
16471                  (const_string "fdiv")
16472               ]
16473               (const_string "fop")))
16474    (set_attr "fp_int_src" "true")
16475    (set_attr "mode" "<MODE>")])
16476
16477 (define_insn "*fop_df_4_i387"
16478   [(set (match_operand:DF 0 "register_operand" "=f,f")
16479         (match_operator:DF 3 "binary_fp_operator"
16480            [(float_extend:DF
16481              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16482             (match_operand:DF 2 "register_operand" "0,f")]))]
16483   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16484    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16485   "* return output_387_binary_op (insn, operands);"
16486   [(set (attr "type")
16487         (cond [(match_operand:DF 3 "mult_operator" "")
16488                  (const_string "fmul")
16489                (match_operand:DF 3 "div_operator" "")
16490                  (const_string "fdiv")
16491               ]
16492               (const_string "fop")))
16493    (set_attr "mode" "SF")])
16494
16495 (define_insn "*fop_df_5_i387"
16496   [(set (match_operand:DF 0 "register_operand" "=f,f")
16497         (match_operator:DF 3 "binary_fp_operator"
16498           [(match_operand:DF 1 "register_operand" "0,f")
16499            (float_extend:DF
16500             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16501   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16502   "* return output_387_binary_op (insn, operands);"
16503   [(set (attr "type")
16504         (cond [(match_operand:DF 3 "mult_operator" "")
16505                  (const_string "fmul")
16506                (match_operand:DF 3 "div_operator" "")
16507                  (const_string "fdiv")
16508               ]
16509               (const_string "fop")))
16510    (set_attr "mode" "SF")])
16511
16512 (define_insn "*fop_df_6_i387"
16513   [(set (match_operand:DF 0 "register_operand" "=f,f")
16514         (match_operator:DF 3 "binary_fp_operator"
16515           [(float_extend:DF
16516             (match_operand:SF 1 "register_operand" "0,f"))
16517            (float_extend:DF
16518             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16519   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16520   "* return output_387_binary_op (insn, operands);"
16521   [(set (attr "type")
16522         (cond [(match_operand:DF 3 "mult_operator" "")
16523                  (const_string "fmul")
16524                (match_operand:DF 3 "div_operator" "")
16525                  (const_string "fdiv")
16526               ]
16527               (const_string "fop")))
16528    (set_attr "mode" "SF")])
16529
16530 (define_insn "*fop_xf_comm_i387"
16531   [(set (match_operand:XF 0 "register_operand" "=f")
16532         (match_operator:XF 3 "binary_fp_operator"
16533                         [(match_operand:XF 1 "register_operand" "%0")
16534                          (match_operand:XF 2 "register_operand" "f")]))]
16535   "TARGET_80387
16536    && COMMUTATIVE_ARITH_P (operands[3])"
16537   "* return output_387_binary_op (insn, operands);"
16538   [(set (attr "type")
16539         (if_then_else (match_operand:XF 3 "mult_operator" "")
16540            (const_string "fmul")
16541            (const_string "fop")))
16542    (set_attr "mode" "XF")])
16543
16544 (define_insn "*fop_xf_1_i387"
16545   [(set (match_operand:XF 0 "register_operand" "=f,f")
16546         (match_operator:XF 3 "binary_fp_operator"
16547                         [(match_operand:XF 1 "register_operand" "0,f")
16548                          (match_operand:XF 2 "register_operand" "f,0")]))]
16549   "TARGET_80387
16550    && !COMMUTATIVE_ARITH_P (operands[3])"
16551   "* return output_387_binary_op (insn, operands);"
16552   [(set (attr "type")
16553         (cond [(match_operand:XF 3 "mult_operator" "")
16554                  (const_string "fmul")
16555                (match_operand:XF 3 "div_operator" "")
16556                  (const_string "fdiv")
16557               ]
16558               (const_string "fop")))
16559    (set_attr "mode" "XF")])
16560
16561 (define_insn "*fop_xf_2_i387"
16562   [(set (match_operand:XF 0 "register_operand" "=f,f")
16563         (match_operator:XF 3 "binary_fp_operator"
16564           [(float:XF
16565              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16566            (match_operand:XF 2 "register_operand" "0,0")]))]
16567   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16568   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16569   [(set (attr "type")
16570         (cond [(match_operand:XF 3 "mult_operator" "")
16571                  (const_string "fmul")
16572                (match_operand:XF 3 "div_operator" "")
16573                  (const_string "fdiv")
16574               ]
16575               (const_string "fop")))
16576    (set_attr "fp_int_src" "true")
16577    (set_attr "mode" "<MODE>")])
16578
16579 (define_insn "*fop_xf_3_i387"
16580   [(set (match_operand:XF 0 "register_operand" "=f,f")
16581         (match_operator:XF 3 "binary_fp_operator"
16582           [(match_operand:XF 1 "register_operand" "0,0")
16583            (float:XF
16584              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16585   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16586   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16587   [(set (attr "type")
16588         (cond [(match_operand:XF 3 "mult_operator" "")
16589                  (const_string "fmul")
16590                (match_operand:XF 3 "div_operator" "")
16591                  (const_string "fdiv")
16592               ]
16593               (const_string "fop")))
16594    (set_attr "fp_int_src" "true")
16595    (set_attr "mode" "<MODE>")])
16596
16597 (define_insn "*fop_xf_4_i387"
16598   [(set (match_operand:XF 0 "register_operand" "=f,f")
16599         (match_operator:XF 3 "binary_fp_operator"
16600            [(float_extend:XF
16601               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16602             (match_operand:XF 2 "register_operand" "0,f")]))]
16603   "TARGET_80387"
16604   "* return output_387_binary_op (insn, operands);"
16605   [(set (attr "type")
16606         (cond [(match_operand:XF 3 "mult_operator" "")
16607                  (const_string "fmul")
16608                (match_operand:XF 3 "div_operator" "")
16609                  (const_string "fdiv")
16610               ]
16611               (const_string "fop")))
16612    (set_attr "mode" "<MODE>")])
16613
16614 (define_insn "*fop_xf_5_i387"
16615   [(set (match_operand:XF 0 "register_operand" "=f,f")
16616         (match_operator:XF 3 "binary_fp_operator"
16617           [(match_operand:XF 1 "register_operand" "0,f")
16618            (float_extend:XF
16619              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16620   "TARGET_80387"
16621   "* return output_387_binary_op (insn, operands);"
16622   [(set (attr "type")
16623         (cond [(match_operand:XF 3 "mult_operator" "")
16624                  (const_string "fmul")
16625                (match_operand:XF 3 "div_operator" "")
16626                  (const_string "fdiv")
16627               ]
16628               (const_string "fop")))
16629    (set_attr "mode" "<MODE>")])
16630
16631 (define_insn "*fop_xf_6_i387"
16632   [(set (match_operand:XF 0 "register_operand" "=f,f")
16633         (match_operator:XF 3 "binary_fp_operator"
16634           [(float_extend:XF
16635              (match_operand:MODEF 1 "register_operand" "0,f"))
16636            (float_extend:XF
16637              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16638   "TARGET_80387"
16639   "* return output_387_binary_op (insn, operands);"
16640   [(set (attr "type")
16641         (cond [(match_operand:XF 3 "mult_operator" "")
16642                  (const_string "fmul")
16643                (match_operand:XF 3 "div_operator" "")
16644                  (const_string "fdiv")
16645               ]
16646               (const_string "fop")))
16647    (set_attr "mode" "<MODE>")])
16648
16649 (define_split
16650   [(set (match_operand 0 "register_operand" "")
16651         (match_operator 3 "binary_fp_operator"
16652            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16653             (match_operand 2 "register_operand" "")]))]
16654   "reload_completed
16655    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16656   [(const_int 0)]
16657 {
16658   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16659   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16660   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16661                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16662                                           GET_MODE (operands[3]),
16663                                           operands[4],
16664                                           operands[2])));
16665   ix86_free_from_memory (GET_MODE (operands[1]));
16666   DONE;
16667 })
16668
16669 (define_split
16670   [(set (match_operand 0 "register_operand" "")
16671         (match_operator 3 "binary_fp_operator"
16672            [(match_operand 1 "register_operand" "")
16673             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16674   "reload_completed
16675    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16676   [(const_int 0)]
16677 {
16678   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16679   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16680   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16681                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16682                                           GET_MODE (operands[3]),
16683                                           operands[1],
16684                                           operands[4])));
16685   ix86_free_from_memory (GET_MODE (operands[2]));
16686   DONE;
16687 })
16688 \f
16689 ;; FPU special functions.
16690
16691 ;; This pattern implements a no-op XFmode truncation for
16692 ;; all fancy i386 XFmode math functions.
16693
16694 (define_insn "truncxf<mode>2_i387_noop_unspec"
16695   [(set (match_operand:MODEF 0 "register_operand" "=f")
16696         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16697         UNSPEC_TRUNC_NOOP))]
16698   "TARGET_USE_FANCY_MATH_387"
16699   "* return output_387_reg_move (insn, operands);"
16700   [(set_attr "type" "fmov")
16701    (set_attr "mode" "<MODE>")])
16702
16703 (define_insn "sqrtxf2"
16704   [(set (match_operand:XF 0 "register_operand" "=f")
16705         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16706   "TARGET_USE_FANCY_MATH_387"
16707   "fsqrt"
16708   [(set_attr "type" "fpspc")
16709    (set_attr "mode" "XF")
16710    (set_attr "athlon_decode" "direct")
16711    (set_attr "amdfam10_decode" "direct")])
16712
16713 (define_insn "sqrt_extend<mode>xf2_i387"
16714   [(set (match_operand:XF 0 "register_operand" "=f")
16715         (sqrt:XF
16716           (float_extend:XF
16717             (match_operand:MODEF 1 "register_operand" "0"))))]
16718   "TARGET_USE_FANCY_MATH_387"
16719   "fsqrt"
16720   [(set_attr "type" "fpspc")
16721    (set_attr "mode" "XF")
16722    (set_attr "athlon_decode" "direct")
16723    (set_attr "amdfam10_decode" "direct")])
16724
16725 (define_insn "*rsqrtsf2_sse"
16726   [(set (match_operand:SF 0 "register_operand" "=x")
16727         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16728                    UNSPEC_RSQRT))]
16729   "TARGET_SSE_MATH"
16730   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16731   [(set_attr "type" "sse")
16732    (set_attr "prefix" "maybe_vex")
16733    (set_attr "mode" "SF")])
16734
16735 (define_expand "rsqrtsf2"
16736   [(set (match_operand:SF 0 "register_operand" "")
16737         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16738                    UNSPEC_RSQRT))]
16739   "TARGET_SSE_MATH"
16740 {
16741   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16742   DONE;
16743 })
16744
16745 (define_insn "*sqrt<mode>2_sse"
16746   [(set (match_operand:MODEF 0 "register_operand" "=x")
16747         (sqrt:MODEF
16748           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16749   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16750   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16751   [(set_attr "type" "sse")
16752    (set_attr "prefix" "maybe_vex")
16753    (set_attr "mode" "<MODE>")
16754    (set_attr "athlon_decode" "*")
16755    (set_attr "amdfam10_decode" "*")])
16756
16757 (define_expand "sqrt<mode>2"
16758   [(set (match_operand:MODEF 0 "register_operand" "")
16759         (sqrt:MODEF
16760           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16761   "TARGET_USE_FANCY_MATH_387
16762    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16763 {
16764   if (<MODE>mode == SFmode
16765       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16766       && flag_finite_math_only && !flag_trapping_math
16767       && flag_unsafe_math_optimizations)
16768     {
16769       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16770       DONE;
16771     }
16772
16773   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16774     {
16775       rtx op0 = gen_reg_rtx (XFmode);
16776       rtx op1 = force_reg (<MODE>mode, operands[1]);
16777
16778       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16779       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16780       DONE;
16781    }
16782 })
16783
16784 (define_insn "fpremxf4_i387"
16785   [(set (match_operand:XF 0 "register_operand" "=f")
16786         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16787                     (match_operand:XF 3 "register_operand" "1")]
16788                    UNSPEC_FPREM_F))
16789    (set (match_operand:XF 1 "register_operand" "=u")
16790         (unspec:XF [(match_dup 2) (match_dup 3)]
16791                    UNSPEC_FPREM_U))
16792    (set (reg:CCFP FPSR_REG)
16793         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16794                      UNSPEC_C2_FLAG))]
16795   "TARGET_USE_FANCY_MATH_387"
16796   "fprem"
16797   [(set_attr "type" "fpspc")
16798    (set_attr "mode" "XF")])
16799
16800 (define_expand "fmodxf3"
16801   [(use (match_operand:XF 0 "register_operand" ""))
16802    (use (match_operand:XF 1 "general_operand" ""))
16803    (use (match_operand:XF 2 "general_operand" ""))]
16804   "TARGET_USE_FANCY_MATH_387"
16805 {
16806   rtx label = gen_label_rtx ();
16807
16808   rtx op1 = gen_reg_rtx (XFmode);
16809   rtx op2 = gen_reg_rtx (XFmode);
16810
16811   emit_move_insn (op2, operands[2]);
16812   emit_move_insn (op1, operands[1]);
16813
16814   emit_label (label);
16815   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16816   ix86_emit_fp_unordered_jump (label);
16817   LABEL_NUSES (label) = 1;
16818
16819   emit_move_insn (operands[0], op1);
16820   DONE;
16821 })
16822
16823 (define_expand "fmod<mode>3"
16824   [(use (match_operand:MODEF 0 "register_operand" ""))
16825    (use (match_operand:MODEF 1 "general_operand" ""))
16826    (use (match_operand:MODEF 2 "general_operand" ""))]
16827   "TARGET_USE_FANCY_MATH_387"
16828 {
16829   rtx label = gen_label_rtx ();
16830
16831   rtx op1 = gen_reg_rtx (XFmode);
16832   rtx op2 = gen_reg_rtx (XFmode);
16833
16834   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16835   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16836
16837   emit_label (label);
16838   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16839   ix86_emit_fp_unordered_jump (label);
16840   LABEL_NUSES (label) = 1;
16841
16842   /* Truncate the result properly for strict SSE math.  */
16843   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16844       && !TARGET_MIX_SSE_I387)
16845     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16846   else
16847     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16848
16849   DONE;
16850 })
16851
16852 (define_insn "fprem1xf4_i387"
16853   [(set (match_operand:XF 0 "register_operand" "=f")
16854         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16855                     (match_operand:XF 3 "register_operand" "1")]
16856                    UNSPEC_FPREM1_F))
16857    (set (match_operand:XF 1 "register_operand" "=u")
16858         (unspec:XF [(match_dup 2) (match_dup 3)]
16859                    UNSPEC_FPREM1_U))
16860    (set (reg:CCFP FPSR_REG)
16861         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16862                      UNSPEC_C2_FLAG))]
16863   "TARGET_USE_FANCY_MATH_387"
16864   "fprem1"
16865   [(set_attr "type" "fpspc")
16866    (set_attr "mode" "XF")])
16867
16868 (define_expand "remainderxf3"
16869   [(use (match_operand:XF 0 "register_operand" ""))
16870    (use (match_operand:XF 1 "general_operand" ""))
16871    (use (match_operand:XF 2 "general_operand" ""))]
16872   "TARGET_USE_FANCY_MATH_387"
16873 {
16874   rtx label = gen_label_rtx ();
16875
16876   rtx op1 = gen_reg_rtx (XFmode);
16877   rtx op2 = gen_reg_rtx (XFmode);
16878
16879   emit_move_insn (op2, operands[2]);
16880   emit_move_insn (op1, operands[1]);
16881
16882   emit_label (label);
16883   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16884   ix86_emit_fp_unordered_jump (label);
16885   LABEL_NUSES (label) = 1;
16886
16887   emit_move_insn (operands[0], op1);
16888   DONE;
16889 })
16890
16891 (define_expand "remainder<mode>3"
16892   [(use (match_operand:MODEF 0 "register_operand" ""))
16893    (use (match_operand:MODEF 1 "general_operand" ""))
16894    (use (match_operand:MODEF 2 "general_operand" ""))]
16895   "TARGET_USE_FANCY_MATH_387"
16896 {
16897   rtx label = gen_label_rtx ();
16898
16899   rtx op1 = gen_reg_rtx (XFmode);
16900   rtx op2 = gen_reg_rtx (XFmode);
16901
16902   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16903   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16904
16905   emit_label (label);
16906
16907   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16908   ix86_emit_fp_unordered_jump (label);
16909   LABEL_NUSES (label) = 1;
16910
16911   /* Truncate the result properly for strict SSE math.  */
16912   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16913       && !TARGET_MIX_SSE_I387)
16914     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16915   else
16916     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16917
16918   DONE;
16919 })
16920
16921 (define_insn "*sinxf2_i387"
16922   [(set (match_operand:XF 0 "register_operand" "=f")
16923         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16924   "TARGET_USE_FANCY_MATH_387
16925    && flag_unsafe_math_optimizations"
16926   "fsin"
16927   [(set_attr "type" "fpspc")
16928    (set_attr "mode" "XF")])
16929
16930 (define_insn "*sin_extend<mode>xf2_i387"
16931   [(set (match_operand:XF 0 "register_operand" "=f")
16932         (unspec:XF [(float_extend:XF
16933                       (match_operand:MODEF 1 "register_operand" "0"))]
16934                    UNSPEC_SIN))]
16935   "TARGET_USE_FANCY_MATH_387
16936    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16937        || TARGET_MIX_SSE_I387)
16938    && flag_unsafe_math_optimizations"
16939   "fsin"
16940   [(set_attr "type" "fpspc")
16941    (set_attr "mode" "XF")])
16942
16943 (define_insn "*cosxf2_i387"
16944   [(set (match_operand:XF 0 "register_operand" "=f")
16945         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16946   "TARGET_USE_FANCY_MATH_387
16947    && flag_unsafe_math_optimizations"
16948   "fcos"
16949   [(set_attr "type" "fpspc")
16950    (set_attr "mode" "XF")])
16951
16952 (define_insn "*cos_extend<mode>xf2_i387"
16953   [(set (match_operand:XF 0 "register_operand" "=f")
16954         (unspec:XF [(float_extend:XF
16955                       (match_operand:MODEF 1 "register_operand" "0"))]
16956                    UNSPEC_COS))]
16957   "TARGET_USE_FANCY_MATH_387
16958    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16959        || TARGET_MIX_SSE_I387)
16960    && flag_unsafe_math_optimizations"
16961   "fcos"
16962   [(set_attr "type" "fpspc")
16963    (set_attr "mode" "XF")])
16964
16965 ;; When sincos pattern is defined, sin and cos builtin functions will be
16966 ;; expanded to sincos pattern with one of its outputs left unused.
16967 ;; CSE pass will figure out if two sincos patterns can be combined,
16968 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16969 ;; depending on the unused output.
16970
16971 (define_insn "sincosxf3"
16972   [(set (match_operand:XF 0 "register_operand" "=f")
16973         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16974                    UNSPEC_SINCOS_COS))
16975    (set (match_operand:XF 1 "register_operand" "=u")
16976         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16977   "TARGET_USE_FANCY_MATH_387
16978    && flag_unsafe_math_optimizations"
16979   "fsincos"
16980   [(set_attr "type" "fpspc")
16981    (set_attr "mode" "XF")])
16982
16983 (define_split
16984   [(set (match_operand:XF 0 "register_operand" "")
16985         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16986                    UNSPEC_SINCOS_COS))
16987    (set (match_operand:XF 1 "register_operand" "")
16988         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16989   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16990    && !(reload_completed || reload_in_progress)"
16991   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16992   "")
16993
16994 (define_split
16995   [(set (match_operand:XF 0 "register_operand" "")
16996         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16997                    UNSPEC_SINCOS_COS))
16998    (set (match_operand:XF 1 "register_operand" "")
16999         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17000   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17001    && !(reload_completed || reload_in_progress)"
17002   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17003   "")
17004
17005 (define_insn "sincos_extend<mode>xf3_i387"
17006   [(set (match_operand:XF 0 "register_operand" "=f")
17007         (unspec:XF [(float_extend:XF
17008                       (match_operand:MODEF 2 "register_operand" "0"))]
17009                    UNSPEC_SINCOS_COS))
17010    (set (match_operand:XF 1 "register_operand" "=u")
17011         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17012   "TARGET_USE_FANCY_MATH_387
17013    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17014        || TARGET_MIX_SSE_I387)
17015    && flag_unsafe_math_optimizations"
17016   "fsincos"
17017   [(set_attr "type" "fpspc")
17018    (set_attr "mode" "XF")])
17019
17020 (define_split
17021   [(set (match_operand:XF 0 "register_operand" "")
17022         (unspec:XF [(float_extend:XF
17023                       (match_operand:MODEF 2 "register_operand" ""))]
17024                    UNSPEC_SINCOS_COS))
17025    (set (match_operand:XF 1 "register_operand" "")
17026         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17027   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17028    && !(reload_completed || reload_in_progress)"
17029   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17030   "")
17031
17032 (define_split
17033   [(set (match_operand:XF 0 "register_operand" "")
17034         (unspec:XF [(float_extend:XF
17035                       (match_operand:MODEF 2 "register_operand" ""))]
17036                    UNSPEC_SINCOS_COS))
17037    (set (match_operand:XF 1 "register_operand" "")
17038         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17039   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17040    && !(reload_completed || reload_in_progress)"
17041   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17042   "")
17043
17044 (define_expand "sincos<mode>3"
17045   [(use (match_operand:MODEF 0 "register_operand" ""))
17046    (use (match_operand:MODEF 1 "register_operand" ""))
17047    (use (match_operand:MODEF 2 "register_operand" ""))]
17048   "TARGET_USE_FANCY_MATH_387
17049    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17050        || TARGET_MIX_SSE_I387)
17051    && flag_unsafe_math_optimizations"
17052 {
17053   rtx op0 = gen_reg_rtx (XFmode);
17054   rtx op1 = gen_reg_rtx (XFmode);
17055
17056   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17057   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17058   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17059   DONE;
17060 })
17061
17062 (define_insn "fptanxf4_i387"
17063   [(set (match_operand:XF 0 "register_operand" "=f")
17064         (match_operand:XF 3 "const_double_operand" "F"))
17065    (set (match_operand:XF 1 "register_operand" "=u")
17066         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17067                    UNSPEC_TAN))]
17068   "TARGET_USE_FANCY_MATH_387
17069    && flag_unsafe_math_optimizations
17070    && standard_80387_constant_p (operands[3]) == 2"
17071   "fptan"
17072   [(set_attr "type" "fpspc")
17073    (set_attr "mode" "XF")])
17074
17075 (define_insn "fptan_extend<mode>xf4_i387"
17076   [(set (match_operand:MODEF 0 "register_operand" "=f")
17077         (match_operand:MODEF 3 "const_double_operand" "F"))
17078    (set (match_operand:XF 1 "register_operand" "=u")
17079         (unspec:XF [(float_extend:XF
17080                       (match_operand:MODEF 2 "register_operand" "0"))]
17081                    UNSPEC_TAN))]
17082   "TARGET_USE_FANCY_MATH_387
17083    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17084        || TARGET_MIX_SSE_I387)
17085    && flag_unsafe_math_optimizations
17086    && standard_80387_constant_p (operands[3]) == 2"
17087   "fptan"
17088   [(set_attr "type" "fpspc")
17089    (set_attr "mode" "XF")])
17090
17091 (define_expand "tanxf2"
17092   [(use (match_operand:XF 0 "register_operand" ""))
17093    (use (match_operand:XF 1 "register_operand" ""))]
17094   "TARGET_USE_FANCY_MATH_387
17095    && flag_unsafe_math_optimizations"
17096 {
17097   rtx one = gen_reg_rtx (XFmode);
17098   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17099
17100   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17101   DONE;
17102 })
17103
17104 (define_expand "tan<mode>2"
17105   [(use (match_operand:MODEF 0 "register_operand" ""))
17106    (use (match_operand:MODEF 1 "register_operand" ""))]
17107   "TARGET_USE_FANCY_MATH_387
17108    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17109        || TARGET_MIX_SSE_I387)
17110    && flag_unsafe_math_optimizations"
17111 {
17112   rtx op0 = gen_reg_rtx (XFmode);
17113
17114   rtx one = gen_reg_rtx (<MODE>mode);
17115   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17116
17117   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17118                                              operands[1], op2));
17119   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17120   DONE;
17121 })
17122
17123 (define_insn "*fpatanxf3_i387"
17124   [(set (match_operand:XF 0 "register_operand" "=f")
17125         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17126                     (match_operand:XF 2 "register_operand" "u")]
17127                    UNSPEC_FPATAN))
17128    (clobber (match_scratch:XF 3 "=2"))]
17129   "TARGET_USE_FANCY_MATH_387
17130    && flag_unsafe_math_optimizations"
17131   "fpatan"
17132   [(set_attr "type" "fpspc")
17133    (set_attr "mode" "XF")])
17134
17135 (define_insn "fpatan_extend<mode>xf3_i387"
17136   [(set (match_operand:XF 0 "register_operand" "=f")
17137         (unspec:XF [(float_extend:XF
17138                       (match_operand:MODEF 1 "register_operand" "0"))
17139                     (float_extend:XF
17140                       (match_operand:MODEF 2 "register_operand" "u"))]
17141                    UNSPEC_FPATAN))
17142    (clobber (match_scratch:XF 3 "=2"))]
17143   "TARGET_USE_FANCY_MATH_387
17144    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17145        || TARGET_MIX_SSE_I387)
17146    && flag_unsafe_math_optimizations"
17147   "fpatan"
17148   [(set_attr "type" "fpspc")
17149    (set_attr "mode" "XF")])
17150
17151 (define_expand "atan2xf3"
17152   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17153                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17154                                (match_operand:XF 1 "register_operand" "")]
17155                               UNSPEC_FPATAN))
17156               (clobber (match_scratch:XF 3 ""))])]
17157   "TARGET_USE_FANCY_MATH_387
17158    && flag_unsafe_math_optimizations"
17159   "")
17160
17161 (define_expand "atan2<mode>3"
17162   [(use (match_operand:MODEF 0 "register_operand" ""))
17163    (use (match_operand:MODEF 1 "register_operand" ""))
17164    (use (match_operand:MODEF 2 "register_operand" ""))]
17165   "TARGET_USE_FANCY_MATH_387
17166    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17167        || TARGET_MIX_SSE_I387)
17168    && flag_unsafe_math_optimizations"
17169 {
17170   rtx op0 = gen_reg_rtx (XFmode);
17171
17172   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17173   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17174   DONE;
17175 })
17176
17177 (define_expand "atanxf2"
17178   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17179                    (unspec:XF [(match_dup 2)
17180                                (match_operand:XF 1 "register_operand" "")]
17181                               UNSPEC_FPATAN))
17182               (clobber (match_scratch:XF 3 ""))])]
17183   "TARGET_USE_FANCY_MATH_387
17184    && flag_unsafe_math_optimizations"
17185 {
17186   operands[2] = gen_reg_rtx (XFmode);
17187   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17188 })
17189
17190 (define_expand "atan<mode>2"
17191   [(use (match_operand:MODEF 0 "register_operand" ""))
17192    (use (match_operand:MODEF 1 "register_operand" ""))]
17193   "TARGET_USE_FANCY_MATH_387
17194    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17195        || TARGET_MIX_SSE_I387)
17196    && flag_unsafe_math_optimizations"
17197 {
17198   rtx op0 = gen_reg_rtx (XFmode);
17199
17200   rtx op2 = gen_reg_rtx (<MODE>mode);
17201   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17202
17203   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17204   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17205   DONE;
17206 })
17207
17208 (define_expand "asinxf2"
17209   [(set (match_dup 2)
17210         (mult:XF (match_operand:XF 1 "register_operand" "")
17211                  (match_dup 1)))
17212    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17213    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17214    (parallel [(set (match_operand:XF 0 "register_operand" "")
17215                    (unspec:XF [(match_dup 5) (match_dup 1)]
17216                               UNSPEC_FPATAN))
17217               (clobber (match_scratch:XF 6 ""))])]
17218   "TARGET_USE_FANCY_MATH_387
17219    && flag_unsafe_math_optimizations"
17220 {
17221   int i;
17222
17223   if (optimize_insn_for_size_p ())
17224     FAIL;
17225
17226   for (i = 2; i < 6; i++)
17227     operands[i] = gen_reg_rtx (XFmode);
17228
17229   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17230 })
17231
17232 (define_expand "asin<mode>2"
17233   [(use (match_operand:MODEF 0 "register_operand" ""))
17234    (use (match_operand:MODEF 1 "general_operand" ""))]
17235  "TARGET_USE_FANCY_MATH_387
17236    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17237        || TARGET_MIX_SSE_I387)
17238    && flag_unsafe_math_optimizations"
17239 {
17240   rtx op0 = gen_reg_rtx (XFmode);
17241   rtx op1 = gen_reg_rtx (XFmode);
17242
17243   if (optimize_insn_for_size_p ())
17244     FAIL;
17245
17246   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17247   emit_insn (gen_asinxf2 (op0, op1));
17248   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17249   DONE;
17250 })
17251
17252 (define_expand "acosxf2"
17253   [(set (match_dup 2)
17254         (mult:XF (match_operand:XF 1 "register_operand" "")
17255                  (match_dup 1)))
17256    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17257    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17258    (parallel [(set (match_operand:XF 0 "register_operand" "")
17259                    (unspec:XF [(match_dup 1) (match_dup 5)]
17260                               UNSPEC_FPATAN))
17261               (clobber (match_scratch:XF 6 ""))])]
17262   "TARGET_USE_FANCY_MATH_387
17263    && flag_unsafe_math_optimizations"
17264 {
17265   int i;
17266
17267   if (optimize_insn_for_size_p ())
17268     FAIL;
17269
17270   for (i = 2; i < 6; i++)
17271     operands[i] = gen_reg_rtx (XFmode);
17272
17273   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17274 })
17275
17276 (define_expand "acos<mode>2"
17277   [(use (match_operand:MODEF 0 "register_operand" ""))
17278    (use (match_operand:MODEF 1 "general_operand" ""))]
17279  "TARGET_USE_FANCY_MATH_387
17280    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17281        || TARGET_MIX_SSE_I387)
17282    && flag_unsafe_math_optimizations"
17283 {
17284   rtx op0 = gen_reg_rtx (XFmode);
17285   rtx op1 = gen_reg_rtx (XFmode);
17286
17287   if (optimize_insn_for_size_p ())
17288     FAIL;
17289
17290   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17291   emit_insn (gen_acosxf2 (op0, op1));
17292   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17293   DONE;
17294 })
17295
17296 (define_insn "fyl2xxf3_i387"
17297   [(set (match_operand:XF 0 "register_operand" "=f")
17298         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17299                     (match_operand:XF 2 "register_operand" "u")]
17300                    UNSPEC_FYL2X))
17301    (clobber (match_scratch:XF 3 "=2"))]
17302   "TARGET_USE_FANCY_MATH_387
17303    && flag_unsafe_math_optimizations"
17304   "fyl2x"
17305   [(set_attr "type" "fpspc")
17306    (set_attr "mode" "XF")])
17307
17308 (define_insn "fyl2x_extend<mode>xf3_i387"
17309   [(set (match_operand:XF 0 "register_operand" "=f")
17310         (unspec:XF [(float_extend:XF
17311                       (match_operand:MODEF 1 "register_operand" "0"))
17312                     (match_operand:XF 2 "register_operand" "u")]
17313                    UNSPEC_FYL2X))
17314    (clobber (match_scratch:XF 3 "=2"))]
17315   "TARGET_USE_FANCY_MATH_387
17316    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17317        || TARGET_MIX_SSE_I387)
17318    && flag_unsafe_math_optimizations"
17319   "fyl2x"
17320   [(set_attr "type" "fpspc")
17321    (set_attr "mode" "XF")])
17322
17323 (define_expand "logxf2"
17324   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17325                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17326                                (match_dup 2)] UNSPEC_FYL2X))
17327               (clobber (match_scratch:XF 3 ""))])]
17328   "TARGET_USE_FANCY_MATH_387
17329    && flag_unsafe_math_optimizations"
17330 {
17331   operands[2] = gen_reg_rtx (XFmode);
17332   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17333 })
17334
17335 (define_expand "log<mode>2"
17336   [(use (match_operand:MODEF 0 "register_operand" ""))
17337    (use (match_operand:MODEF 1 "register_operand" ""))]
17338   "TARGET_USE_FANCY_MATH_387
17339    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17340        || TARGET_MIX_SSE_I387)
17341    && flag_unsafe_math_optimizations"
17342 {
17343   rtx op0 = gen_reg_rtx (XFmode);
17344
17345   rtx op2 = gen_reg_rtx (XFmode);
17346   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17347
17348   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17349   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17350   DONE;
17351 })
17352
17353 (define_expand "log10xf2"
17354   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17355                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17356                                (match_dup 2)] UNSPEC_FYL2X))
17357               (clobber (match_scratch:XF 3 ""))])]
17358   "TARGET_USE_FANCY_MATH_387
17359    && flag_unsafe_math_optimizations"
17360 {
17361   operands[2] = gen_reg_rtx (XFmode);
17362   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17363 })
17364
17365 (define_expand "log10<mode>2"
17366   [(use (match_operand:MODEF 0 "register_operand" ""))
17367    (use (match_operand:MODEF 1 "register_operand" ""))]
17368   "TARGET_USE_FANCY_MATH_387
17369    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17370        || TARGET_MIX_SSE_I387)
17371    && flag_unsafe_math_optimizations"
17372 {
17373   rtx op0 = gen_reg_rtx (XFmode);
17374
17375   rtx op2 = gen_reg_rtx (XFmode);
17376   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17377
17378   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17379   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17380   DONE;
17381 })
17382
17383 (define_expand "log2xf2"
17384   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17385                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17386                                (match_dup 2)] UNSPEC_FYL2X))
17387               (clobber (match_scratch:XF 3 ""))])]
17388   "TARGET_USE_FANCY_MATH_387
17389    && flag_unsafe_math_optimizations"
17390 {
17391   operands[2] = gen_reg_rtx (XFmode);
17392   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17393 })
17394
17395 (define_expand "log2<mode>2"
17396   [(use (match_operand:MODEF 0 "register_operand" ""))
17397    (use (match_operand:MODEF 1 "register_operand" ""))]
17398   "TARGET_USE_FANCY_MATH_387
17399    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17400        || TARGET_MIX_SSE_I387)
17401    && flag_unsafe_math_optimizations"
17402 {
17403   rtx op0 = gen_reg_rtx (XFmode);
17404
17405   rtx op2 = gen_reg_rtx (XFmode);
17406   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17407
17408   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17409   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17410   DONE;
17411 })
17412
17413 (define_insn "fyl2xp1xf3_i387"
17414   [(set (match_operand:XF 0 "register_operand" "=f")
17415         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17416                     (match_operand:XF 2 "register_operand" "u")]
17417                    UNSPEC_FYL2XP1))
17418    (clobber (match_scratch:XF 3 "=2"))]
17419   "TARGET_USE_FANCY_MATH_387
17420    && flag_unsafe_math_optimizations"
17421   "fyl2xp1"
17422   [(set_attr "type" "fpspc")
17423    (set_attr "mode" "XF")])
17424
17425 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17426   [(set (match_operand:XF 0 "register_operand" "=f")
17427         (unspec:XF [(float_extend:XF
17428                       (match_operand:MODEF 1 "register_operand" "0"))
17429                     (match_operand:XF 2 "register_operand" "u")]
17430                    UNSPEC_FYL2XP1))
17431    (clobber (match_scratch:XF 3 "=2"))]
17432   "TARGET_USE_FANCY_MATH_387
17433    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17434        || TARGET_MIX_SSE_I387)
17435    && flag_unsafe_math_optimizations"
17436   "fyl2xp1"
17437   [(set_attr "type" "fpspc")
17438    (set_attr "mode" "XF")])
17439
17440 (define_expand "log1pxf2"
17441   [(use (match_operand:XF 0 "register_operand" ""))
17442    (use (match_operand:XF 1 "register_operand" ""))]
17443   "TARGET_USE_FANCY_MATH_387
17444    && flag_unsafe_math_optimizations"
17445 {
17446   if (optimize_insn_for_size_p ())
17447     FAIL;
17448
17449   ix86_emit_i387_log1p (operands[0], operands[1]);
17450   DONE;
17451 })
17452
17453 (define_expand "log1p<mode>2"
17454   [(use (match_operand:MODEF 0 "register_operand" ""))
17455    (use (match_operand:MODEF 1 "register_operand" ""))]
17456   "TARGET_USE_FANCY_MATH_387
17457    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17458        || TARGET_MIX_SSE_I387)
17459    && flag_unsafe_math_optimizations"
17460 {
17461   rtx op0;
17462
17463   if (optimize_insn_for_size_p ())
17464     FAIL;
17465
17466   op0 = gen_reg_rtx (XFmode);
17467
17468   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17469
17470   ix86_emit_i387_log1p (op0, operands[1]);
17471   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17472   DONE;
17473 })
17474
17475 (define_insn "fxtractxf3_i387"
17476   [(set (match_operand:XF 0 "register_operand" "=f")
17477         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17478                    UNSPEC_XTRACT_FRACT))
17479    (set (match_operand:XF 1 "register_operand" "=u")
17480         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17481   "TARGET_USE_FANCY_MATH_387
17482    && flag_unsafe_math_optimizations"
17483   "fxtract"
17484   [(set_attr "type" "fpspc")
17485    (set_attr "mode" "XF")])
17486
17487 (define_insn "fxtract_extend<mode>xf3_i387"
17488   [(set (match_operand:XF 0 "register_operand" "=f")
17489         (unspec:XF [(float_extend:XF
17490                       (match_operand:MODEF 2 "register_operand" "0"))]
17491                    UNSPEC_XTRACT_FRACT))
17492    (set (match_operand:XF 1 "register_operand" "=u")
17493         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17494   "TARGET_USE_FANCY_MATH_387
17495    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17496        || TARGET_MIX_SSE_I387)
17497    && flag_unsafe_math_optimizations"
17498   "fxtract"
17499   [(set_attr "type" "fpspc")
17500    (set_attr "mode" "XF")])
17501
17502 (define_expand "logbxf2"
17503   [(parallel [(set (match_dup 2)
17504                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17505                               UNSPEC_XTRACT_FRACT))
17506               (set (match_operand:XF 0 "register_operand" "")
17507                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17508   "TARGET_USE_FANCY_MATH_387
17509    && flag_unsafe_math_optimizations"
17510 {
17511   operands[2] = gen_reg_rtx (XFmode);
17512 })
17513
17514 (define_expand "logb<mode>2"
17515   [(use (match_operand:MODEF 0 "register_operand" ""))
17516    (use (match_operand:MODEF 1 "register_operand" ""))]
17517   "TARGET_USE_FANCY_MATH_387
17518    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17519        || TARGET_MIX_SSE_I387)
17520    && flag_unsafe_math_optimizations"
17521 {
17522   rtx op0 = gen_reg_rtx (XFmode);
17523   rtx op1 = gen_reg_rtx (XFmode);
17524
17525   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17526   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17527   DONE;
17528 })
17529
17530 (define_expand "ilogbxf2"
17531   [(use (match_operand:SI 0 "register_operand" ""))
17532    (use (match_operand:XF 1 "register_operand" ""))]
17533   "TARGET_USE_FANCY_MATH_387
17534    && flag_unsafe_math_optimizations"
17535 {
17536   rtx op0, op1;
17537
17538   if (optimize_insn_for_size_p ())
17539     FAIL;
17540
17541   op0 = gen_reg_rtx (XFmode);
17542   op1 = gen_reg_rtx (XFmode);
17543
17544   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17545   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17546   DONE;
17547 })
17548
17549 (define_expand "ilogb<mode>2"
17550   [(use (match_operand:SI 0 "register_operand" ""))
17551    (use (match_operand:MODEF 1 "register_operand" ""))]
17552   "TARGET_USE_FANCY_MATH_387
17553    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17554        || TARGET_MIX_SSE_I387)
17555    && flag_unsafe_math_optimizations"
17556 {
17557   rtx op0, op1;
17558
17559   if (optimize_insn_for_size_p ())
17560     FAIL;
17561
17562   op0 = gen_reg_rtx (XFmode);
17563   op1 = gen_reg_rtx (XFmode);
17564
17565   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17566   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17567   DONE;
17568 })
17569
17570 (define_insn "*f2xm1xf2_i387"
17571   [(set (match_operand:XF 0 "register_operand" "=f")
17572         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17573                    UNSPEC_F2XM1))]
17574   "TARGET_USE_FANCY_MATH_387
17575    && flag_unsafe_math_optimizations"
17576   "f2xm1"
17577   [(set_attr "type" "fpspc")
17578    (set_attr "mode" "XF")])
17579
17580 (define_insn "*fscalexf4_i387"
17581   [(set (match_operand:XF 0 "register_operand" "=f")
17582         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17583                     (match_operand:XF 3 "register_operand" "1")]
17584                    UNSPEC_FSCALE_FRACT))
17585    (set (match_operand:XF 1 "register_operand" "=u")
17586         (unspec:XF [(match_dup 2) (match_dup 3)]
17587                    UNSPEC_FSCALE_EXP))]
17588   "TARGET_USE_FANCY_MATH_387
17589    && flag_unsafe_math_optimizations"
17590   "fscale"
17591   [(set_attr "type" "fpspc")
17592    (set_attr "mode" "XF")])
17593
17594 (define_expand "expNcorexf3"
17595   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17596                                (match_operand:XF 2 "register_operand" "")))
17597    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17598    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17599    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17600    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17601    (parallel [(set (match_operand:XF 0 "register_operand" "")
17602                    (unspec:XF [(match_dup 8) (match_dup 4)]
17603                               UNSPEC_FSCALE_FRACT))
17604               (set (match_dup 9)
17605                    (unspec:XF [(match_dup 8) (match_dup 4)]
17606                               UNSPEC_FSCALE_EXP))])]
17607   "TARGET_USE_FANCY_MATH_387
17608    && flag_unsafe_math_optimizations"
17609 {
17610   int i;
17611
17612   if (optimize_insn_for_size_p ())
17613     FAIL;
17614
17615   for (i = 3; i < 10; i++)
17616     operands[i] = gen_reg_rtx (XFmode);
17617
17618   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17619 })
17620
17621 (define_expand "expxf2"
17622   [(use (match_operand:XF 0 "register_operand" ""))
17623    (use (match_operand:XF 1 "register_operand" ""))]
17624   "TARGET_USE_FANCY_MATH_387
17625    && flag_unsafe_math_optimizations"
17626 {
17627   rtx op2;
17628
17629   if (optimize_insn_for_size_p ())
17630     FAIL;
17631
17632   op2 = gen_reg_rtx (XFmode);
17633   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17634
17635   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17636   DONE;
17637 })
17638
17639 (define_expand "exp<mode>2"
17640   [(use (match_operand:MODEF 0 "register_operand" ""))
17641    (use (match_operand:MODEF 1 "general_operand" ""))]
17642  "TARGET_USE_FANCY_MATH_387
17643    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17644        || TARGET_MIX_SSE_I387)
17645    && flag_unsafe_math_optimizations"
17646 {
17647   rtx op0, op1;
17648
17649   if (optimize_insn_for_size_p ())
17650     FAIL;
17651
17652   op0 = gen_reg_rtx (XFmode);
17653   op1 = gen_reg_rtx (XFmode);
17654
17655   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17656   emit_insn (gen_expxf2 (op0, op1));
17657   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17658   DONE;
17659 })
17660
17661 (define_expand "exp10xf2"
17662   [(use (match_operand:XF 0 "register_operand" ""))
17663    (use (match_operand:XF 1 "register_operand" ""))]
17664   "TARGET_USE_FANCY_MATH_387
17665    && flag_unsafe_math_optimizations"
17666 {
17667   rtx op2;
17668
17669   if (optimize_insn_for_size_p ())
17670     FAIL;
17671
17672   op2 = gen_reg_rtx (XFmode);
17673   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17674
17675   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17676   DONE;
17677 })
17678
17679 (define_expand "exp10<mode>2"
17680   [(use (match_operand:MODEF 0 "register_operand" ""))
17681    (use (match_operand:MODEF 1 "general_operand" ""))]
17682  "TARGET_USE_FANCY_MATH_387
17683    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17684        || TARGET_MIX_SSE_I387)
17685    && flag_unsafe_math_optimizations"
17686 {
17687   rtx op0, op1;
17688
17689   if (optimize_insn_for_size_p ())
17690     FAIL;
17691
17692   op0 = gen_reg_rtx (XFmode);
17693   op1 = gen_reg_rtx (XFmode);
17694
17695   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17696   emit_insn (gen_exp10xf2 (op0, op1));
17697   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17698   DONE;
17699 })
17700
17701 (define_expand "exp2xf2"
17702   [(use (match_operand:XF 0 "register_operand" ""))
17703    (use (match_operand:XF 1 "register_operand" ""))]
17704   "TARGET_USE_FANCY_MATH_387
17705    && flag_unsafe_math_optimizations"
17706 {
17707   rtx op2;
17708
17709   if (optimize_insn_for_size_p ())
17710     FAIL;
17711
17712   op2 = gen_reg_rtx (XFmode);
17713   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17714
17715   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17716   DONE;
17717 })
17718
17719 (define_expand "exp2<mode>2"
17720   [(use (match_operand:MODEF 0 "register_operand" ""))
17721    (use (match_operand:MODEF 1 "general_operand" ""))]
17722  "TARGET_USE_FANCY_MATH_387
17723    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17724        || TARGET_MIX_SSE_I387)
17725    && flag_unsafe_math_optimizations"
17726 {
17727   rtx op0, op1;
17728
17729   if (optimize_insn_for_size_p ())
17730     FAIL;
17731
17732   op0 = gen_reg_rtx (XFmode);
17733   op1 = gen_reg_rtx (XFmode);
17734
17735   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17736   emit_insn (gen_exp2xf2 (op0, op1));
17737   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17738   DONE;
17739 })
17740
17741 (define_expand "expm1xf2"
17742   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17743                                (match_dup 2)))
17744    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17745    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17746    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17747    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17748    (parallel [(set (match_dup 7)
17749                    (unspec:XF [(match_dup 6) (match_dup 4)]
17750                               UNSPEC_FSCALE_FRACT))
17751               (set (match_dup 8)
17752                    (unspec:XF [(match_dup 6) (match_dup 4)]
17753                               UNSPEC_FSCALE_EXP))])
17754    (parallel [(set (match_dup 10)
17755                    (unspec:XF [(match_dup 9) (match_dup 8)]
17756                               UNSPEC_FSCALE_FRACT))
17757               (set (match_dup 11)
17758                    (unspec:XF [(match_dup 9) (match_dup 8)]
17759                               UNSPEC_FSCALE_EXP))])
17760    (set (match_dup 12) (minus:XF (match_dup 10)
17761                                  (float_extend:XF (match_dup 13))))
17762    (set (match_operand:XF 0 "register_operand" "")
17763         (plus:XF (match_dup 12) (match_dup 7)))]
17764   "TARGET_USE_FANCY_MATH_387
17765    && flag_unsafe_math_optimizations"
17766 {
17767   int i;
17768
17769   if (optimize_insn_for_size_p ())
17770     FAIL;
17771
17772   for (i = 2; i < 13; i++)
17773     operands[i] = gen_reg_rtx (XFmode);
17774
17775   operands[13]
17776     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17777
17778   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17779 })
17780
17781 (define_expand "expm1<mode>2"
17782   [(use (match_operand:MODEF 0 "register_operand" ""))
17783    (use (match_operand:MODEF 1 "general_operand" ""))]
17784  "TARGET_USE_FANCY_MATH_387
17785    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17786        || TARGET_MIX_SSE_I387)
17787    && flag_unsafe_math_optimizations"
17788 {
17789   rtx op0, op1;
17790
17791   if (optimize_insn_for_size_p ())
17792     FAIL;
17793
17794   op0 = gen_reg_rtx (XFmode);
17795   op1 = gen_reg_rtx (XFmode);
17796
17797   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17798   emit_insn (gen_expm1xf2 (op0, op1));
17799   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17800   DONE;
17801 })
17802
17803 (define_expand "ldexpxf3"
17804   [(set (match_dup 3)
17805         (float:XF (match_operand:SI 2 "register_operand" "")))
17806    (parallel [(set (match_operand:XF 0 " register_operand" "")
17807                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17808                                (match_dup 3)]
17809                               UNSPEC_FSCALE_FRACT))
17810               (set (match_dup 4)
17811                    (unspec:XF [(match_dup 1) (match_dup 3)]
17812                               UNSPEC_FSCALE_EXP))])]
17813   "TARGET_USE_FANCY_MATH_387
17814    && flag_unsafe_math_optimizations"
17815 {
17816   if (optimize_insn_for_size_p ())
17817     FAIL;
17818
17819   operands[3] = gen_reg_rtx (XFmode);
17820   operands[4] = gen_reg_rtx (XFmode);
17821 })
17822
17823 (define_expand "ldexp<mode>3"
17824   [(use (match_operand:MODEF 0 "register_operand" ""))
17825    (use (match_operand:MODEF 1 "general_operand" ""))
17826    (use (match_operand:SI 2 "register_operand" ""))]
17827  "TARGET_USE_FANCY_MATH_387
17828    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17829        || TARGET_MIX_SSE_I387)
17830    && flag_unsafe_math_optimizations"
17831 {
17832   rtx op0, op1;
17833
17834   if (optimize_insn_for_size_p ())
17835     FAIL;
17836
17837   op0 = gen_reg_rtx (XFmode);
17838   op1 = gen_reg_rtx (XFmode);
17839
17840   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17841   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17842   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17843   DONE;
17844 })
17845
17846 (define_expand "scalbxf3"
17847   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17848                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17849                                (match_operand:XF 2 "register_operand" "")]
17850                               UNSPEC_FSCALE_FRACT))
17851               (set (match_dup 3)
17852                    (unspec:XF [(match_dup 1) (match_dup 2)]
17853                               UNSPEC_FSCALE_EXP))])]
17854   "TARGET_USE_FANCY_MATH_387
17855    && flag_unsafe_math_optimizations"
17856 {
17857   if (optimize_insn_for_size_p ())
17858     FAIL;
17859
17860   operands[3] = gen_reg_rtx (XFmode);
17861 })
17862
17863 (define_expand "scalb<mode>3"
17864   [(use (match_operand:MODEF 0 "register_operand" ""))
17865    (use (match_operand:MODEF 1 "general_operand" ""))
17866    (use (match_operand:MODEF 2 "register_operand" ""))]
17867  "TARGET_USE_FANCY_MATH_387
17868    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17869        || TARGET_MIX_SSE_I387)
17870    && flag_unsafe_math_optimizations"
17871 {
17872   rtx op0, op1, op2;
17873
17874   if (optimize_insn_for_size_p ())
17875     FAIL;
17876
17877   op0 = gen_reg_rtx (XFmode);
17878   op1 = gen_reg_rtx (XFmode);
17879   op2 = gen_reg_rtx (XFmode);
17880
17881   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17882   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17883   emit_insn (gen_scalbxf3 (op0, op1, op2));
17884   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17885   DONE;
17886 })
17887 \f
17888
17889 (define_insn "sse4_1_round<mode>2"
17890   [(set (match_operand:MODEF 0 "register_operand" "=x")
17891         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17892                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17893                       UNSPEC_ROUND))]
17894   "TARGET_ROUND"
17895   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17896   [(set_attr "type" "ssecvt")
17897    (set_attr "prefix_extra" "1")
17898    (set_attr "prefix" "maybe_vex")
17899    (set_attr "mode" "<MODE>")])
17900
17901 (define_insn "rintxf2"
17902   [(set (match_operand:XF 0 "register_operand" "=f")
17903         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17904                    UNSPEC_FRNDINT))]
17905   "TARGET_USE_FANCY_MATH_387
17906    && flag_unsafe_math_optimizations"
17907   "frndint"
17908   [(set_attr "type" "fpspc")
17909    (set_attr "mode" "XF")])
17910
17911 (define_expand "rint<mode>2"
17912   [(use (match_operand:MODEF 0 "register_operand" ""))
17913    (use (match_operand:MODEF 1 "register_operand" ""))]
17914   "(TARGET_USE_FANCY_MATH_387
17915     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17916         || TARGET_MIX_SSE_I387)
17917     && flag_unsafe_math_optimizations)
17918    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17919        && !flag_trapping_math)"
17920 {
17921   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17922       && !flag_trapping_math)
17923     {
17924       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17925         FAIL;
17926       if (TARGET_ROUND)
17927         emit_insn (gen_sse4_1_round<mode>2
17928                    (operands[0], operands[1], GEN_INT (0x04)));
17929       else
17930         ix86_expand_rint (operand0, operand1);
17931     }
17932   else
17933     {
17934       rtx op0 = gen_reg_rtx (XFmode);
17935       rtx op1 = gen_reg_rtx (XFmode);
17936
17937       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17938       emit_insn (gen_rintxf2 (op0, op1));
17939
17940       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17941     }
17942   DONE;
17943 })
17944
17945 (define_expand "round<mode>2"
17946   [(match_operand:MODEF 0 "register_operand" "")
17947    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17948   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17949    && !flag_trapping_math && !flag_rounding_math"
17950 {
17951   if (optimize_insn_for_size_p ())
17952     FAIL;
17953   if (TARGET_64BIT || (<MODE>mode != DFmode))
17954     ix86_expand_round (operand0, operand1);
17955   else
17956     ix86_expand_rounddf_32 (operand0, operand1);
17957   DONE;
17958 })
17959
17960 (define_insn_and_split "*fistdi2_1"
17961   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17962         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17963                    UNSPEC_FIST))]
17964   "TARGET_USE_FANCY_MATH_387
17965    && !(reload_completed || reload_in_progress)"
17966   "#"
17967   "&& 1"
17968   [(const_int 0)]
17969 {
17970   if (memory_operand (operands[0], VOIDmode))
17971     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17972   else
17973     {
17974       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17975       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17976                                          operands[2]));
17977     }
17978   DONE;
17979 }
17980   [(set_attr "type" "fpspc")
17981    (set_attr "mode" "DI")])
17982
17983 (define_insn "fistdi2"
17984   [(set (match_operand:DI 0 "memory_operand" "=m")
17985         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17986                    UNSPEC_FIST))
17987    (clobber (match_scratch:XF 2 "=&1f"))]
17988   "TARGET_USE_FANCY_MATH_387"
17989   "* return output_fix_trunc (insn, operands, 0);"
17990   [(set_attr "type" "fpspc")
17991    (set_attr "mode" "DI")])
17992
17993 (define_insn "fistdi2_with_temp"
17994   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17995         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17996                    UNSPEC_FIST))
17997    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17998    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17999   "TARGET_USE_FANCY_MATH_387"
18000   "#"
18001   [(set_attr "type" "fpspc")
18002    (set_attr "mode" "DI")])
18003
18004 (define_split
18005   [(set (match_operand:DI 0 "register_operand" "")
18006         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18007                    UNSPEC_FIST))
18008    (clobber (match_operand:DI 2 "memory_operand" ""))
18009    (clobber (match_scratch 3 ""))]
18010   "reload_completed"
18011   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18012               (clobber (match_dup 3))])
18013    (set (match_dup 0) (match_dup 2))]
18014   "")
18015
18016 (define_split
18017   [(set (match_operand:DI 0 "memory_operand" "")
18018         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18019                    UNSPEC_FIST))
18020    (clobber (match_operand:DI 2 "memory_operand" ""))
18021    (clobber (match_scratch 3 ""))]
18022   "reload_completed"
18023   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18024               (clobber (match_dup 3))])]
18025   "")
18026
18027 (define_insn_and_split "*fist<mode>2_1"
18028   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18029         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18030                            UNSPEC_FIST))]
18031   "TARGET_USE_FANCY_MATH_387
18032    && !(reload_completed || reload_in_progress)"
18033   "#"
18034   "&& 1"
18035   [(const_int 0)]
18036 {
18037   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18038   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18039                                         operands[2]));
18040   DONE;
18041 }
18042   [(set_attr "type" "fpspc")
18043    (set_attr "mode" "<MODE>")])
18044
18045 (define_insn "fist<mode>2"
18046   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18047         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18048                            UNSPEC_FIST))]
18049   "TARGET_USE_FANCY_MATH_387"
18050   "* return output_fix_trunc (insn, operands, 0);"
18051   [(set_attr "type" "fpspc")
18052    (set_attr "mode" "<MODE>")])
18053
18054 (define_insn "fist<mode>2_with_temp"
18055   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18056         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18057                            UNSPEC_FIST))
18058    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18059   "TARGET_USE_FANCY_MATH_387"
18060   "#"
18061   [(set_attr "type" "fpspc")
18062    (set_attr "mode" "<MODE>")])
18063
18064 (define_split
18065   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18066         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18067                            UNSPEC_FIST))
18068    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18069   "reload_completed"
18070   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18071    (set (match_dup 0) (match_dup 2))]
18072   "")
18073
18074 (define_split
18075   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18076         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18077                            UNSPEC_FIST))
18078    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18079   "reload_completed"
18080   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18081   "")
18082
18083 (define_expand "lrintxf<mode>2"
18084   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18085      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18086                       UNSPEC_FIST))]
18087   "TARGET_USE_FANCY_MATH_387"
18088   "")
18089
18090 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18091   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18092      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18093                         UNSPEC_FIX_NOTRUNC))]
18094   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18095    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18096   "")
18097
18098 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18099   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18100    (match_operand:MODEF 1 "register_operand" "")]
18101   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18102    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18103    && !flag_trapping_math && !flag_rounding_math"
18104 {
18105   if (optimize_insn_for_size_p ())
18106     FAIL;
18107   ix86_expand_lround (operand0, operand1);
18108   DONE;
18109 })
18110
18111 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18112 (define_insn_and_split "frndintxf2_floor"
18113   [(set (match_operand:XF 0 "register_operand" "")
18114         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18115          UNSPEC_FRNDINT_FLOOR))
18116    (clobber (reg:CC FLAGS_REG))]
18117   "TARGET_USE_FANCY_MATH_387
18118    && flag_unsafe_math_optimizations
18119    && !(reload_completed || reload_in_progress)"
18120   "#"
18121   "&& 1"
18122   [(const_int 0)]
18123 {
18124   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18125
18126   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18127   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18128
18129   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18130                                         operands[2], operands[3]));
18131   DONE;
18132 }
18133   [(set_attr "type" "frndint")
18134    (set_attr "i387_cw" "floor")
18135    (set_attr "mode" "XF")])
18136
18137 (define_insn "frndintxf2_floor_i387"
18138   [(set (match_operand:XF 0 "register_operand" "=f")
18139         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18140          UNSPEC_FRNDINT_FLOOR))
18141    (use (match_operand:HI 2 "memory_operand" "m"))
18142    (use (match_operand:HI 3 "memory_operand" "m"))]
18143   "TARGET_USE_FANCY_MATH_387
18144    && flag_unsafe_math_optimizations"
18145   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18146   [(set_attr "type" "frndint")
18147    (set_attr "i387_cw" "floor")
18148    (set_attr "mode" "XF")])
18149
18150 (define_expand "floorxf2"
18151   [(use (match_operand:XF 0 "register_operand" ""))
18152    (use (match_operand:XF 1 "register_operand" ""))]
18153   "TARGET_USE_FANCY_MATH_387
18154    && flag_unsafe_math_optimizations"
18155 {
18156   if (optimize_insn_for_size_p ())
18157     FAIL;
18158   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18159   DONE;
18160 })
18161
18162 (define_expand "floor<mode>2"
18163   [(use (match_operand:MODEF 0 "register_operand" ""))
18164    (use (match_operand:MODEF 1 "register_operand" ""))]
18165   "(TARGET_USE_FANCY_MATH_387
18166     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18167         || TARGET_MIX_SSE_I387)
18168     && flag_unsafe_math_optimizations)
18169    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18170        && !flag_trapping_math)"
18171 {
18172   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18173       && !flag_trapping_math
18174       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18175     {
18176       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18177         FAIL;
18178       if (TARGET_ROUND)
18179         emit_insn (gen_sse4_1_round<mode>2
18180                    (operands[0], operands[1], GEN_INT (0x01)));
18181       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18182         ix86_expand_floorceil (operand0, operand1, true);
18183       else
18184         ix86_expand_floorceildf_32 (operand0, operand1, true);
18185     }
18186   else
18187     {
18188       rtx op0, op1;
18189
18190       if (optimize_insn_for_size_p ())
18191         FAIL;
18192
18193       op0 = gen_reg_rtx (XFmode);
18194       op1 = gen_reg_rtx (XFmode);
18195       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18196       emit_insn (gen_frndintxf2_floor (op0, op1));
18197
18198       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18199     }
18200   DONE;
18201 })
18202
18203 (define_insn_and_split "*fist<mode>2_floor_1"
18204   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18205         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18206          UNSPEC_FIST_FLOOR))
18207    (clobber (reg:CC FLAGS_REG))]
18208   "TARGET_USE_FANCY_MATH_387
18209    && flag_unsafe_math_optimizations
18210    && !(reload_completed || reload_in_progress)"
18211   "#"
18212   "&& 1"
18213   [(const_int 0)]
18214 {
18215   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18216
18217   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18218   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18219   if (memory_operand (operands[0], VOIDmode))
18220     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18221                                       operands[2], operands[3]));
18222   else
18223     {
18224       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18225       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18226                                                   operands[2], operands[3],
18227                                                   operands[4]));
18228     }
18229   DONE;
18230 }
18231   [(set_attr "type" "fistp")
18232    (set_attr "i387_cw" "floor")
18233    (set_attr "mode" "<MODE>")])
18234
18235 (define_insn "fistdi2_floor"
18236   [(set (match_operand:DI 0 "memory_operand" "=m")
18237         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18238          UNSPEC_FIST_FLOOR))
18239    (use (match_operand:HI 2 "memory_operand" "m"))
18240    (use (match_operand:HI 3 "memory_operand" "m"))
18241    (clobber (match_scratch:XF 4 "=&1f"))]
18242   "TARGET_USE_FANCY_MATH_387
18243    && flag_unsafe_math_optimizations"
18244   "* return output_fix_trunc (insn, operands, 0);"
18245   [(set_attr "type" "fistp")
18246    (set_attr "i387_cw" "floor")
18247    (set_attr "mode" "DI")])
18248
18249 (define_insn "fistdi2_floor_with_temp"
18250   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18251         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18252          UNSPEC_FIST_FLOOR))
18253    (use (match_operand:HI 2 "memory_operand" "m,m"))
18254    (use (match_operand:HI 3 "memory_operand" "m,m"))
18255    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18256    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18257   "TARGET_USE_FANCY_MATH_387
18258    && flag_unsafe_math_optimizations"
18259   "#"
18260   [(set_attr "type" "fistp")
18261    (set_attr "i387_cw" "floor")
18262    (set_attr "mode" "DI")])
18263
18264 (define_split
18265   [(set (match_operand:DI 0 "register_operand" "")
18266         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18267          UNSPEC_FIST_FLOOR))
18268    (use (match_operand:HI 2 "memory_operand" ""))
18269    (use (match_operand:HI 3 "memory_operand" ""))
18270    (clobber (match_operand:DI 4 "memory_operand" ""))
18271    (clobber (match_scratch 5 ""))]
18272   "reload_completed"
18273   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18274               (use (match_dup 2))
18275               (use (match_dup 3))
18276               (clobber (match_dup 5))])
18277    (set (match_dup 0) (match_dup 4))]
18278   "")
18279
18280 (define_split
18281   [(set (match_operand:DI 0 "memory_operand" "")
18282         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18283          UNSPEC_FIST_FLOOR))
18284    (use (match_operand:HI 2 "memory_operand" ""))
18285    (use (match_operand:HI 3 "memory_operand" ""))
18286    (clobber (match_operand:DI 4 "memory_operand" ""))
18287    (clobber (match_scratch 5 ""))]
18288   "reload_completed"
18289   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18290               (use (match_dup 2))
18291               (use (match_dup 3))
18292               (clobber (match_dup 5))])]
18293   "")
18294
18295 (define_insn "fist<mode>2_floor"
18296   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18297         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18298          UNSPEC_FIST_FLOOR))
18299    (use (match_operand:HI 2 "memory_operand" "m"))
18300    (use (match_operand:HI 3 "memory_operand" "m"))]
18301   "TARGET_USE_FANCY_MATH_387
18302    && flag_unsafe_math_optimizations"
18303   "* return output_fix_trunc (insn, operands, 0);"
18304   [(set_attr "type" "fistp")
18305    (set_attr "i387_cw" "floor")
18306    (set_attr "mode" "<MODE>")])
18307
18308 (define_insn "fist<mode>2_floor_with_temp"
18309   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18310         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18311          UNSPEC_FIST_FLOOR))
18312    (use (match_operand:HI 2 "memory_operand" "m,m"))
18313    (use (match_operand:HI 3 "memory_operand" "m,m"))
18314    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18315   "TARGET_USE_FANCY_MATH_387
18316    && flag_unsafe_math_optimizations"
18317   "#"
18318   [(set_attr "type" "fistp")
18319    (set_attr "i387_cw" "floor")
18320    (set_attr "mode" "<MODE>")])
18321
18322 (define_split
18323   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18324         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18325          UNSPEC_FIST_FLOOR))
18326    (use (match_operand:HI 2 "memory_operand" ""))
18327    (use (match_operand:HI 3 "memory_operand" ""))
18328    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18329   "reload_completed"
18330   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18331                                   UNSPEC_FIST_FLOOR))
18332               (use (match_dup 2))
18333               (use (match_dup 3))])
18334    (set (match_dup 0) (match_dup 4))]
18335   "")
18336
18337 (define_split
18338   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18339         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18340          UNSPEC_FIST_FLOOR))
18341    (use (match_operand:HI 2 "memory_operand" ""))
18342    (use (match_operand:HI 3 "memory_operand" ""))
18343    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18344   "reload_completed"
18345   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18346                                   UNSPEC_FIST_FLOOR))
18347               (use (match_dup 2))
18348               (use (match_dup 3))])]
18349   "")
18350
18351 (define_expand "lfloorxf<mode>2"
18352   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18353                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18354                     UNSPEC_FIST_FLOOR))
18355               (clobber (reg:CC FLAGS_REG))])]
18356   "TARGET_USE_FANCY_MATH_387
18357    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18358    && flag_unsafe_math_optimizations"
18359   "")
18360
18361 (define_expand "lfloor<mode>di2"
18362   [(match_operand:DI 0 "nonimmediate_operand" "")
18363    (match_operand:MODEF 1 "register_operand" "")]
18364   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18365    && !flag_trapping_math"
18366 {
18367   if (optimize_insn_for_size_p ())
18368     FAIL;
18369   ix86_expand_lfloorceil (operand0, operand1, true);
18370   DONE;
18371 })
18372
18373 (define_expand "lfloor<mode>si2"
18374   [(match_operand:SI 0 "nonimmediate_operand" "")
18375    (match_operand:MODEF 1 "register_operand" "")]
18376   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18377    && !flag_trapping_math"
18378 {
18379   if (optimize_insn_for_size_p () && TARGET_64BIT)
18380     FAIL;
18381   ix86_expand_lfloorceil (operand0, operand1, true);
18382   DONE;
18383 })
18384
18385 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18386 (define_insn_and_split "frndintxf2_ceil"
18387   [(set (match_operand:XF 0 "register_operand" "")
18388         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18389          UNSPEC_FRNDINT_CEIL))
18390    (clobber (reg:CC FLAGS_REG))]
18391   "TARGET_USE_FANCY_MATH_387
18392    && flag_unsafe_math_optimizations
18393    && !(reload_completed || reload_in_progress)"
18394   "#"
18395   "&& 1"
18396   [(const_int 0)]
18397 {
18398   ix86_optimize_mode_switching[I387_CEIL] = 1;
18399
18400   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18401   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18402
18403   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18404                                        operands[2], operands[3]));
18405   DONE;
18406 }
18407   [(set_attr "type" "frndint")
18408    (set_attr "i387_cw" "ceil")
18409    (set_attr "mode" "XF")])
18410
18411 (define_insn "frndintxf2_ceil_i387"
18412   [(set (match_operand:XF 0 "register_operand" "=f")
18413         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18414          UNSPEC_FRNDINT_CEIL))
18415    (use (match_operand:HI 2 "memory_operand" "m"))
18416    (use (match_operand:HI 3 "memory_operand" "m"))]
18417   "TARGET_USE_FANCY_MATH_387
18418    && flag_unsafe_math_optimizations"
18419   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18420   [(set_attr "type" "frndint")
18421    (set_attr "i387_cw" "ceil")
18422    (set_attr "mode" "XF")])
18423
18424 (define_expand "ceilxf2"
18425   [(use (match_operand:XF 0 "register_operand" ""))
18426    (use (match_operand:XF 1 "register_operand" ""))]
18427   "TARGET_USE_FANCY_MATH_387
18428    && flag_unsafe_math_optimizations"
18429 {
18430   if (optimize_insn_for_size_p ())
18431     FAIL;
18432   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18433   DONE;
18434 })
18435
18436 (define_expand "ceil<mode>2"
18437   [(use (match_operand:MODEF 0 "register_operand" ""))
18438    (use (match_operand:MODEF 1 "register_operand" ""))]
18439   "(TARGET_USE_FANCY_MATH_387
18440     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18441         || TARGET_MIX_SSE_I387)
18442     && flag_unsafe_math_optimizations)
18443    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18444        && !flag_trapping_math)"
18445 {
18446   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18447       && !flag_trapping_math
18448       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18449     {
18450       if (TARGET_ROUND)
18451         emit_insn (gen_sse4_1_round<mode>2
18452                    (operands[0], operands[1], GEN_INT (0x02)));
18453       else if (optimize_insn_for_size_p ())
18454         FAIL;
18455       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18456         ix86_expand_floorceil (operand0, operand1, false);
18457       else
18458         ix86_expand_floorceildf_32 (operand0, operand1, false);
18459     }
18460   else
18461     {
18462       rtx op0, op1;
18463
18464       if (optimize_insn_for_size_p ())
18465         FAIL;
18466
18467       op0 = gen_reg_rtx (XFmode);
18468       op1 = gen_reg_rtx (XFmode);
18469       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18470       emit_insn (gen_frndintxf2_ceil (op0, op1));
18471
18472       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18473     }
18474   DONE;
18475 })
18476
18477 (define_insn_and_split "*fist<mode>2_ceil_1"
18478   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18479         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18480          UNSPEC_FIST_CEIL))
18481    (clobber (reg:CC FLAGS_REG))]
18482   "TARGET_USE_FANCY_MATH_387
18483    && flag_unsafe_math_optimizations
18484    && !(reload_completed || reload_in_progress)"
18485   "#"
18486   "&& 1"
18487   [(const_int 0)]
18488 {
18489   ix86_optimize_mode_switching[I387_CEIL] = 1;
18490
18491   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18492   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18493   if (memory_operand (operands[0], VOIDmode))
18494     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18495                                      operands[2], operands[3]));
18496   else
18497     {
18498       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18499       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18500                                                  operands[2], operands[3],
18501                                                  operands[4]));
18502     }
18503   DONE;
18504 }
18505   [(set_attr "type" "fistp")
18506    (set_attr "i387_cw" "ceil")
18507    (set_attr "mode" "<MODE>")])
18508
18509 (define_insn "fistdi2_ceil"
18510   [(set (match_operand:DI 0 "memory_operand" "=m")
18511         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18512          UNSPEC_FIST_CEIL))
18513    (use (match_operand:HI 2 "memory_operand" "m"))
18514    (use (match_operand:HI 3 "memory_operand" "m"))
18515    (clobber (match_scratch:XF 4 "=&1f"))]
18516   "TARGET_USE_FANCY_MATH_387
18517    && flag_unsafe_math_optimizations"
18518   "* return output_fix_trunc (insn, operands, 0);"
18519   [(set_attr "type" "fistp")
18520    (set_attr "i387_cw" "ceil")
18521    (set_attr "mode" "DI")])
18522
18523 (define_insn "fistdi2_ceil_with_temp"
18524   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18525         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18526          UNSPEC_FIST_CEIL))
18527    (use (match_operand:HI 2 "memory_operand" "m,m"))
18528    (use (match_operand:HI 3 "memory_operand" "m,m"))
18529    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18530    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18531   "TARGET_USE_FANCY_MATH_387
18532    && flag_unsafe_math_optimizations"
18533   "#"
18534   [(set_attr "type" "fistp")
18535    (set_attr "i387_cw" "ceil")
18536    (set_attr "mode" "DI")])
18537
18538 (define_split
18539   [(set (match_operand:DI 0 "register_operand" "")
18540         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18541          UNSPEC_FIST_CEIL))
18542    (use (match_operand:HI 2 "memory_operand" ""))
18543    (use (match_operand:HI 3 "memory_operand" ""))
18544    (clobber (match_operand:DI 4 "memory_operand" ""))
18545    (clobber (match_scratch 5 ""))]
18546   "reload_completed"
18547   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18548               (use (match_dup 2))
18549               (use (match_dup 3))
18550               (clobber (match_dup 5))])
18551    (set (match_dup 0) (match_dup 4))]
18552   "")
18553
18554 (define_split
18555   [(set (match_operand:DI 0 "memory_operand" "")
18556         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18557          UNSPEC_FIST_CEIL))
18558    (use (match_operand:HI 2 "memory_operand" ""))
18559    (use (match_operand:HI 3 "memory_operand" ""))
18560    (clobber (match_operand:DI 4 "memory_operand" ""))
18561    (clobber (match_scratch 5 ""))]
18562   "reload_completed"
18563   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18564               (use (match_dup 2))
18565               (use (match_dup 3))
18566               (clobber (match_dup 5))])]
18567   "")
18568
18569 (define_insn "fist<mode>2_ceil"
18570   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18571         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18572          UNSPEC_FIST_CEIL))
18573    (use (match_operand:HI 2 "memory_operand" "m"))
18574    (use (match_operand:HI 3 "memory_operand" "m"))]
18575   "TARGET_USE_FANCY_MATH_387
18576    && flag_unsafe_math_optimizations"
18577   "* return output_fix_trunc (insn, operands, 0);"
18578   [(set_attr "type" "fistp")
18579    (set_attr "i387_cw" "ceil")
18580    (set_attr "mode" "<MODE>")])
18581
18582 (define_insn "fist<mode>2_ceil_with_temp"
18583   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18584         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18585          UNSPEC_FIST_CEIL))
18586    (use (match_operand:HI 2 "memory_operand" "m,m"))
18587    (use (match_operand:HI 3 "memory_operand" "m,m"))
18588    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18589   "TARGET_USE_FANCY_MATH_387
18590    && flag_unsafe_math_optimizations"
18591   "#"
18592   [(set_attr "type" "fistp")
18593    (set_attr "i387_cw" "ceil")
18594    (set_attr "mode" "<MODE>")])
18595
18596 (define_split
18597   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18598         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18599          UNSPEC_FIST_CEIL))
18600    (use (match_operand:HI 2 "memory_operand" ""))
18601    (use (match_operand:HI 3 "memory_operand" ""))
18602    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18603   "reload_completed"
18604   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18605                                   UNSPEC_FIST_CEIL))
18606               (use (match_dup 2))
18607               (use (match_dup 3))])
18608    (set (match_dup 0) (match_dup 4))]
18609   "")
18610
18611 (define_split
18612   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18613         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18614          UNSPEC_FIST_CEIL))
18615    (use (match_operand:HI 2 "memory_operand" ""))
18616    (use (match_operand:HI 3 "memory_operand" ""))
18617    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18618   "reload_completed"
18619   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18620                                   UNSPEC_FIST_CEIL))
18621               (use (match_dup 2))
18622               (use (match_dup 3))])]
18623   "")
18624
18625 (define_expand "lceilxf<mode>2"
18626   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18627                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18628                     UNSPEC_FIST_CEIL))
18629               (clobber (reg:CC FLAGS_REG))])]
18630   "TARGET_USE_FANCY_MATH_387
18631    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18632    && flag_unsafe_math_optimizations"
18633   "")
18634
18635 (define_expand "lceil<mode>di2"
18636   [(match_operand:DI 0 "nonimmediate_operand" "")
18637    (match_operand:MODEF 1 "register_operand" "")]
18638   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18639    && !flag_trapping_math"
18640 {
18641   ix86_expand_lfloorceil (operand0, operand1, false);
18642   DONE;
18643 })
18644
18645 (define_expand "lceil<mode>si2"
18646   [(match_operand:SI 0 "nonimmediate_operand" "")
18647    (match_operand:MODEF 1 "register_operand" "")]
18648   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18649    && !flag_trapping_math"
18650 {
18651   ix86_expand_lfloorceil (operand0, operand1, false);
18652   DONE;
18653 })
18654
18655 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18656 (define_insn_and_split "frndintxf2_trunc"
18657   [(set (match_operand:XF 0 "register_operand" "")
18658         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18659          UNSPEC_FRNDINT_TRUNC))
18660    (clobber (reg:CC FLAGS_REG))]
18661   "TARGET_USE_FANCY_MATH_387
18662    && flag_unsafe_math_optimizations
18663    && !(reload_completed || reload_in_progress)"
18664   "#"
18665   "&& 1"
18666   [(const_int 0)]
18667 {
18668   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18669
18670   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18671   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18672
18673   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18674                                         operands[2], operands[3]));
18675   DONE;
18676 }
18677   [(set_attr "type" "frndint")
18678    (set_attr "i387_cw" "trunc")
18679    (set_attr "mode" "XF")])
18680
18681 (define_insn "frndintxf2_trunc_i387"
18682   [(set (match_operand:XF 0 "register_operand" "=f")
18683         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18684          UNSPEC_FRNDINT_TRUNC))
18685    (use (match_operand:HI 2 "memory_operand" "m"))
18686    (use (match_operand:HI 3 "memory_operand" "m"))]
18687   "TARGET_USE_FANCY_MATH_387
18688    && flag_unsafe_math_optimizations"
18689   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18690   [(set_attr "type" "frndint")
18691    (set_attr "i387_cw" "trunc")
18692    (set_attr "mode" "XF")])
18693
18694 (define_expand "btruncxf2"
18695   [(use (match_operand:XF 0 "register_operand" ""))
18696    (use (match_operand:XF 1 "register_operand" ""))]
18697   "TARGET_USE_FANCY_MATH_387
18698    && flag_unsafe_math_optimizations"
18699 {
18700   if (optimize_insn_for_size_p ())
18701     FAIL;
18702   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18703   DONE;
18704 })
18705
18706 (define_expand "btrunc<mode>2"
18707   [(use (match_operand:MODEF 0 "register_operand" ""))
18708    (use (match_operand:MODEF 1 "register_operand" ""))]
18709   "(TARGET_USE_FANCY_MATH_387
18710     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18711         || TARGET_MIX_SSE_I387)
18712     && flag_unsafe_math_optimizations)
18713    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18714        && !flag_trapping_math)"
18715 {
18716   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18717       && !flag_trapping_math
18718       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18719     {
18720       if (TARGET_ROUND)
18721         emit_insn (gen_sse4_1_round<mode>2
18722                    (operands[0], operands[1], GEN_INT (0x03)));
18723       else if (optimize_insn_for_size_p ())
18724         FAIL;
18725       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18726         ix86_expand_trunc (operand0, operand1);
18727       else
18728         ix86_expand_truncdf_32 (operand0, operand1);
18729     }
18730   else
18731     {
18732       rtx op0, op1;
18733
18734       if (optimize_insn_for_size_p ())
18735         FAIL;
18736
18737       op0 = gen_reg_rtx (XFmode);
18738       op1 = gen_reg_rtx (XFmode);
18739       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18740       emit_insn (gen_frndintxf2_trunc (op0, op1));
18741
18742       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18743     }
18744   DONE;
18745 })
18746
18747 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18748 (define_insn_and_split "frndintxf2_mask_pm"
18749   [(set (match_operand:XF 0 "register_operand" "")
18750         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18751          UNSPEC_FRNDINT_MASK_PM))
18752    (clobber (reg:CC FLAGS_REG))]
18753   "TARGET_USE_FANCY_MATH_387
18754    && flag_unsafe_math_optimizations
18755    && !(reload_completed || reload_in_progress)"
18756   "#"
18757   "&& 1"
18758   [(const_int 0)]
18759 {
18760   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18761
18762   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18763   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18764
18765   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18766                                           operands[2], operands[3]));
18767   DONE;
18768 }
18769   [(set_attr "type" "frndint")
18770    (set_attr "i387_cw" "mask_pm")
18771    (set_attr "mode" "XF")])
18772
18773 (define_insn "frndintxf2_mask_pm_i387"
18774   [(set (match_operand:XF 0 "register_operand" "=f")
18775         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18776          UNSPEC_FRNDINT_MASK_PM))
18777    (use (match_operand:HI 2 "memory_operand" "m"))
18778    (use (match_operand:HI 3 "memory_operand" "m"))]
18779   "TARGET_USE_FANCY_MATH_387
18780    && flag_unsafe_math_optimizations"
18781   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18782   [(set_attr "type" "frndint")
18783    (set_attr "i387_cw" "mask_pm")
18784    (set_attr "mode" "XF")])
18785
18786 (define_expand "nearbyintxf2"
18787   [(use (match_operand:XF 0 "register_operand" ""))
18788    (use (match_operand:XF 1 "register_operand" ""))]
18789   "TARGET_USE_FANCY_MATH_387
18790    && flag_unsafe_math_optimizations"
18791 {
18792   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18793
18794   DONE;
18795 })
18796
18797 (define_expand "nearbyint<mode>2"
18798   [(use (match_operand:MODEF 0 "register_operand" ""))
18799    (use (match_operand:MODEF 1 "register_operand" ""))]
18800   "TARGET_USE_FANCY_MATH_387
18801    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18802        || TARGET_MIX_SSE_I387)
18803    && flag_unsafe_math_optimizations"
18804 {
18805   rtx op0 = gen_reg_rtx (XFmode);
18806   rtx op1 = gen_reg_rtx (XFmode);
18807
18808   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18809   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18810
18811   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18812   DONE;
18813 })
18814
18815 (define_insn "fxam<mode>2_i387"
18816   [(set (match_operand:HI 0 "register_operand" "=a")
18817         (unspec:HI
18818           [(match_operand:X87MODEF 1 "register_operand" "f")]
18819           UNSPEC_FXAM))]
18820   "TARGET_USE_FANCY_MATH_387"
18821   "fxam\n\tfnstsw\t%0"
18822   [(set_attr "type" "multi")
18823    (set_attr "unit" "i387")
18824    (set_attr "mode" "<MODE>")])
18825
18826 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18827   [(set (match_operand:HI 0 "register_operand" "")
18828         (unspec:HI
18829           [(match_operand:MODEF 1 "memory_operand" "")]
18830           UNSPEC_FXAM_MEM))]
18831   "TARGET_USE_FANCY_MATH_387
18832    && !(reload_completed || reload_in_progress)"
18833   "#"
18834   "&& 1"
18835   [(set (match_dup 2)(match_dup 1))
18836    (set (match_dup 0)
18837         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18838 {
18839   operands[2] = gen_reg_rtx (<MODE>mode);
18840
18841   MEM_VOLATILE_P (operands[1]) = 1;
18842 }
18843   [(set_attr "type" "multi")
18844    (set_attr "unit" "i387")
18845    (set_attr "mode" "<MODE>")])
18846
18847 (define_expand "isinfxf2"
18848   [(use (match_operand:SI 0 "register_operand" ""))
18849    (use (match_operand:XF 1 "register_operand" ""))]
18850   "TARGET_USE_FANCY_MATH_387
18851    && TARGET_C99_FUNCTIONS"
18852 {
18853   rtx mask = GEN_INT (0x45);
18854   rtx val = GEN_INT (0x05);
18855
18856   rtx cond;
18857
18858   rtx scratch = gen_reg_rtx (HImode);
18859   rtx res = gen_reg_rtx (QImode);
18860
18861   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18862
18863   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18864   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18865   cond = gen_rtx_fmt_ee (EQ, QImode,
18866                          gen_rtx_REG (CCmode, FLAGS_REG),
18867                          const0_rtx);
18868   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18869   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18870   DONE;
18871 })
18872
18873 (define_expand "isinf<mode>2"
18874   [(use (match_operand:SI 0 "register_operand" ""))
18875    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18876   "TARGET_USE_FANCY_MATH_387
18877    && TARGET_C99_FUNCTIONS
18878    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18879 {
18880   rtx mask = GEN_INT (0x45);
18881   rtx val = GEN_INT (0x05);
18882
18883   rtx cond;
18884
18885   rtx scratch = gen_reg_rtx (HImode);
18886   rtx res = gen_reg_rtx (QImode);
18887
18888   /* Remove excess precision by forcing value through memory. */
18889   if (memory_operand (operands[1], VOIDmode))
18890     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18891   else
18892     {
18893       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18894       rtx temp = assign_386_stack_local (<MODE>mode, slot);
18895
18896       emit_move_insn (temp, operands[1]);
18897       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18898     }
18899
18900   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18901   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18902   cond = gen_rtx_fmt_ee (EQ, QImode,
18903                          gen_rtx_REG (CCmode, FLAGS_REG),
18904                          const0_rtx);
18905   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18906   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18907   DONE;
18908 })
18909
18910 (define_expand "signbit<mode>2"
18911   [(use (match_operand:SI 0 "register_operand" ""))
18912    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18913   "TARGET_USE_FANCY_MATH_387
18914    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18915 {
18916   rtx mask = GEN_INT (0x0200);
18917
18918   rtx scratch = gen_reg_rtx (HImode);
18919
18920   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18921   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18922   DONE;
18923 })
18924 \f
18925 ;; Block operation instructions
18926
18927 (define_insn "cld"
18928   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18929   ""
18930   "cld"
18931   [(set_attr "length" "1")
18932    (set_attr "length_immediate" "0")
18933    (set_attr "modrm" "0")])
18934
18935 (define_expand "movmemsi"
18936   [(use (match_operand:BLK 0 "memory_operand" ""))
18937    (use (match_operand:BLK 1 "memory_operand" ""))
18938    (use (match_operand:SI 2 "nonmemory_operand" ""))
18939    (use (match_operand:SI 3 "const_int_operand" ""))
18940    (use (match_operand:SI 4 "const_int_operand" ""))
18941    (use (match_operand:SI 5 "const_int_operand" ""))]
18942   ""
18943 {
18944  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18945                          operands[4], operands[5]))
18946    DONE;
18947  else
18948    FAIL;
18949 })
18950
18951 (define_expand "movmemdi"
18952   [(use (match_operand:BLK 0 "memory_operand" ""))
18953    (use (match_operand:BLK 1 "memory_operand" ""))
18954    (use (match_operand:DI 2 "nonmemory_operand" ""))
18955    (use (match_operand:DI 3 "const_int_operand" ""))
18956    (use (match_operand:SI 4 "const_int_operand" ""))
18957    (use (match_operand:SI 5 "const_int_operand" ""))]
18958   "TARGET_64BIT"
18959 {
18960  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18961                          operands[4], operands[5]))
18962    DONE;
18963  else
18964    FAIL;
18965 })
18966
18967 ;; Most CPUs don't like single string operations
18968 ;; Handle this case here to simplify previous expander.
18969
18970 (define_expand "strmov"
18971   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18972    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18973    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18974               (clobber (reg:CC FLAGS_REG))])
18975    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18976               (clobber (reg:CC FLAGS_REG))])]
18977   ""
18978 {
18979   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18980
18981   /* If .md ever supports :P for Pmode, these can be directly
18982      in the pattern above.  */
18983   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18984   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18985
18986   /* Can't use this if the user has appropriated esi or edi.  */
18987   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18988       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18989     {
18990       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18991                                       operands[2], operands[3],
18992                                       operands[5], operands[6]));
18993       DONE;
18994     }
18995
18996   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18997 })
18998
18999 (define_expand "strmov_singleop"
19000   [(parallel [(set (match_operand 1 "memory_operand" "")
19001                    (match_operand 3 "memory_operand" ""))
19002               (set (match_operand 0 "register_operand" "")
19003                    (match_operand 4 "" ""))
19004               (set (match_operand 2 "register_operand" "")
19005                    (match_operand 5 "" ""))])]
19006   ""
19007   "ix86_current_function_needs_cld = 1;")
19008
19009 (define_insn "*strmovdi_rex_1"
19010   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19011         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19012    (set (match_operand:DI 0 "register_operand" "=D")
19013         (plus:DI (match_dup 2)
19014                  (const_int 8)))
19015    (set (match_operand:DI 1 "register_operand" "=S")
19016         (plus:DI (match_dup 3)
19017                  (const_int 8)))]
19018   "TARGET_64BIT"
19019   "movsq"
19020   [(set_attr "type" "str")
19021    (set_attr "mode" "DI")
19022    (set_attr "memory" "both")])
19023
19024 (define_insn "*strmovsi_1"
19025   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19026         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19027    (set (match_operand:SI 0 "register_operand" "=D")
19028         (plus:SI (match_dup 2)
19029                  (const_int 4)))
19030    (set (match_operand:SI 1 "register_operand" "=S")
19031         (plus:SI (match_dup 3)
19032                  (const_int 4)))]
19033   "!TARGET_64BIT"
19034   "movs{l|d}"
19035   [(set_attr "type" "str")
19036    (set_attr "mode" "SI")
19037    (set_attr "memory" "both")])
19038
19039 (define_insn "*strmovsi_rex_1"
19040   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19041         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19042    (set (match_operand:DI 0 "register_operand" "=D")
19043         (plus:DI (match_dup 2)
19044                  (const_int 4)))
19045    (set (match_operand:DI 1 "register_operand" "=S")
19046         (plus:DI (match_dup 3)
19047                  (const_int 4)))]
19048   "TARGET_64BIT"
19049   "movs{l|d}"
19050   [(set_attr "type" "str")
19051    (set_attr "mode" "SI")
19052    (set_attr "memory" "both")])
19053
19054 (define_insn "*strmovhi_1"
19055   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19056         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19057    (set (match_operand:SI 0 "register_operand" "=D")
19058         (plus:SI (match_dup 2)
19059                  (const_int 2)))
19060    (set (match_operand:SI 1 "register_operand" "=S")
19061         (plus:SI (match_dup 3)
19062                  (const_int 2)))]
19063   "!TARGET_64BIT"
19064   "movsw"
19065   [(set_attr "type" "str")
19066    (set_attr "memory" "both")
19067    (set_attr "mode" "HI")])
19068
19069 (define_insn "*strmovhi_rex_1"
19070   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19071         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19072    (set (match_operand:DI 0 "register_operand" "=D")
19073         (plus:DI (match_dup 2)
19074                  (const_int 2)))
19075    (set (match_operand:DI 1 "register_operand" "=S")
19076         (plus:DI (match_dup 3)
19077                  (const_int 2)))]
19078   "TARGET_64BIT"
19079   "movsw"
19080   [(set_attr "type" "str")
19081    (set_attr "memory" "both")
19082    (set_attr "mode" "HI")])
19083
19084 (define_insn "*strmovqi_1"
19085   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19086         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19087    (set (match_operand:SI 0 "register_operand" "=D")
19088         (plus:SI (match_dup 2)
19089                  (const_int 1)))
19090    (set (match_operand:SI 1 "register_operand" "=S")
19091         (plus:SI (match_dup 3)
19092                  (const_int 1)))]
19093   "!TARGET_64BIT"
19094   "movsb"
19095   [(set_attr "type" "str")
19096    (set_attr "memory" "both")
19097    (set_attr "mode" "QI")])
19098
19099 (define_insn "*strmovqi_rex_1"
19100   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19101         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19102    (set (match_operand:DI 0 "register_operand" "=D")
19103         (plus:DI (match_dup 2)
19104                  (const_int 1)))
19105    (set (match_operand:DI 1 "register_operand" "=S")
19106         (plus:DI (match_dup 3)
19107                  (const_int 1)))]
19108   "TARGET_64BIT"
19109   "movsb"
19110   [(set_attr "type" "str")
19111    (set_attr "memory" "both")
19112    (set_attr "mode" "QI")])
19113
19114 (define_expand "rep_mov"
19115   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19116               (set (match_operand 0 "register_operand" "")
19117                    (match_operand 5 "" ""))
19118               (set (match_operand 2 "register_operand" "")
19119                    (match_operand 6 "" ""))
19120               (set (match_operand 1 "memory_operand" "")
19121                    (match_operand 3 "memory_operand" ""))
19122               (use (match_dup 4))])]
19123   ""
19124   "ix86_current_function_needs_cld = 1;")
19125
19126 (define_insn "*rep_movdi_rex64"
19127   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19128    (set (match_operand:DI 0 "register_operand" "=D")
19129         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19130                             (const_int 3))
19131                  (match_operand:DI 3 "register_operand" "0")))
19132    (set (match_operand:DI 1 "register_operand" "=S")
19133         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19134                  (match_operand:DI 4 "register_operand" "1")))
19135    (set (mem:BLK (match_dup 3))
19136         (mem:BLK (match_dup 4)))
19137    (use (match_dup 5))]
19138   "TARGET_64BIT"
19139   "rep movsq"
19140   [(set_attr "type" "str")
19141    (set_attr "prefix_rep" "1")
19142    (set_attr "memory" "both")
19143    (set_attr "mode" "DI")])
19144
19145 (define_insn "*rep_movsi"
19146   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19147    (set (match_operand:SI 0 "register_operand" "=D")
19148         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19149                             (const_int 2))
19150                  (match_operand:SI 3 "register_operand" "0")))
19151    (set (match_operand:SI 1 "register_operand" "=S")
19152         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19153                  (match_operand:SI 4 "register_operand" "1")))
19154    (set (mem:BLK (match_dup 3))
19155         (mem:BLK (match_dup 4)))
19156    (use (match_dup 5))]
19157   "!TARGET_64BIT"
19158   "rep movs{l|d}"
19159   [(set_attr "type" "str")
19160    (set_attr "prefix_rep" "1")
19161    (set_attr "memory" "both")
19162    (set_attr "mode" "SI")])
19163
19164 (define_insn "*rep_movsi_rex64"
19165   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19166    (set (match_operand:DI 0 "register_operand" "=D")
19167         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19168                             (const_int 2))
19169                  (match_operand:DI 3 "register_operand" "0")))
19170    (set (match_operand:DI 1 "register_operand" "=S")
19171         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19172                  (match_operand:DI 4 "register_operand" "1")))
19173    (set (mem:BLK (match_dup 3))
19174         (mem:BLK (match_dup 4)))
19175    (use (match_dup 5))]
19176   "TARGET_64BIT"
19177   "rep movs{l|d}"
19178   [(set_attr "type" "str")
19179    (set_attr "prefix_rep" "1")
19180    (set_attr "memory" "both")
19181    (set_attr "mode" "SI")])
19182
19183 (define_insn "*rep_movqi"
19184   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19185    (set (match_operand:SI 0 "register_operand" "=D")
19186         (plus:SI (match_operand:SI 3 "register_operand" "0")
19187                  (match_operand:SI 5 "register_operand" "2")))
19188    (set (match_operand:SI 1 "register_operand" "=S")
19189         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19190    (set (mem:BLK (match_dup 3))
19191         (mem:BLK (match_dup 4)))
19192    (use (match_dup 5))]
19193   "!TARGET_64BIT"
19194   "rep movsb"
19195   [(set_attr "type" "str")
19196    (set_attr "prefix_rep" "1")
19197    (set_attr "memory" "both")
19198    (set_attr "mode" "SI")])
19199
19200 (define_insn "*rep_movqi_rex64"
19201   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19202    (set (match_operand:DI 0 "register_operand" "=D")
19203         (plus:DI (match_operand:DI 3 "register_operand" "0")
19204                  (match_operand:DI 5 "register_operand" "2")))
19205    (set (match_operand:DI 1 "register_operand" "=S")
19206         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19207    (set (mem:BLK (match_dup 3))
19208         (mem:BLK (match_dup 4)))
19209    (use (match_dup 5))]
19210   "TARGET_64BIT"
19211   "rep movsb"
19212   [(set_attr "type" "str")
19213    (set_attr "prefix_rep" "1")
19214    (set_attr "memory" "both")
19215    (set_attr "mode" "SI")])
19216
19217 (define_expand "setmemsi"
19218    [(use (match_operand:BLK 0 "memory_operand" ""))
19219     (use (match_operand:SI 1 "nonmemory_operand" ""))
19220     (use (match_operand 2 "const_int_operand" ""))
19221     (use (match_operand 3 "const_int_operand" ""))
19222     (use (match_operand:SI 4 "const_int_operand" ""))
19223     (use (match_operand:SI 5 "const_int_operand" ""))]
19224   ""
19225 {
19226  if (ix86_expand_setmem (operands[0], operands[1],
19227                          operands[2], operands[3],
19228                          operands[4], operands[5]))
19229    DONE;
19230  else
19231    FAIL;
19232 })
19233
19234 (define_expand "setmemdi"
19235    [(use (match_operand:BLK 0 "memory_operand" ""))
19236     (use (match_operand:DI 1 "nonmemory_operand" ""))
19237     (use (match_operand 2 "const_int_operand" ""))
19238     (use (match_operand 3 "const_int_operand" ""))
19239     (use (match_operand 4 "const_int_operand" ""))
19240     (use (match_operand 5 "const_int_operand" ""))]
19241   "TARGET_64BIT"
19242 {
19243  if (ix86_expand_setmem (operands[0], operands[1],
19244                          operands[2], operands[3],
19245                          operands[4], operands[5]))
19246    DONE;
19247  else
19248    FAIL;
19249 })
19250
19251 ;; Most CPUs don't like single string operations
19252 ;; Handle this case here to simplify previous expander.
19253
19254 (define_expand "strset"
19255   [(set (match_operand 1 "memory_operand" "")
19256         (match_operand 2 "register_operand" ""))
19257    (parallel [(set (match_operand 0 "register_operand" "")
19258                    (match_dup 3))
19259               (clobber (reg:CC FLAGS_REG))])]
19260   ""
19261 {
19262   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19263     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19264
19265   /* If .md ever supports :P for Pmode, this can be directly
19266      in the pattern above.  */
19267   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19268                               GEN_INT (GET_MODE_SIZE (GET_MODE
19269                                                       (operands[2]))));
19270   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19271     {
19272       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19273                                       operands[3]));
19274       DONE;
19275     }
19276 })
19277
19278 (define_expand "strset_singleop"
19279   [(parallel [(set (match_operand 1 "memory_operand" "")
19280                    (match_operand 2 "register_operand" ""))
19281               (set (match_operand 0 "register_operand" "")
19282                    (match_operand 3 "" ""))])]
19283   ""
19284   "ix86_current_function_needs_cld = 1;")
19285
19286 (define_insn "*strsetdi_rex_1"
19287   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19288         (match_operand:DI 2 "register_operand" "a"))
19289    (set (match_operand:DI 0 "register_operand" "=D")
19290         (plus:DI (match_dup 1)
19291                  (const_int 8)))]
19292   "TARGET_64BIT"
19293   "stosq"
19294   [(set_attr "type" "str")
19295    (set_attr "memory" "store")
19296    (set_attr "mode" "DI")])
19297
19298 (define_insn "*strsetsi_1"
19299   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19300         (match_operand:SI 2 "register_operand" "a"))
19301    (set (match_operand:SI 0 "register_operand" "=D")
19302         (plus:SI (match_dup 1)
19303                  (const_int 4)))]
19304   "!TARGET_64BIT"
19305   "stos{l|d}"
19306   [(set_attr "type" "str")
19307    (set_attr "memory" "store")
19308    (set_attr "mode" "SI")])
19309
19310 (define_insn "*strsetsi_rex_1"
19311   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19312         (match_operand:SI 2 "register_operand" "a"))
19313    (set (match_operand:DI 0 "register_operand" "=D")
19314         (plus:DI (match_dup 1)
19315                  (const_int 4)))]
19316   "TARGET_64BIT"
19317   "stos{l|d}"
19318   [(set_attr "type" "str")
19319    (set_attr "memory" "store")
19320    (set_attr "mode" "SI")])
19321
19322 (define_insn "*strsethi_1"
19323   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19324         (match_operand:HI 2 "register_operand" "a"))
19325    (set (match_operand:SI 0 "register_operand" "=D")
19326         (plus:SI (match_dup 1)
19327                  (const_int 2)))]
19328   "!TARGET_64BIT"
19329   "stosw"
19330   [(set_attr "type" "str")
19331    (set_attr "memory" "store")
19332    (set_attr "mode" "HI")])
19333
19334 (define_insn "*strsethi_rex_1"
19335   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19336         (match_operand:HI 2 "register_operand" "a"))
19337    (set (match_operand:DI 0 "register_operand" "=D")
19338         (plus:DI (match_dup 1)
19339                  (const_int 2)))]
19340   "TARGET_64BIT"
19341   "stosw"
19342   [(set_attr "type" "str")
19343    (set_attr "memory" "store")
19344    (set_attr "mode" "HI")])
19345
19346 (define_insn "*strsetqi_1"
19347   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19348         (match_operand:QI 2 "register_operand" "a"))
19349    (set (match_operand:SI 0 "register_operand" "=D")
19350         (plus:SI (match_dup 1)
19351                  (const_int 1)))]
19352   "!TARGET_64BIT"
19353   "stosb"
19354   [(set_attr "type" "str")
19355    (set_attr "memory" "store")
19356    (set_attr "mode" "QI")])
19357
19358 (define_insn "*strsetqi_rex_1"
19359   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19360         (match_operand:QI 2 "register_operand" "a"))
19361    (set (match_operand:DI 0 "register_operand" "=D")
19362         (plus:DI (match_dup 1)
19363                  (const_int 1)))]
19364   "TARGET_64BIT"
19365   "stosb"
19366   [(set_attr "type" "str")
19367    (set_attr "memory" "store")
19368    (set_attr "mode" "QI")])
19369
19370 (define_expand "rep_stos"
19371   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19372               (set (match_operand 0 "register_operand" "")
19373                    (match_operand 4 "" ""))
19374               (set (match_operand 2 "memory_operand" "") (const_int 0))
19375               (use (match_operand 3 "register_operand" ""))
19376               (use (match_dup 1))])]
19377   ""
19378   "ix86_current_function_needs_cld = 1;")
19379
19380 (define_insn "*rep_stosdi_rex64"
19381   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19382    (set (match_operand:DI 0 "register_operand" "=D")
19383         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19384                             (const_int 3))
19385                  (match_operand:DI 3 "register_operand" "0")))
19386    (set (mem:BLK (match_dup 3))
19387         (const_int 0))
19388    (use (match_operand:DI 2 "register_operand" "a"))
19389    (use (match_dup 4))]
19390   "TARGET_64BIT"
19391   "rep stosq"
19392   [(set_attr "type" "str")
19393    (set_attr "prefix_rep" "1")
19394    (set_attr "memory" "store")
19395    (set_attr "mode" "DI")])
19396
19397 (define_insn "*rep_stossi"
19398   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19399    (set (match_operand:SI 0 "register_operand" "=D")
19400         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19401                             (const_int 2))
19402                  (match_operand:SI 3 "register_operand" "0")))
19403    (set (mem:BLK (match_dup 3))
19404         (const_int 0))
19405    (use (match_operand:SI 2 "register_operand" "a"))
19406    (use (match_dup 4))]
19407   "!TARGET_64BIT"
19408   "rep stos{l|d}"
19409   [(set_attr "type" "str")
19410    (set_attr "prefix_rep" "1")
19411    (set_attr "memory" "store")
19412    (set_attr "mode" "SI")])
19413
19414 (define_insn "*rep_stossi_rex64"
19415   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19416    (set (match_operand:DI 0 "register_operand" "=D")
19417         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19418                             (const_int 2))
19419                  (match_operand:DI 3 "register_operand" "0")))
19420    (set (mem:BLK (match_dup 3))
19421         (const_int 0))
19422    (use (match_operand:SI 2 "register_operand" "a"))
19423    (use (match_dup 4))]
19424   "TARGET_64BIT"
19425   "rep stos{l|d}"
19426   [(set_attr "type" "str")
19427    (set_attr "prefix_rep" "1")
19428    (set_attr "memory" "store")
19429    (set_attr "mode" "SI")])
19430
19431 (define_insn "*rep_stosqi"
19432   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19433    (set (match_operand:SI 0 "register_operand" "=D")
19434         (plus:SI (match_operand:SI 3 "register_operand" "0")
19435                  (match_operand:SI 4 "register_operand" "1")))
19436    (set (mem:BLK (match_dup 3))
19437         (const_int 0))
19438    (use (match_operand:QI 2 "register_operand" "a"))
19439    (use (match_dup 4))]
19440   "!TARGET_64BIT"
19441   "rep stosb"
19442   [(set_attr "type" "str")
19443    (set_attr "prefix_rep" "1")
19444    (set_attr "memory" "store")
19445    (set_attr "mode" "QI")])
19446
19447 (define_insn "*rep_stosqi_rex64"
19448   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19449    (set (match_operand:DI 0 "register_operand" "=D")
19450         (plus:DI (match_operand:DI 3 "register_operand" "0")
19451                  (match_operand:DI 4 "register_operand" "1")))
19452    (set (mem:BLK (match_dup 3))
19453         (const_int 0))
19454    (use (match_operand:QI 2 "register_operand" "a"))
19455    (use (match_dup 4))]
19456   "TARGET_64BIT"
19457   "rep stosb"
19458   [(set_attr "type" "str")
19459    (set_attr "prefix_rep" "1")
19460    (set_attr "memory" "store")
19461    (set_attr "mode" "QI")])
19462
19463 (define_expand "cmpstrnsi"
19464   [(set (match_operand:SI 0 "register_operand" "")
19465         (compare:SI (match_operand:BLK 1 "general_operand" "")
19466                     (match_operand:BLK 2 "general_operand" "")))
19467    (use (match_operand 3 "general_operand" ""))
19468    (use (match_operand 4 "immediate_operand" ""))]
19469   ""
19470 {
19471   rtx addr1, addr2, out, outlow, count, countreg, align;
19472
19473   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19474     FAIL;
19475
19476   /* Can't use this if the user has appropriated esi or edi.  */
19477   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19478     FAIL;
19479
19480   out = operands[0];
19481   if (!REG_P (out))
19482     out = gen_reg_rtx (SImode);
19483
19484   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19485   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19486   if (addr1 != XEXP (operands[1], 0))
19487     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19488   if (addr2 != XEXP (operands[2], 0))
19489     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19490
19491   count = operands[3];
19492   countreg = ix86_zero_extend_to_Pmode (count);
19493
19494   /* %%% Iff we are testing strict equality, we can use known alignment
19495      to good advantage.  This may be possible with combine, particularly
19496      once cc0 is dead.  */
19497   align = operands[4];
19498
19499   if (CONST_INT_P (count))
19500     {
19501       if (INTVAL (count) == 0)
19502         {
19503           emit_move_insn (operands[0], const0_rtx);
19504           DONE;
19505         }
19506       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19507                                      operands[1], operands[2]));
19508     }
19509   else
19510     {
19511       if (TARGET_64BIT)
19512         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19513       else
19514         emit_insn (gen_cmpsi_1 (countreg, countreg));
19515       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19516                                   operands[1], operands[2]));
19517     }
19518
19519   outlow = gen_lowpart (QImode, out);
19520   emit_insn (gen_cmpintqi (outlow));
19521   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19522
19523   if (operands[0] != out)
19524     emit_move_insn (operands[0], out);
19525
19526   DONE;
19527 })
19528
19529 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19530
19531 (define_expand "cmpintqi"
19532   [(set (match_dup 1)
19533         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19534    (set (match_dup 2)
19535         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19536    (parallel [(set (match_operand:QI 0 "register_operand" "")
19537                    (minus:QI (match_dup 1)
19538                              (match_dup 2)))
19539               (clobber (reg:CC FLAGS_REG))])]
19540   ""
19541   "operands[1] = gen_reg_rtx (QImode);
19542    operands[2] = gen_reg_rtx (QImode);")
19543
19544 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19545 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19546
19547 (define_expand "cmpstrnqi_nz_1"
19548   [(parallel [(set (reg:CC FLAGS_REG)
19549                    (compare:CC (match_operand 4 "memory_operand" "")
19550                                (match_operand 5 "memory_operand" "")))
19551               (use (match_operand 2 "register_operand" ""))
19552               (use (match_operand:SI 3 "immediate_operand" ""))
19553               (clobber (match_operand 0 "register_operand" ""))
19554               (clobber (match_operand 1 "register_operand" ""))
19555               (clobber (match_dup 2))])]
19556   ""
19557   "ix86_current_function_needs_cld = 1;")
19558
19559 (define_insn "*cmpstrnqi_nz_1"
19560   [(set (reg:CC FLAGS_REG)
19561         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19562                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19563    (use (match_operand:SI 6 "register_operand" "2"))
19564    (use (match_operand:SI 3 "immediate_operand" "i"))
19565    (clobber (match_operand:SI 0 "register_operand" "=S"))
19566    (clobber (match_operand:SI 1 "register_operand" "=D"))
19567    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19568   "!TARGET_64BIT"
19569   "repz cmpsb"
19570   [(set_attr "type" "str")
19571    (set_attr "mode" "QI")
19572    (set_attr "prefix_rep" "1")])
19573
19574 (define_insn "*cmpstrnqi_nz_rex_1"
19575   [(set (reg:CC FLAGS_REG)
19576         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19577                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19578    (use (match_operand:DI 6 "register_operand" "2"))
19579    (use (match_operand:SI 3 "immediate_operand" "i"))
19580    (clobber (match_operand:DI 0 "register_operand" "=S"))
19581    (clobber (match_operand:DI 1 "register_operand" "=D"))
19582    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19583   "TARGET_64BIT"
19584   "repz cmpsb"
19585   [(set_attr "type" "str")
19586    (set_attr "mode" "QI")
19587    (set_attr "prefix_rep" "1")])
19588
19589 ;; The same, but the count is not known to not be zero.
19590
19591 (define_expand "cmpstrnqi_1"
19592   [(parallel [(set (reg:CC FLAGS_REG)
19593                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19594                                      (const_int 0))
19595                   (compare:CC (match_operand 4 "memory_operand" "")
19596                               (match_operand 5 "memory_operand" ""))
19597                   (const_int 0)))
19598               (use (match_operand:SI 3 "immediate_operand" ""))
19599               (use (reg:CC FLAGS_REG))
19600               (clobber (match_operand 0 "register_operand" ""))
19601               (clobber (match_operand 1 "register_operand" ""))
19602               (clobber (match_dup 2))])]
19603   ""
19604   "ix86_current_function_needs_cld = 1;")
19605
19606 (define_insn "*cmpstrnqi_1"
19607   [(set (reg:CC FLAGS_REG)
19608         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19609                              (const_int 0))
19610           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19611                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19612           (const_int 0)))
19613    (use (match_operand:SI 3 "immediate_operand" "i"))
19614    (use (reg:CC FLAGS_REG))
19615    (clobber (match_operand:SI 0 "register_operand" "=S"))
19616    (clobber (match_operand:SI 1 "register_operand" "=D"))
19617    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19618   "!TARGET_64BIT"
19619   "repz cmpsb"
19620   [(set_attr "type" "str")
19621    (set_attr "mode" "QI")
19622    (set_attr "prefix_rep" "1")])
19623
19624 (define_insn "*cmpstrnqi_rex_1"
19625   [(set (reg:CC FLAGS_REG)
19626         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19627                              (const_int 0))
19628           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19629                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19630           (const_int 0)))
19631    (use (match_operand:SI 3 "immediate_operand" "i"))
19632    (use (reg:CC FLAGS_REG))
19633    (clobber (match_operand:DI 0 "register_operand" "=S"))
19634    (clobber (match_operand:DI 1 "register_operand" "=D"))
19635    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19636   "TARGET_64BIT"
19637   "repz cmpsb"
19638   [(set_attr "type" "str")
19639    (set_attr "mode" "QI")
19640    (set_attr "prefix_rep" "1")])
19641
19642 (define_expand "strlensi"
19643   [(set (match_operand:SI 0 "register_operand" "")
19644         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19645                     (match_operand:QI 2 "immediate_operand" "")
19646                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19647   ""
19648 {
19649  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19650    DONE;
19651  else
19652    FAIL;
19653 })
19654
19655 (define_expand "strlendi"
19656   [(set (match_operand:DI 0 "register_operand" "")
19657         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19658                     (match_operand:QI 2 "immediate_operand" "")
19659                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19660   ""
19661 {
19662  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19663    DONE;
19664  else
19665    FAIL;
19666 })
19667
19668 (define_expand "strlenqi_1"
19669   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19670               (clobber (match_operand 1 "register_operand" ""))
19671               (clobber (reg:CC FLAGS_REG))])]
19672   ""
19673   "ix86_current_function_needs_cld = 1;")
19674
19675 (define_insn "*strlenqi_1"
19676   [(set (match_operand:SI 0 "register_operand" "=&c")
19677         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19678                     (match_operand:QI 2 "register_operand" "a")
19679                     (match_operand:SI 3 "immediate_operand" "i")
19680                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19681    (clobber (match_operand:SI 1 "register_operand" "=D"))
19682    (clobber (reg:CC FLAGS_REG))]
19683   "!TARGET_64BIT"
19684   "repnz scasb"
19685   [(set_attr "type" "str")
19686    (set_attr "mode" "QI")
19687    (set_attr "prefix_rep" "1")])
19688
19689 (define_insn "*strlenqi_rex_1"
19690   [(set (match_operand:DI 0 "register_operand" "=&c")
19691         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19692                     (match_operand:QI 2 "register_operand" "a")
19693                     (match_operand:DI 3 "immediate_operand" "i")
19694                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19695    (clobber (match_operand:DI 1 "register_operand" "=D"))
19696    (clobber (reg:CC FLAGS_REG))]
19697   "TARGET_64BIT"
19698   "repnz scasb"
19699   [(set_attr "type" "str")
19700    (set_attr "mode" "QI")
19701    (set_attr "prefix_rep" "1")])
19702
19703 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19704 ;; handled in combine, but it is not currently up to the task.
19705 ;; When used for their truth value, the cmpstrn* expanders generate
19706 ;; code like this:
19707 ;;
19708 ;;   repz cmpsb
19709 ;;   seta       %al
19710 ;;   setb       %dl
19711 ;;   cmpb       %al, %dl
19712 ;;   jcc        label
19713 ;;
19714 ;; The intermediate three instructions are unnecessary.
19715
19716 ;; This one handles cmpstrn*_nz_1...
19717 (define_peephole2
19718   [(parallel[
19719      (set (reg:CC FLAGS_REG)
19720           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19721                       (mem:BLK (match_operand 5 "register_operand" ""))))
19722      (use (match_operand 6 "register_operand" ""))
19723      (use (match_operand:SI 3 "immediate_operand" ""))
19724      (clobber (match_operand 0 "register_operand" ""))
19725      (clobber (match_operand 1 "register_operand" ""))
19726      (clobber (match_operand 2 "register_operand" ""))])
19727    (set (match_operand:QI 7 "register_operand" "")
19728         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19729    (set (match_operand:QI 8 "register_operand" "")
19730         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19731    (set (reg FLAGS_REG)
19732         (compare (match_dup 7) (match_dup 8)))
19733   ]
19734   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19735   [(parallel[
19736      (set (reg:CC FLAGS_REG)
19737           (compare:CC (mem:BLK (match_dup 4))
19738                       (mem:BLK (match_dup 5))))
19739      (use (match_dup 6))
19740      (use (match_dup 3))
19741      (clobber (match_dup 0))
19742      (clobber (match_dup 1))
19743      (clobber (match_dup 2))])]
19744   "")
19745
19746 ;; ...and this one handles cmpstrn*_1.
19747 (define_peephole2
19748   [(parallel[
19749      (set (reg:CC FLAGS_REG)
19750           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19751                                (const_int 0))
19752             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19753                         (mem:BLK (match_operand 5 "register_operand" "")))
19754             (const_int 0)))
19755      (use (match_operand:SI 3 "immediate_operand" ""))
19756      (use (reg:CC FLAGS_REG))
19757      (clobber (match_operand 0 "register_operand" ""))
19758      (clobber (match_operand 1 "register_operand" ""))
19759      (clobber (match_operand 2 "register_operand" ""))])
19760    (set (match_operand:QI 7 "register_operand" "")
19761         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19762    (set (match_operand:QI 8 "register_operand" "")
19763         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19764    (set (reg FLAGS_REG)
19765         (compare (match_dup 7) (match_dup 8)))
19766   ]
19767   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19768   [(parallel[
19769      (set (reg:CC FLAGS_REG)
19770           (if_then_else:CC (ne (match_dup 6)
19771                                (const_int 0))
19772             (compare:CC (mem:BLK (match_dup 4))
19773                         (mem:BLK (match_dup 5)))
19774             (const_int 0)))
19775      (use (match_dup 3))
19776      (use (reg:CC FLAGS_REG))
19777      (clobber (match_dup 0))
19778      (clobber (match_dup 1))
19779      (clobber (match_dup 2))])]
19780   "")
19781
19782
19783 \f
19784 ;; Conditional move instructions.
19785
19786 (define_expand "movdicc"
19787   [(set (match_operand:DI 0 "register_operand" "")
19788         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19789                          (match_operand:DI 2 "general_operand" "")
19790                          (match_operand:DI 3 "general_operand" "")))]
19791   "TARGET_64BIT"
19792   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19793
19794 (define_insn "x86_movdicc_0_m1_rex64"
19795   [(set (match_operand:DI 0 "register_operand" "=r")
19796         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19797           (const_int -1)
19798           (const_int 0)))
19799    (clobber (reg:CC FLAGS_REG))]
19800   "TARGET_64BIT"
19801   "sbb{q}\t%0, %0"
19802   ; Since we don't have the proper number of operands for an alu insn,
19803   ; fill in all the blanks.
19804   [(set_attr "type" "alu")
19805    (set_attr "pent_pair" "pu")
19806    (set_attr "memory" "none")
19807    (set_attr "imm_disp" "false")
19808    (set_attr "mode" "DI")
19809    (set_attr "length_immediate" "0")])
19810
19811 (define_insn "*x86_movdicc_0_m1_se"
19812   [(set (match_operand:DI 0 "register_operand" "=r")
19813         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19814                          (const_int 1)
19815                          (const_int 0)))
19816    (clobber (reg:CC FLAGS_REG))]
19817   ""
19818   "sbb{q}\t%0, %0"
19819   [(set_attr "type" "alu")
19820    (set_attr "pent_pair" "pu")
19821    (set_attr "memory" "none")
19822    (set_attr "imm_disp" "false")
19823    (set_attr "mode" "DI")
19824    (set_attr "length_immediate" "0")])
19825
19826 (define_insn "*movdicc_c_rex64"
19827   [(set (match_operand:DI 0 "register_operand" "=r,r")
19828         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19829                                 [(reg FLAGS_REG) (const_int 0)])
19830                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19831                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19832   "TARGET_64BIT && TARGET_CMOVE
19833    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19834   "@
19835    cmov%O2%C1\t{%2, %0|%0, %2}
19836    cmov%O2%c1\t{%3, %0|%0, %3}"
19837   [(set_attr "type" "icmov")
19838    (set_attr "mode" "DI")])
19839
19840 (define_expand "movsicc"
19841   [(set (match_operand:SI 0 "register_operand" "")
19842         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19843                          (match_operand:SI 2 "general_operand" "")
19844                          (match_operand:SI 3 "general_operand" "")))]
19845   ""
19846   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19847
19848 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19849 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19850 ;; So just document what we're doing explicitly.
19851
19852 (define_insn "x86_movsicc_0_m1"
19853   [(set (match_operand:SI 0 "register_operand" "=r")
19854         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19855           (const_int -1)
19856           (const_int 0)))
19857    (clobber (reg:CC FLAGS_REG))]
19858   ""
19859   "sbb{l}\t%0, %0"
19860   ; Since we don't have the proper number of operands for an alu insn,
19861   ; fill in all the blanks.
19862   [(set_attr "type" "alu")
19863    (set_attr "pent_pair" "pu")
19864    (set_attr "memory" "none")
19865    (set_attr "imm_disp" "false")
19866    (set_attr "mode" "SI")
19867    (set_attr "length_immediate" "0")])
19868
19869 (define_insn "*x86_movsicc_0_m1_se"
19870   [(set (match_operand:SI 0 "register_operand" "=r")
19871         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19872                          (const_int 1)
19873                          (const_int 0)))
19874    (clobber (reg:CC FLAGS_REG))]
19875   ""
19876   "sbb{l}\t%0, %0"
19877   [(set_attr "type" "alu")
19878    (set_attr "pent_pair" "pu")
19879    (set_attr "memory" "none")
19880    (set_attr "imm_disp" "false")
19881    (set_attr "mode" "SI")
19882    (set_attr "length_immediate" "0")])
19883
19884 (define_insn "*movsicc_noc"
19885   [(set (match_operand:SI 0 "register_operand" "=r,r")
19886         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19887                                 [(reg FLAGS_REG) (const_int 0)])
19888                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19889                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19890   "TARGET_CMOVE
19891    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19892   "@
19893    cmov%O2%C1\t{%2, %0|%0, %2}
19894    cmov%O2%c1\t{%3, %0|%0, %3}"
19895   [(set_attr "type" "icmov")
19896    (set_attr "mode" "SI")])
19897
19898 (define_expand "movhicc"
19899   [(set (match_operand:HI 0 "register_operand" "")
19900         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19901                          (match_operand:HI 2 "general_operand" "")
19902                          (match_operand:HI 3 "general_operand" "")))]
19903   "TARGET_HIMODE_MATH"
19904   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19905
19906 (define_insn "*movhicc_noc"
19907   [(set (match_operand:HI 0 "register_operand" "=r,r")
19908         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19909                                 [(reg FLAGS_REG) (const_int 0)])
19910                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19911                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19912   "TARGET_CMOVE
19913    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19914   "@
19915    cmov%O2%C1\t{%2, %0|%0, %2}
19916    cmov%O2%c1\t{%3, %0|%0, %3}"
19917   [(set_attr "type" "icmov")
19918    (set_attr "mode" "HI")])
19919
19920 (define_expand "movqicc"
19921   [(set (match_operand:QI 0 "register_operand" "")
19922         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19923                          (match_operand:QI 2 "general_operand" "")
19924                          (match_operand:QI 3 "general_operand" "")))]
19925   "TARGET_QIMODE_MATH"
19926   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19927
19928 (define_insn_and_split "*movqicc_noc"
19929   [(set (match_operand:QI 0 "register_operand" "=r,r")
19930         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19931                                 [(match_operand 4 "flags_reg_operand" "")
19932                                  (const_int 0)])
19933                       (match_operand:QI 2 "register_operand" "r,0")
19934                       (match_operand:QI 3 "register_operand" "0,r")))]
19935   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19936   "#"
19937   "&& reload_completed"
19938   [(set (match_dup 0)
19939         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19940                       (match_dup 2)
19941                       (match_dup 3)))]
19942   "operands[0] = gen_lowpart (SImode, operands[0]);
19943    operands[2] = gen_lowpart (SImode, operands[2]);
19944    operands[3] = gen_lowpart (SImode, operands[3]);"
19945   [(set_attr "type" "icmov")
19946    (set_attr "mode" "SI")])
19947
19948 (define_expand "mov<mode>cc"
19949   [(set (match_operand:X87MODEF 0 "register_operand" "")
19950         (if_then_else:X87MODEF
19951           (match_operand 1 "comparison_operator" "")
19952           (match_operand:X87MODEF 2 "register_operand" "")
19953           (match_operand:X87MODEF 3 "register_operand" "")))]
19954   "(TARGET_80387 && TARGET_CMOVE)
19955    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19956   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19957
19958 (define_insn "*movsfcc_1_387"
19959   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19960         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19961                                 [(reg FLAGS_REG) (const_int 0)])
19962                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19963                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19964   "TARGET_80387 && TARGET_CMOVE
19965    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19966   "@
19967    fcmov%F1\t{%2, %0|%0, %2}
19968    fcmov%f1\t{%3, %0|%0, %3}
19969    cmov%O2%C1\t{%2, %0|%0, %2}
19970    cmov%O2%c1\t{%3, %0|%0, %3}"
19971   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19972    (set_attr "mode" "SF,SF,SI,SI")])
19973
19974 (define_insn "*movdfcc_1"
19975   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19976         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19977                                 [(reg FLAGS_REG) (const_int 0)])
19978                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19979                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19980   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19981    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19982   "@
19983    fcmov%F1\t{%2, %0|%0, %2}
19984    fcmov%f1\t{%3, %0|%0, %3}
19985    #
19986    #"
19987   [(set_attr "type" "fcmov,fcmov,multi,multi")
19988    (set_attr "mode" "DF")])
19989
19990 (define_insn "*movdfcc_1_rex64"
19991   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19992         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19993                                 [(reg FLAGS_REG) (const_int 0)])
19994                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19995                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19996   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19997    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19998   "@
19999    fcmov%F1\t{%2, %0|%0, %2}
20000    fcmov%f1\t{%3, %0|%0, %3}
20001    cmov%O2%C1\t{%2, %0|%0, %2}
20002    cmov%O2%c1\t{%3, %0|%0, %3}"
20003   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20004    (set_attr "mode" "DF")])
20005
20006 (define_split
20007   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20008         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20009                                 [(match_operand 4 "flags_reg_operand" "")
20010                                  (const_int 0)])
20011                       (match_operand:DF 2 "nonimmediate_operand" "")
20012                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20013   "!TARGET_64BIT && reload_completed"
20014   [(set (match_dup 2)
20015         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20016                       (match_dup 5)
20017                       (match_dup 6)))
20018    (set (match_dup 3)
20019         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20020                       (match_dup 7)
20021                       (match_dup 8)))]
20022   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20023    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20024
20025 (define_insn "*movxfcc_1"
20026   [(set (match_operand:XF 0 "register_operand" "=f,f")
20027         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20028                                 [(reg FLAGS_REG) (const_int 0)])
20029                       (match_operand:XF 2 "register_operand" "f,0")
20030                       (match_operand:XF 3 "register_operand" "0,f")))]
20031   "TARGET_80387 && TARGET_CMOVE"
20032   "@
20033    fcmov%F1\t{%2, %0|%0, %2}
20034    fcmov%f1\t{%3, %0|%0, %3}"
20035   [(set_attr "type" "fcmov")
20036    (set_attr "mode" "XF")])
20037
20038 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20039 ;; the scalar versions to have only XMM registers as operands.
20040
20041 ;; SSE5 conditional move
20042 (define_insn "*sse5_pcmov_<mode>"
20043   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20044         (if_then_else:MODEF
20045           (match_operand:MODEF 1 "register_operand" "x,0")
20046           (match_operand:MODEF 2 "register_operand" "0,x")
20047           (match_operand:MODEF 3 "register_operand" "x,x")))]
20048   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20049   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20050   [(set_attr "type" "sse4arg")])
20051
20052 ;; These versions of the min/max patterns are intentionally ignorant of
20053 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20054 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20055 ;; are undefined in this condition, we're certain this is correct.
20056
20057 (define_insn "*avx_<code><mode>3"
20058   [(set (match_operand:MODEF 0 "register_operand" "=x")
20059         (smaxmin:MODEF
20060           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20061           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20062   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20063   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20064   [(set_attr "type" "sseadd")
20065    (set_attr "prefix" "vex")
20066    (set_attr "mode" "<MODE>")])
20067
20068 (define_insn "<code><mode>3"
20069   [(set (match_operand:MODEF 0 "register_operand" "=x")
20070         (smaxmin:MODEF
20071           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20072           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20073   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20074   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20075   [(set_attr "type" "sseadd")
20076    (set_attr "mode" "<MODE>")])
20077
20078 ;; These versions of the min/max patterns implement exactly the operations
20079 ;;   min = (op1 < op2 ? op1 : op2)
20080 ;;   max = (!(op1 < op2) ? op1 : op2)
20081 ;; Their operands are not commutative, and thus they may be used in the
20082 ;; presence of -0.0 and NaN.
20083
20084 (define_insn "*avx_ieee_smin<mode>3"
20085   [(set (match_operand:MODEF 0 "register_operand" "=x")
20086         (unspec:MODEF
20087           [(match_operand:MODEF 1 "register_operand" "x")
20088            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20089          UNSPEC_IEEE_MIN))]
20090   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20091   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20092   [(set_attr "type" "sseadd")
20093    (set_attr "prefix" "vex")
20094    (set_attr "mode" "<MODE>")])
20095
20096 (define_insn "*ieee_smin<mode>3"
20097   [(set (match_operand:MODEF 0 "register_operand" "=x")
20098         (unspec:MODEF
20099           [(match_operand:MODEF 1 "register_operand" "0")
20100            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20101          UNSPEC_IEEE_MIN))]
20102   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20103   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20104   [(set_attr "type" "sseadd")
20105    (set_attr "mode" "<MODE>")])
20106
20107 (define_insn "*avx_ieee_smax<mode>3"
20108   [(set (match_operand:MODEF 0 "register_operand" "=x")
20109         (unspec:MODEF
20110           [(match_operand:MODEF 1 "register_operand" "0")
20111            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20112          UNSPEC_IEEE_MAX))]
20113   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20114   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20115   [(set_attr "type" "sseadd")
20116    (set_attr "prefix" "vex")
20117    (set_attr "mode" "<MODE>")])
20118
20119 (define_insn "*ieee_smax<mode>3"
20120   [(set (match_operand:MODEF 0 "register_operand" "=x")
20121         (unspec:MODEF
20122           [(match_operand:MODEF 1 "register_operand" "0")
20123            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20124          UNSPEC_IEEE_MAX))]
20125   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20126   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20127   [(set_attr "type" "sseadd")
20128    (set_attr "mode" "<MODE>")])
20129
20130 ;; Make two stack loads independent:
20131 ;;   fld aa              fld aa
20132 ;;   fld %st(0)     ->   fld bb
20133 ;;   fmul bb             fmul %st(1), %st
20134 ;;
20135 ;; Actually we only match the last two instructions for simplicity.
20136 (define_peephole2
20137   [(set (match_operand 0 "fp_register_operand" "")
20138         (match_operand 1 "fp_register_operand" ""))
20139    (set (match_dup 0)
20140         (match_operator 2 "binary_fp_operator"
20141            [(match_dup 0)
20142             (match_operand 3 "memory_operand" "")]))]
20143   "REGNO (operands[0]) != REGNO (operands[1])"
20144   [(set (match_dup 0) (match_dup 3))
20145    (set (match_dup 0) (match_dup 4))]
20146
20147   ;; The % modifier is not operational anymore in peephole2's, so we have to
20148   ;; swap the operands manually in the case of addition and multiplication.
20149   "if (COMMUTATIVE_ARITH_P (operands[2]))
20150      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20151                                  operands[0], operands[1]);
20152    else
20153      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20154                                  operands[1], operands[0]);")
20155
20156 ;; Conditional addition patterns
20157 (define_expand "add<mode>cc"
20158   [(match_operand:SWI 0 "register_operand" "")
20159    (match_operand 1 "comparison_operator" "")
20160    (match_operand:SWI 2 "register_operand" "")
20161    (match_operand:SWI 3 "const_int_operand" "")]
20162   ""
20163   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20164
20165 \f
20166 ;; Misc patterns (?)
20167
20168 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20169 ;; Otherwise there will be nothing to keep
20170 ;;
20171 ;; [(set (reg ebp) (reg esp))]
20172 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20173 ;;  (clobber (eflags)]
20174 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20175 ;;
20176 ;; in proper program order.
20177 (define_insn "pro_epilogue_adjust_stack_1"
20178   [(set (match_operand:SI 0 "register_operand" "=r,r")
20179         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20180                  (match_operand:SI 2 "immediate_operand" "i,i")))
20181    (clobber (reg:CC FLAGS_REG))
20182    (clobber (mem:BLK (scratch)))]
20183   "!TARGET_64BIT"
20184 {
20185   switch (get_attr_type (insn))
20186     {
20187     case TYPE_IMOV:
20188       return "mov{l}\t{%1, %0|%0, %1}";
20189
20190     case TYPE_ALU:
20191       if (CONST_INT_P (operands[2])
20192           && (INTVAL (operands[2]) == 128
20193               || (INTVAL (operands[2]) < 0
20194                   && INTVAL (operands[2]) != -128)))
20195         {
20196           operands[2] = GEN_INT (-INTVAL (operands[2]));
20197           return "sub{l}\t{%2, %0|%0, %2}";
20198         }
20199       return "add{l}\t{%2, %0|%0, %2}";
20200
20201     case TYPE_LEA:
20202       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20203       return "lea{l}\t{%a2, %0|%0, %a2}";
20204
20205     default:
20206       gcc_unreachable ();
20207     }
20208 }
20209   [(set (attr "type")
20210         (cond [(eq_attr "alternative" "0")
20211                  (const_string "alu")
20212                (match_operand:SI 2 "const0_operand" "")
20213                  (const_string "imov")
20214               ]
20215               (const_string "lea")))
20216    (set_attr "mode" "SI")])
20217
20218 (define_insn "pro_epilogue_adjust_stack_rex64"
20219   [(set (match_operand:DI 0 "register_operand" "=r,r")
20220         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20221                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20222    (clobber (reg:CC FLAGS_REG))
20223    (clobber (mem:BLK (scratch)))]
20224   "TARGET_64BIT"
20225 {
20226   switch (get_attr_type (insn))
20227     {
20228     case TYPE_IMOV:
20229       return "mov{q}\t{%1, %0|%0, %1}";
20230
20231     case TYPE_ALU:
20232       if (CONST_INT_P (operands[2])
20233           /* Avoid overflows.  */
20234           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20235           && (INTVAL (operands[2]) == 128
20236               || (INTVAL (operands[2]) < 0
20237                   && INTVAL (operands[2]) != -128)))
20238         {
20239           operands[2] = GEN_INT (-INTVAL (operands[2]));
20240           return "sub{q}\t{%2, %0|%0, %2}";
20241         }
20242       return "add{q}\t{%2, %0|%0, %2}";
20243
20244     case TYPE_LEA:
20245       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20246       return "lea{q}\t{%a2, %0|%0, %a2}";
20247
20248     default:
20249       gcc_unreachable ();
20250     }
20251 }
20252   [(set (attr "type")
20253         (cond [(eq_attr "alternative" "0")
20254                  (const_string "alu")
20255                (match_operand:DI 2 "const0_operand" "")
20256                  (const_string "imov")
20257               ]
20258               (const_string "lea")))
20259    (set_attr "mode" "DI")])
20260
20261 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20262   [(set (match_operand:DI 0 "register_operand" "=r,r")
20263         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20264                  (match_operand:DI 3 "immediate_operand" "i,i")))
20265    (use (match_operand:DI 2 "register_operand" "r,r"))
20266    (clobber (reg:CC FLAGS_REG))
20267    (clobber (mem:BLK (scratch)))]
20268   "TARGET_64BIT"
20269 {
20270   switch (get_attr_type (insn))
20271     {
20272     case TYPE_ALU:
20273       return "add{q}\t{%2, %0|%0, %2}";
20274
20275     case TYPE_LEA:
20276       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20277       return "lea{q}\t{%a2, %0|%0, %a2}";
20278
20279     default:
20280       gcc_unreachable ();
20281     }
20282 }
20283   [(set_attr "type" "alu,lea")
20284    (set_attr "mode" "DI")])
20285
20286 (define_insn "allocate_stack_worker_32"
20287   [(set (match_operand:SI 0 "register_operand" "=a")
20288         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20289                             UNSPECV_STACK_PROBE))
20290    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20291    (clobber (reg:CC FLAGS_REG))]
20292   "!TARGET_64BIT && TARGET_STACK_PROBE"
20293   "call\t___chkstk"
20294   [(set_attr "type" "multi")
20295    (set_attr "length" "5")])
20296
20297 (define_insn "allocate_stack_worker_64"
20298   [(set (match_operand:DI 0 "register_operand" "=a")
20299         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20300                             UNSPECV_STACK_PROBE))
20301    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20302    (clobber (reg:DI R10_REG))
20303    (clobber (reg:DI R11_REG))
20304    (clobber (reg:CC FLAGS_REG))]
20305   "TARGET_64BIT && TARGET_STACK_PROBE"
20306   "call\t___chkstk"
20307   [(set_attr "type" "multi")
20308    (set_attr "length" "5")])
20309
20310 (define_expand "allocate_stack"
20311   [(match_operand 0 "register_operand" "")
20312    (match_operand 1 "general_operand" "")]
20313   "TARGET_STACK_PROBE"
20314 {
20315   rtx x;
20316
20317 #ifndef CHECK_STACK_LIMIT
20318 #define CHECK_STACK_LIMIT 0
20319 #endif
20320
20321   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20322       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20323     {
20324       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20325                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20326       if (x != stack_pointer_rtx)
20327         emit_move_insn (stack_pointer_rtx, x);
20328     }
20329   else
20330     {
20331       x = copy_to_mode_reg (Pmode, operands[1]);
20332       if (TARGET_64BIT)
20333         x = gen_allocate_stack_worker_64 (x, x);
20334       else
20335         x = gen_allocate_stack_worker_32 (x, x);
20336       emit_insn (x);
20337     }
20338
20339   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20340   DONE;
20341 })
20342
20343 (define_expand "builtin_setjmp_receiver"
20344   [(label_ref (match_operand 0 "" ""))]
20345   "!TARGET_64BIT && flag_pic"
20346 {
20347 #if TARGET_MACHO
20348   if (TARGET_MACHO)
20349     {
20350       rtx xops[3];
20351       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20352       rtx label_rtx = gen_label_rtx ();
20353       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20354       xops[0] = xops[1] = picreg;
20355       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20356       ix86_expand_binary_operator (MINUS, SImode, xops);
20357     }
20358   else
20359 #endif
20360     emit_insn (gen_set_got (pic_offset_table_rtx));
20361   DONE;
20362 })
20363 \f
20364 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20365
20366 (define_split
20367   [(set (match_operand 0 "register_operand" "")
20368         (match_operator 3 "promotable_binary_operator"
20369            [(match_operand 1 "register_operand" "")
20370             (match_operand 2 "aligned_operand" "")]))
20371    (clobber (reg:CC FLAGS_REG))]
20372   "! TARGET_PARTIAL_REG_STALL && reload_completed
20373    && ((GET_MODE (operands[0]) == HImode
20374         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20375             /* ??? next two lines just !satisfies_constraint_K (...) */
20376             || !CONST_INT_P (operands[2])
20377             || satisfies_constraint_K (operands[2])))
20378        || (GET_MODE (operands[0]) == QImode
20379            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20380   [(parallel [(set (match_dup 0)
20381                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20382               (clobber (reg:CC FLAGS_REG))])]
20383   "operands[0] = gen_lowpart (SImode, operands[0]);
20384    operands[1] = gen_lowpart (SImode, operands[1]);
20385    if (GET_CODE (operands[3]) != ASHIFT)
20386      operands[2] = gen_lowpart (SImode, operands[2]);
20387    PUT_MODE (operands[3], SImode);")
20388
20389 ; Promote the QImode tests, as i386 has encoding of the AND
20390 ; instruction with 32-bit sign-extended immediate and thus the
20391 ; instruction size is unchanged, except in the %eax case for
20392 ; which it is increased by one byte, hence the ! optimize_size.
20393 (define_split
20394   [(set (match_operand 0 "flags_reg_operand" "")
20395         (match_operator 2 "compare_operator"
20396           [(and (match_operand 3 "aligned_operand" "")
20397                 (match_operand 4 "const_int_operand" ""))
20398            (const_int 0)]))
20399    (set (match_operand 1 "register_operand" "")
20400         (and (match_dup 3) (match_dup 4)))]
20401   "! TARGET_PARTIAL_REG_STALL && reload_completed
20402    && optimize_insn_for_speed_p ()
20403    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20404        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20405    /* Ensure that the operand will remain sign-extended immediate.  */
20406    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20407   [(parallel [(set (match_dup 0)
20408                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20409                                     (const_int 0)]))
20410               (set (match_dup 1)
20411                    (and:SI (match_dup 3) (match_dup 4)))])]
20412 {
20413   operands[4]
20414     = gen_int_mode (INTVAL (operands[4])
20415                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20416   operands[1] = gen_lowpart (SImode, operands[1]);
20417   operands[3] = gen_lowpart (SImode, operands[3]);
20418 })
20419
20420 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20421 ; the TEST instruction with 32-bit sign-extended immediate and thus
20422 ; the instruction size would at least double, which is not what we
20423 ; want even with ! optimize_size.
20424 (define_split
20425   [(set (match_operand 0 "flags_reg_operand" "")
20426         (match_operator 1 "compare_operator"
20427           [(and (match_operand:HI 2 "aligned_operand" "")
20428                 (match_operand:HI 3 "const_int_operand" ""))
20429            (const_int 0)]))]
20430   "! TARGET_PARTIAL_REG_STALL && reload_completed
20431    && ! TARGET_FAST_PREFIX
20432    && optimize_insn_for_speed_p ()
20433    /* Ensure that the operand will remain sign-extended immediate.  */
20434    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20435   [(set (match_dup 0)
20436         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20437                          (const_int 0)]))]
20438 {
20439   operands[3]
20440     = gen_int_mode (INTVAL (operands[3])
20441                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20442   operands[2] = gen_lowpart (SImode, operands[2]);
20443 })
20444
20445 (define_split
20446   [(set (match_operand 0 "register_operand" "")
20447         (neg (match_operand 1 "register_operand" "")))
20448    (clobber (reg:CC FLAGS_REG))]
20449   "! TARGET_PARTIAL_REG_STALL && reload_completed
20450    && (GET_MODE (operands[0]) == HImode
20451        || (GET_MODE (operands[0]) == QImode
20452            && (TARGET_PROMOTE_QImode
20453                || optimize_insn_for_size_p ())))"
20454   [(parallel [(set (match_dup 0)
20455                    (neg:SI (match_dup 1)))
20456               (clobber (reg:CC FLAGS_REG))])]
20457   "operands[0] = gen_lowpart (SImode, operands[0]);
20458    operands[1] = gen_lowpart (SImode, operands[1]);")
20459
20460 (define_split
20461   [(set (match_operand 0 "register_operand" "")
20462         (not (match_operand 1 "register_operand" "")))]
20463   "! TARGET_PARTIAL_REG_STALL && reload_completed
20464    && (GET_MODE (operands[0]) == HImode
20465        || (GET_MODE (operands[0]) == QImode
20466            && (TARGET_PROMOTE_QImode
20467                || optimize_insn_for_size_p ())))"
20468   [(set (match_dup 0)
20469         (not:SI (match_dup 1)))]
20470   "operands[0] = gen_lowpart (SImode, operands[0]);
20471    operands[1] = gen_lowpart (SImode, operands[1]);")
20472
20473 (define_split
20474   [(set (match_operand 0 "register_operand" "")
20475         (if_then_else (match_operator 1 "comparison_operator"
20476                                 [(reg FLAGS_REG) (const_int 0)])
20477                       (match_operand 2 "register_operand" "")
20478                       (match_operand 3 "register_operand" "")))]
20479   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20480    && (GET_MODE (operands[0]) == HImode
20481        || (GET_MODE (operands[0]) == QImode
20482            && (TARGET_PROMOTE_QImode
20483                || optimize_insn_for_size_p ())))"
20484   [(set (match_dup 0)
20485         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20486   "operands[0] = gen_lowpart (SImode, operands[0]);
20487    operands[2] = gen_lowpart (SImode, operands[2]);
20488    operands[3] = gen_lowpart (SImode, operands[3]);")
20489
20490 \f
20491 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20492 ;; transform a complex memory operation into two memory to register operations.
20493
20494 ;; Don't push memory operands
20495 (define_peephole2
20496   [(set (match_operand:SI 0 "push_operand" "")
20497         (match_operand:SI 1 "memory_operand" ""))
20498    (match_scratch:SI 2 "r")]
20499   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20500    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20501   [(set (match_dup 2) (match_dup 1))
20502    (set (match_dup 0) (match_dup 2))]
20503   "")
20504
20505 (define_peephole2
20506   [(set (match_operand:DI 0 "push_operand" "")
20507         (match_operand:DI 1 "memory_operand" ""))
20508    (match_scratch:DI 2 "r")]
20509   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20510    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20511   [(set (match_dup 2) (match_dup 1))
20512    (set (match_dup 0) (match_dup 2))]
20513   "")
20514
20515 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20516 ;; SImode pushes.
20517 (define_peephole2
20518   [(set (match_operand:SF 0 "push_operand" "")
20519         (match_operand:SF 1 "memory_operand" ""))
20520    (match_scratch:SF 2 "r")]
20521   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20522    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20523   [(set (match_dup 2) (match_dup 1))
20524    (set (match_dup 0) (match_dup 2))]
20525   "")
20526
20527 (define_peephole2
20528   [(set (match_operand:HI 0 "push_operand" "")
20529         (match_operand:HI 1 "memory_operand" ""))
20530    (match_scratch:HI 2 "r")]
20531   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20532    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20533   [(set (match_dup 2) (match_dup 1))
20534    (set (match_dup 0) (match_dup 2))]
20535   "")
20536
20537 (define_peephole2
20538   [(set (match_operand:QI 0 "push_operand" "")
20539         (match_operand:QI 1 "memory_operand" ""))
20540    (match_scratch:QI 2 "q")]
20541   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20542    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20543   [(set (match_dup 2) (match_dup 1))
20544    (set (match_dup 0) (match_dup 2))]
20545   "")
20546
20547 ;; Don't move an immediate directly to memory when the instruction
20548 ;; gets too big.
20549 (define_peephole2
20550   [(match_scratch:SI 1 "r")
20551    (set (match_operand:SI 0 "memory_operand" "")
20552         (const_int 0))]
20553   "optimize_insn_for_speed_p ()
20554    && ! TARGET_USE_MOV0
20555    && TARGET_SPLIT_LONG_MOVES
20556    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20557    && peep2_regno_dead_p (0, FLAGS_REG)"
20558   [(parallel [(set (match_dup 1) (const_int 0))
20559               (clobber (reg:CC FLAGS_REG))])
20560    (set (match_dup 0) (match_dup 1))]
20561   "")
20562
20563 (define_peephole2
20564   [(match_scratch:HI 1 "r")
20565    (set (match_operand:HI 0 "memory_operand" "")
20566         (const_int 0))]
20567   "optimize_insn_for_speed_p ()
20568    && ! TARGET_USE_MOV0
20569    && TARGET_SPLIT_LONG_MOVES
20570    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20571    && peep2_regno_dead_p (0, FLAGS_REG)"
20572   [(parallel [(set (match_dup 2) (const_int 0))
20573               (clobber (reg:CC FLAGS_REG))])
20574    (set (match_dup 0) (match_dup 1))]
20575   "operands[2] = gen_lowpart (SImode, operands[1]);")
20576
20577 (define_peephole2
20578   [(match_scratch:QI 1 "q")
20579    (set (match_operand:QI 0 "memory_operand" "")
20580         (const_int 0))]
20581   "optimize_insn_for_speed_p ()
20582    && ! TARGET_USE_MOV0
20583    && TARGET_SPLIT_LONG_MOVES
20584    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20585    && peep2_regno_dead_p (0, FLAGS_REG)"
20586   [(parallel [(set (match_dup 2) (const_int 0))
20587               (clobber (reg:CC FLAGS_REG))])
20588    (set (match_dup 0) (match_dup 1))]
20589   "operands[2] = gen_lowpart (SImode, operands[1]);")
20590
20591 (define_peephole2
20592   [(match_scratch:SI 2 "r")
20593    (set (match_operand:SI 0 "memory_operand" "")
20594         (match_operand:SI 1 "immediate_operand" ""))]
20595   "optimize_insn_for_speed_p ()
20596    && TARGET_SPLIT_LONG_MOVES
20597    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20598   [(set (match_dup 2) (match_dup 1))
20599    (set (match_dup 0) (match_dup 2))]
20600   "")
20601
20602 (define_peephole2
20603   [(match_scratch:HI 2 "r")
20604    (set (match_operand:HI 0 "memory_operand" "")
20605         (match_operand:HI 1 "immediate_operand" ""))]
20606   "optimize_insn_for_speed_p ()
20607    && TARGET_SPLIT_LONG_MOVES
20608    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20609   [(set (match_dup 2) (match_dup 1))
20610    (set (match_dup 0) (match_dup 2))]
20611   "")
20612
20613 (define_peephole2
20614   [(match_scratch:QI 2 "q")
20615    (set (match_operand:QI 0 "memory_operand" "")
20616         (match_operand:QI 1 "immediate_operand" ""))]
20617   "optimize_insn_for_speed_p ()
20618    && TARGET_SPLIT_LONG_MOVES
20619    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20620   [(set (match_dup 2) (match_dup 1))
20621    (set (match_dup 0) (match_dup 2))]
20622   "")
20623
20624 ;; Don't compare memory with zero, load and use a test instead.
20625 (define_peephole2
20626   [(set (match_operand 0 "flags_reg_operand" "")
20627         (match_operator 1 "compare_operator"
20628           [(match_operand:SI 2 "memory_operand" "")
20629            (const_int 0)]))
20630    (match_scratch:SI 3 "r")]
20631   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20632   [(set (match_dup 3) (match_dup 2))
20633    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20634   "")
20635
20636 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20637 ;; Don't split NOTs with a displacement operand, because resulting XOR
20638 ;; will not be pairable anyway.
20639 ;;
20640 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20641 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20642 ;; so this split helps here as well.
20643 ;;
20644 ;; Note: Can't do this as a regular split because we can't get proper
20645 ;; lifetime information then.
20646
20647 (define_peephole2
20648   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20649         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20650   "optimize_insn_for_speed_p ()
20651    && ((TARGET_NOT_UNPAIRABLE
20652         && (!MEM_P (operands[0])
20653             || !memory_displacement_operand (operands[0], SImode)))
20654        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20655    && peep2_regno_dead_p (0, FLAGS_REG)"
20656   [(parallel [(set (match_dup 0)
20657                    (xor:SI (match_dup 1) (const_int -1)))
20658               (clobber (reg:CC FLAGS_REG))])]
20659   "")
20660
20661 (define_peephole2
20662   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20663         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20664   "optimize_insn_for_speed_p ()
20665    && ((TARGET_NOT_UNPAIRABLE
20666         && (!MEM_P (operands[0])
20667             || !memory_displacement_operand (operands[0], HImode)))
20668        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20669    && peep2_regno_dead_p (0, FLAGS_REG)"
20670   [(parallel [(set (match_dup 0)
20671                    (xor:HI (match_dup 1) (const_int -1)))
20672               (clobber (reg:CC FLAGS_REG))])]
20673   "")
20674
20675 (define_peephole2
20676   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20677         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20678   "optimize_insn_for_speed_p ()
20679    && ((TARGET_NOT_UNPAIRABLE
20680         && (!MEM_P (operands[0])
20681             || !memory_displacement_operand (operands[0], QImode)))
20682        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20683    && peep2_regno_dead_p (0, FLAGS_REG)"
20684   [(parallel [(set (match_dup 0)
20685                    (xor:QI (match_dup 1) (const_int -1)))
20686               (clobber (reg:CC FLAGS_REG))])]
20687   "")
20688
20689 ;; Non pairable "test imm, reg" instructions can be translated to
20690 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20691 ;; byte opcode instead of two, have a short form for byte operands),
20692 ;; so do it for other CPUs as well.  Given that the value was dead,
20693 ;; this should not create any new dependencies.  Pass on the sub-word
20694 ;; versions if we're concerned about partial register stalls.
20695
20696 (define_peephole2
20697   [(set (match_operand 0 "flags_reg_operand" "")
20698         (match_operator 1 "compare_operator"
20699           [(and:SI (match_operand:SI 2 "register_operand" "")
20700                    (match_operand:SI 3 "immediate_operand" ""))
20701            (const_int 0)]))]
20702   "ix86_match_ccmode (insn, CCNOmode)
20703    && (true_regnum (operands[2]) != AX_REG
20704        || satisfies_constraint_K (operands[3]))
20705    && peep2_reg_dead_p (1, operands[2])"
20706   [(parallel
20707      [(set (match_dup 0)
20708            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20709                             (const_int 0)]))
20710       (set (match_dup 2)
20711            (and:SI (match_dup 2) (match_dup 3)))])]
20712   "")
20713
20714 ;; We don't need to handle HImode case, because it will be promoted to SImode
20715 ;; on ! TARGET_PARTIAL_REG_STALL
20716
20717 (define_peephole2
20718   [(set (match_operand 0 "flags_reg_operand" "")
20719         (match_operator 1 "compare_operator"
20720           [(and:QI (match_operand:QI 2 "register_operand" "")
20721                    (match_operand:QI 3 "immediate_operand" ""))
20722            (const_int 0)]))]
20723   "! TARGET_PARTIAL_REG_STALL
20724    && ix86_match_ccmode (insn, CCNOmode)
20725    && true_regnum (operands[2]) != AX_REG
20726    && peep2_reg_dead_p (1, operands[2])"
20727   [(parallel
20728      [(set (match_dup 0)
20729            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20730                             (const_int 0)]))
20731       (set (match_dup 2)
20732            (and:QI (match_dup 2) (match_dup 3)))])]
20733   "")
20734
20735 (define_peephole2
20736   [(set (match_operand 0 "flags_reg_operand" "")
20737         (match_operator 1 "compare_operator"
20738           [(and:SI
20739              (zero_extract:SI
20740                (match_operand 2 "ext_register_operand" "")
20741                (const_int 8)
20742                (const_int 8))
20743              (match_operand 3 "const_int_operand" ""))
20744            (const_int 0)]))]
20745   "! TARGET_PARTIAL_REG_STALL
20746    && ix86_match_ccmode (insn, CCNOmode)
20747    && true_regnum (operands[2]) != AX_REG
20748    && peep2_reg_dead_p (1, operands[2])"
20749   [(parallel [(set (match_dup 0)
20750                    (match_op_dup 1
20751                      [(and:SI
20752                         (zero_extract:SI
20753                           (match_dup 2)
20754                           (const_int 8)
20755                           (const_int 8))
20756                         (match_dup 3))
20757                       (const_int 0)]))
20758               (set (zero_extract:SI (match_dup 2)
20759                                     (const_int 8)
20760                                     (const_int 8))
20761                    (and:SI
20762                      (zero_extract:SI
20763                        (match_dup 2)
20764                        (const_int 8)
20765                        (const_int 8))
20766                      (match_dup 3)))])]
20767   "")
20768
20769 ;; Don't do logical operations with memory inputs.
20770 (define_peephole2
20771   [(match_scratch:SI 2 "r")
20772    (parallel [(set (match_operand:SI 0 "register_operand" "")
20773                    (match_operator:SI 3 "arith_or_logical_operator"
20774                      [(match_dup 0)
20775                       (match_operand:SI 1 "memory_operand" "")]))
20776               (clobber (reg:CC FLAGS_REG))])]
20777   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20778   [(set (match_dup 2) (match_dup 1))
20779    (parallel [(set (match_dup 0)
20780                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20781               (clobber (reg:CC FLAGS_REG))])]
20782   "")
20783
20784 (define_peephole2
20785   [(match_scratch:SI 2 "r")
20786    (parallel [(set (match_operand:SI 0 "register_operand" "")
20787                    (match_operator:SI 3 "arith_or_logical_operator"
20788                      [(match_operand:SI 1 "memory_operand" "")
20789                       (match_dup 0)]))
20790               (clobber (reg:CC FLAGS_REG))])]
20791   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20792   [(set (match_dup 2) (match_dup 1))
20793    (parallel [(set (match_dup 0)
20794                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20795               (clobber (reg:CC FLAGS_REG))])]
20796   "")
20797
20798 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20799 ;; refers to the destination of the load!
20800
20801 (define_peephole2
20802   [(set (match_operand:SI 0 "register_operand" "")
20803         (match_operand:SI 1 "register_operand" ""))
20804    (parallel [(set (match_dup 0)
20805                    (match_operator:SI 3 "commutative_operator"
20806                      [(match_dup 0)
20807                       (match_operand:SI 2 "memory_operand" "")]))
20808               (clobber (reg:CC FLAGS_REG))])]
20809   "REGNO (operands[0]) != REGNO (operands[1])
20810    && GENERAL_REGNO_P (REGNO (operands[0]))
20811    && GENERAL_REGNO_P (REGNO (operands[1]))"
20812   [(set (match_dup 0) (match_dup 4))
20813    (parallel [(set (match_dup 0)
20814                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20815               (clobber (reg:CC FLAGS_REG))])]
20816   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20817
20818 (define_peephole2
20819   [(set (match_operand 0 "register_operand" "")
20820         (match_operand 1 "register_operand" ""))
20821    (set (match_dup 0)
20822                    (match_operator 3 "commutative_operator"
20823                      [(match_dup 0)
20824                       (match_operand 2 "memory_operand" "")]))]
20825   "REGNO (operands[0]) != REGNO (operands[1])
20826    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
20827        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20828   [(set (match_dup 0) (match_dup 2))
20829    (set (match_dup 0)
20830         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20831   "")
20832
20833 ; Don't do logical operations with memory outputs
20834 ;
20835 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20836 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20837 ; the same decoder scheduling characteristics as the original.
20838
20839 (define_peephole2
20840   [(match_scratch:SI 2 "r")
20841    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20842                    (match_operator:SI 3 "arith_or_logical_operator"
20843                      [(match_dup 0)
20844                       (match_operand:SI 1 "nonmemory_operand" "")]))
20845               (clobber (reg:CC FLAGS_REG))])]
20846   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20847   [(set (match_dup 2) (match_dup 0))
20848    (parallel [(set (match_dup 2)
20849                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20850               (clobber (reg:CC FLAGS_REG))])
20851    (set (match_dup 0) (match_dup 2))]
20852   "")
20853
20854 (define_peephole2
20855   [(match_scratch:SI 2 "r")
20856    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20857                    (match_operator:SI 3 "arith_or_logical_operator"
20858                      [(match_operand:SI 1 "nonmemory_operand" "")
20859                       (match_dup 0)]))
20860               (clobber (reg:CC FLAGS_REG))])]
20861   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20862   [(set (match_dup 2) (match_dup 0))
20863    (parallel [(set (match_dup 2)
20864                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20865               (clobber (reg:CC FLAGS_REG))])
20866    (set (match_dup 0) (match_dup 2))]
20867   "")
20868
20869 ;; Attempt to always use XOR for zeroing registers.
20870 (define_peephole2
20871   [(set (match_operand 0 "register_operand" "")
20872         (match_operand 1 "const0_operand" ""))]
20873   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20874    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20875    && GENERAL_REG_P (operands[0])
20876    && peep2_regno_dead_p (0, FLAGS_REG)"
20877   [(parallel [(set (match_dup 0) (const_int 0))
20878               (clobber (reg:CC FLAGS_REG))])]
20879 {
20880   operands[0] = gen_lowpart (word_mode, operands[0]);
20881 })
20882
20883 (define_peephole2
20884   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20885         (const_int 0))]
20886   "(GET_MODE (operands[0]) == QImode
20887     || GET_MODE (operands[0]) == HImode)
20888    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20889    && peep2_regno_dead_p (0, FLAGS_REG)"
20890   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20891               (clobber (reg:CC FLAGS_REG))])])
20892
20893 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20894 (define_peephole2
20895   [(set (match_operand 0 "register_operand" "")
20896         (const_int -1))]
20897   "(GET_MODE (operands[0]) == HImode
20898     || GET_MODE (operands[0]) == SImode
20899     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20900    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20901    && peep2_regno_dead_p (0, FLAGS_REG)"
20902   [(parallel [(set (match_dup 0) (const_int -1))
20903               (clobber (reg:CC FLAGS_REG))])]
20904   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20905                               operands[0]);")
20906
20907 ;; Attempt to convert simple leas to adds. These can be created by
20908 ;; move expanders.
20909 (define_peephole2
20910   [(set (match_operand:SI 0 "register_operand" "")
20911         (plus:SI (match_dup 0)
20912                  (match_operand:SI 1 "nonmemory_operand" "")))]
20913   "peep2_regno_dead_p (0, FLAGS_REG)"
20914   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20915               (clobber (reg:CC FLAGS_REG))])]
20916   "")
20917
20918 (define_peephole2
20919   [(set (match_operand:SI 0 "register_operand" "")
20920         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20921                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20922   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20923   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20924               (clobber (reg:CC FLAGS_REG))])]
20925   "operands[2] = gen_lowpart (SImode, operands[2]);")
20926
20927 (define_peephole2
20928   [(set (match_operand:DI 0 "register_operand" "")
20929         (plus:DI (match_dup 0)
20930                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20931   "peep2_regno_dead_p (0, FLAGS_REG)"
20932   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20933               (clobber (reg:CC FLAGS_REG))])]
20934   "")
20935
20936 (define_peephole2
20937   [(set (match_operand:SI 0 "register_operand" "")
20938         (mult:SI (match_dup 0)
20939                  (match_operand:SI 1 "const_int_operand" "")))]
20940   "exact_log2 (INTVAL (operands[1])) >= 0
20941    && peep2_regno_dead_p (0, FLAGS_REG)"
20942   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20943               (clobber (reg:CC FLAGS_REG))])]
20944   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20945
20946 (define_peephole2
20947   [(set (match_operand:DI 0 "register_operand" "")
20948         (mult:DI (match_dup 0)
20949                  (match_operand:DI 1 "const_int_operand" "")))]
20950   "exact_log2 (INTVAL (operands[1])) >= 0
20951    && peep2_regno_dead_p (0, FLAGS_REG)"
20952   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20953               (clobber (reg:CC FLAGS_REG))])]
20954   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20955
20956 (define_peephole2
20957   [(set (match_operand:SI 0 "register_operand" "")
20958         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20959                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20960   "exact_log2 (INTVAL (operands[2])) >= 0
20961    && REGNO (operands[0]) == REGNO (operands[1])
20962    && peep2_regno_dead_p (0, FLAGS_REG)"
20963   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20964               (clobber (reg:CC FLAGS_REG))])]
20965   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20966
20967 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20968 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20969 ;; many CPUs it is also faster, since special hardware to avoid esp
20970 ;; dependencies is present.
20971
20972 ;; While some of these conversions may be done using splitters, we use peepholes
20973 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20974
20975 ;; Convert prologue esp subtractions to push.
20976 ;; We need register to push.  In order to keep verify_flow_info happy we have
20977 ;; two choices
20978 ;; - use scratch and clobber it in order to avoid dependencies
20979 ;; - use already live register
20980 ;; We can't use the second way right now, since there is no reliable way how to
20981 ;; verify that given register is live.  First choice will also most likely in
20982 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20983 ;; call clobbered registers are dead.  We may want to use base pointer as an
20984 ;; alternative when no register is available later.
20985
20986 (define_peephole2
20987   [(match_scratch:SI 0 "r")
20988    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20989               (clobber (reg:CC FLAGS_REG))
20990               (clobber (mem:BLK (scratch)))])]
20991   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20992   [(clobber (match_dup 0))
20993    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20994               (clobber (mem:BLK (scratch)))])])
20995
20996 (define_peephole2
20997   [(match_scratch:SI 0 "r")
20998    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20999               (clobber (reg:CC FLAGS_REG))
21000               (clobber (mem:BLK (scratch)))])]
21001   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21002   [(clobber (match_dup 0))
21003    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21004    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21005               (clobber (mem:BLK (scratch)))])])
21006
21007 ;; Convert esp subtractions to push.
21008 (define_peephole2
21009   [(match_scratch:SI 0 "r")
21010    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21011               (clobber (reg:CC FLAGS_REG))])]
21012   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21013   [(clobber (match_dup 0))
21014    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21015
21016 (define_peephole2
21017   [(match_scratch:SI 0 "r")
21018    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21019               (clobber (reg:CC FLAGS_REG))])]
21020   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21021   [(clobber (match_dup 0))
21022    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21023    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21024
21025 ;; Convert epilogue deallocator to pop.
21026 (define_peephole2
21027   [(match_scratch:SI 0 "r")
21028    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21029               (clobber (reg:CC FLAGS_REG))
21030               (clobber (mem:BLK (scratch)))])]
21031   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21032   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21033               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21034               (clobber (mem:BLK (scratch)))])]
21035   "")
21036
21037 ;; Two pops case is tricky, since pop causes dependency on destination register.
21038 ;; We use two registers if available.
21039 (define_peephole2
21040   [(match_scratch:SI 0 "r")
21041    (match_scratch:SI 1 "r")
21042    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21043               (clobber (reg:CC FLAGS_REG))
21044               (clobber (mem:BLK (scratch)))])]
21045   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21046   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21047               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21048               (clobber (mem:BLK (scratch)))])
21049    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21050               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21051   "")
21052
21053 (define_peephole2
21054   [(match_scratch:SI 0 "r")
21055    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21056               (clobber (reg:CC FLAGS_REG))
21057               (clobber (mem:BLK (scratch)))])]
21058   "optimize_insn_for_size_p ()"
21059   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21060               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21061               (clobber (mem:BLK (scratch)))])
21062    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21063               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21064   "")
21065
21066 ;; Convert esp additions to pop.
21067 (define_peephole2
21068   [(match_scratch:SI 0 "r")
21069    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21070               (clobber (reg:CC FLAGS_REG))])]
21071   ""
21072   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21073               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21074   "")
21075
21076 ;; Two pops case is tricky, since pop causes dependency on destination register.
21077 ;; We use two registers if available.
21078 (define_peephole2
21079   [(match_scratch:SI 0 "r")
21080    (match_scratch:SI 1 "r")
21081    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21082               (clobber (reg:CC FLAGS_REG))])]
21083   ""
21084   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21085               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21086    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21087               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21088   "")
21089
21090 (define_peephole2
21091   [(match_scratch:SI 0 "r")
21092    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21093               (clobber (reg:CC FLAGS_REG))])]
21094   "optimize_insn_for_size_p ()"
21095   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21096               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21097    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21098               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21099   "")
21100 \f
21101 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21102 ;; required and register dies.  Similarly for 128 to -128.
21103 (define_peephole2
21104   [(set (match_operand 0 "flags_reg_operand" "")
21105         (match_operator 1 "compare_operator"
21106           [(match_operand 2 "register_operand" "")
21107            (match_operand 3 "const_int_operand" "")]))]
21108   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21109      && incdec_operand (operands[3], GET_MODE (operands[3])))
21110     || (!TARGET_FUSE_CMP_AND_BRANCH
21111         && INTVAL (operands[3]) == 128))
21112    && ix86_match_ccmode (insn, CCGCmode)
21113    && peep2_reg_dead_p (1, operands[2])"
21114   [(parallel [(set (match_dup 0)
21115                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21116               (clobber (match_dup 2))])]
21117   "")
21118 \f
21119 (define_peephole2
21120   [(match_scratch:DI 0 "r")
21121    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21122               (clobber (reg:CC FLAGS_REG))
21123               (clobber (mem:BLK (scratch)))])]
21124   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21125   [(clobber (match_dup 0))
21126    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21127               (clobber (mem:BLK (scratch)))])])
21128
21129 (define_peephole2
21130   [(match_scratch:DI 0 "r")
21131    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21132               (clobber (reg:CC FLAGS_REG))
21133               (clobber (mem:BLK (scratch)))])]
21134   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21135   [(clobber (match_dup 0))
21136    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21137    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21138               (clobber (mem:BLK (scratch)))])])
21139
21140 ;; Convert esp subtractions to push.
21141 (define_peephole2
21142   [(match_scratch:DI 0 "r")
21143    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21144               (clobber (reg:CC FLAGS_REG))])]
21145   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21146   [(clobber (match_dup 0))
21147    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21148
21149 (define_peephole2
21150   [(match_scratch:DI 0 "r")
21151    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21152               (clobber (reg:CC FLAGS_REG))])]
21153   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21154   [(clobber (match_dup 0))
21155    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21156    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21157
21158 ;; Convert epilogue deallocator to pop.
21159 (define_peephole2
21160   [(match_scratch:DI 0 "r")
21161    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21162               (clobber (reg:CC FLAGS_REG))
21163               (clobber (mem:BLK (scratch)))])]
21164   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21165   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21166               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21167               (clobber (mem:BLK (scratch)))])]
21168   "")
21169
21170 ;; Two pops case is tricky, since pop causes dependency on destination register.
21171 ;; We use two registers if available.
21172 (define_peephole2
21173   [(match_scratch:DI 0 "r")
21174    (match_scratch:DI 1 "r")
21175    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21176               (clobber (reg:CC FLAGS_REG))
21177               (clobber (mem:BLK (scratch)))])]
21178   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21179   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21180               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21181               (clobber (mem:BLK (scratch)))])
21182    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21183               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21184   "")
21185
21186 (define_peephole2
21187   [(match_scratch:DI 0 "r")
21188    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21189               (clobber (reg:CC FLAGS_REG))
21190               (clobber (mem:BLK (scratch)))])]
21191   "optimize_insn_for_size_p ()"
21192   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21193               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21194               (clobber (mem:BLK (scratch)))])
21195    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21196               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21197   "")
21198
21199 ;; Convert esp additions to pop.
21200 (define_peephole2
21201   [(match_scratch:DI 0 "r")
21202    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21203               (clobber (reg:CC FLAGS_REG))])]
21204   ""
21205   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21206               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21207   "")
21208
21209 ;; Two pops case is tricky, since pop causes dependency on destination register.
21210 ;; We use two registers if available.
21211 (define_peephole2
21212   [(match_scratch:DI 0 "r")
21213    (match_scratch:DI 1 "r")
21214    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21215               (clobber (reg:CC FLAGS_REG))])]
21216   ""
21217   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21218               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21219    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21220               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21221   "")
21222
21223 (define_peephole2
21224   [(match_scratch:DI 0 "r")
21225    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21226               (clobber (reg:CC FLAGS_REG))])]
21227   "optimize_insn_for_size_p ()"
21228   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21229               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21230    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21231               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21232   "")
21233 \f
21234 ;; Convert imul by three, five and nine into lea
21235 (define_peephole2
21236   [(parallel
21237     [(set (match_operand:SI 0 "register_operand" "")
21238           (mult:SI (match_operand:SI 1 "register_operand" "")
21239                    (match_operand:SI 2 "const_int_operand" "")))
21240      (clobber (reg:CC FLAGS_REG))])]
21241   "INTVAL (operands[2]) == 3
21242    || INTVAL (operands[2]) == 5
21243    || INTVAL (operands[2]) == 9"
21244   [(set (match_dup 0)
21245         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21246                  (match_dup 1)))]
21247   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21248
21249 (define_peephole2
21250   [(parallel
21251     [(set (match_operand:SI 0 "register_operand" "")
21252           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21253                    (match_operand:SI 2 "const_int_operand" "")))
21254      (clobber (reg:CC FLAGS_REG))])]
21255   "optimize_insn_for_speed_p ()
21256    && (INTVAL (operands[2]) == 3
21257        || INTVAL (operands[2]) == 5
21258        || INTVAL (operands[2]) == 9)"
21259   [(set (match_dup 0) (match_dup 1))
21260    (set (match_dup 0)
21261         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21262                  (match_dup 0)))]
21263   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21264
21265 (define_peephole2
21266   [(parallel
21267     [(set (match_operand:DI 0 "register_operand" "")
21268           (mult:DI (match_operand:DI 1 "register_operand" "")
21269                    (match_operand:DI 2 "const_int_operand" "")))
21270      (clobber (reg:CC FLAGS_REG))])]
21271   "TARGET_64BIT
21272    && (INTVAL (operands[2]) == 3
21273        || INTVAL (operands[2]) == 5
21274        || INTVAL (operands[2]) == 9)"
21275   [(set (match_dup 0)
21276         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21277                  (match_dup 1)))]
21278   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21279
21280 (define_peephole2
21281   [(parallel
21282     [(set (match_operand:DI 0 "register_operand" "")
21283           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21284                    (match_operand:DI 2 "const_int_operand" "")))
21285      (clobber (reg:CC FLAGS_REG))])]
21286   "TARGET_64BIT
21287    && optimize_insn_for_speed_p ()
21288    && (INTVAL (operands[2]) == 3
21289        || INTVAL (operands[2]) == 5
21290        || INTVAL (operands[2]) == 9)"
21291   [(set (match_dup 0) (match_dup 1))
21292    (set (match_dup 0)
21293         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21294                  (match_dup 0)))]
21295   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21296
21297 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21298 ;; imul $32bit_imm, reg, reg is direct decoded.
21299 (define_peephole2
21300   [(match_scratch:DI 3 "r")
21301    (parallel [(set (match_operand:DI 0 "register_operand" "")
21302                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21303                             (match_operand:DI 2 "immediate_operand" "")))
21304               (clobber (reg:CC FLAGS_REG))])]
21305   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21306    && !satisfies_constraint_K (operands[2])"
21307   [(set (match_dup 3) (match_dup 1))
21308    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21309               (clobber (reg:CC FLAGS_REG))])]
21310 "")
21311
21312 (define_peephole2
21313   [(match_scratch:SI 3 "r")
21314    (parallel [(set (match_operand:SI 0 "register_operand" "")
21315                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21316                             (match_operand:SI 2 "immediate_operand" "")))
21317               (clobber (reg:CC FLAGS_REG))])]
21318   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21319    && !satisfies_constraint_K (operands[2])"
21320   [(set (match_dup 3) (match_dup 1))
21321    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21322               (clobber (reg:CC FLAGS_REG))])]
21323 "")
21324
21325 (define_peephole2
21326   [(match_scratch:SI 3 "r")
21327    (parallel [(set (match_operand:DI 0 "register_operand" "")
21328                    (zero_extend:DI
21329                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21330                               (match_operand:SI 2 "immediate_operand" ""))))
21331               (clobber (reg:CC FLAGS_REG))])]
21332   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21333    && !satisfies_constraint_K (operands[2])"
21334   [(set (match_dup 3) (match_dup 1))
21335    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21336               (clobber (reg:CC FLAGS_REG))])]
21337 "")
21338
21339 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21340 ;; Convert it into imul reg, reg
21341 ;; It would be better to force assembler to encode instruction using long
21342 ;; immediate, but there is apparently no way to do so.
21343 (define_peephole2
21344   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21345                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21346                             (match_operand:DI 2 "const_int_operand" "")))
21347               (clobber (reg:CC FLAGS_REG))])
21348    (match_scratch:DI 3 "r")]
21349   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21350    && satisfies_constraint_K (operands[2])"
21351   [(set (match_dup 3) (match_dup 2))
21352    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21353               (clobber (reg:CC FLAGS_REG))])]
21354 {
21355   if (!rtx_equal_p (operands[0], operands[1]))
21356     emit_move_insn (operands[0], operands[1]);
21357 })
21358
21359 (define_peephole2
21360   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21361                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21362                             (match_operand:SI 2 "const_int_operand" "")))
21363               (clobber (reg:CC FLAGS_REG))])
21364    (match_scratch:SI 3 "r")]
21365   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21366    && satisfies_constraint_K (operands[2])"
21367   [(set (match_dup 3) (match_dup 2))
21368    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21369               (clobber (reg:CC FLAGS_REG))])]
21370 {
21371   if (!rtx_equal_p (operands[0], operands[1]))
21372     emit_move_insn (operands[0], operands[1]);
21373 })
21374
21375 (define_peephole2
21376   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21377                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21378                             (match_operand:HI 2 "immediate_operand" "")))
21379               (clobber (reg:CC FLAGS_REG))])
21380    (match_scratch:HI 3 "r")]
21381   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21382   [(set (match_dup 3) (match_dup 2))
21383    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21384               (clobber (reg:CC FLAGS_REG))])]
21385 {
21386   if (!rtx_equal_p (operands[0], operands[1]))
21387     emit_move_insn (operands[0], operands[1]);
21388 })
21389
21390 ;; After splitting up read-modify operations, array accesses with memory
21391 ;; operands might end up in form:
21392 ;;  sall    $2, %eax
21393 ;;  movl    4(%esp), %edx
21394 ;;  addl    %edx, %eax
21395 ;; instead of pre-splitting:
21396 ;;  sall    $2, %eax
21397 ;;  addl    4(%esp), %eax
21398 ;; Turn it into:
21399 ;;  movl    4(%esp), %edx
21400 ;;  leal    (%edx,%eax,4), %eax
21401
21402 (define_peephole2
21403   [(parallel [(set (match_operand 0 "register_operand" "")
21404                    (ashift (match_operand 1 "register_operand" "")
21405                            (match_operand 2 "const_int_operand" "")))
21406                (clobber (reg:CC FLAGS_REG))])
21407    (set (match_operand 3 "register_operand")
21408         (match_operand 4 "x86_64_general_operand" ""))
21409    (parallel [(set (match_operand 5 "register_operand" "")
21410                    (plus (match_operand 6 "register_operand" "")
21411                          (match_operand 7 "register_operand" "")))
21412                    (clobber (reg:CC FLAGS_REG))])]
21413   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21414    /* Validate MODE for lea.  */
21415    && ((!TARGET_PARTIAL_REG_STALL
21416         && (GET_MODE (operands[0]) == QImode
21417             || GET_MODE (operands[0]) == HImode))
21418        || GET_MODE (operands[0]) == SImode
21419        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21420    /* We reorder load and the shift.  */
21421    && !rtx_equal_p (operands[1], operands[3])
21422    && !reg_overlap_mentioned_p (operands[0], operands[4])
21423    /* Last PLUS must consist of operand 0 and 3.  */
21424    && !rtx_equal_p (operands[0], operands[3])
21425    && (rtx_equal_p (operands[3], operands[6])
21426        || rtx_equal_p (operands[3], operands[7]))
21427    && (rtx_equal_p (operands[0], operands[6])
21428        || rtx_equal_p (operands[0], operands[7]))
21429    /* The intermediate operand 0 must die or be same as output.  */
21430    && (rtx_equal_p (operands[0], operands[5])
21431        || peep2_reg_dead_p (3, operands[0]))"
21432   [(set (match_dup 3) (match_dup 4))
21433    (set (match_dup 0) (match_dup 1))]
21434 {
21435   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21436   int scale = 1 << INTVAL (operands[2]);
21437   rtx index = gen_lowpart (Pmode, operands[1]);
21438   rtx base = gen_lowpart (Pmode, operands[3]);
21439   rtx dest = gen_lowpart (mode, operands[5]);
21440
21441   operands[1] = gen_rtx_PLUS (Pmode, base,
21442                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21443   if (mode != Pmode)
21444     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21445   operands[0] = dest;
21446 })
21447 \f
21448 ;; Call-value patterns last so that the wildcard operand does not
21449 ;; disrupt insn-recog's switch tables.
21450
21451 (define_insn "*call_value_pop_0"
21452   [(set (match_operand 0 "" "")
21453         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21454               (match_operand:SI 2 "" "")))
21455    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21456                             (match_operand:SI 3 "immediate_operand" "")))]
21457   "!TARGET_64BIT"
21458 {
21459   if (SIBLING_CALL_P (insn))
21460     return "jmp\t%P1";
21461   else
21462     return "call\t%P1";
21463 }
21464   [(set_attr "type" "callv")])
21465
21466 (define_insn "*call_value_pop_1"
21467   [(set (match_operand 0 "" "")
21468         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21469               (match_operand:SI 2 "" "")))
21470    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21471                             (match_operand:SI 3 "immediate_operand" "i")))]
21472   "!TARGET_64BIT"
21473 {
21474   if (constant_call_address_operand (operands[1], Pmode))
21475     {
21476       if (SIBLING_CALL_P (insn))
21477         return "jmp\t%P1";
21478       else
21479         return "call\t%P1";
21480     }
21481   if (SIBLING_CALL_P (insn))
21482     return "jmp\t%A1";
21483   else
21484     return "call\t%A1";
21485 }
21486   [(set_attr "type" "callv")])
21487
21488 (define_insn "*call_value_0"
21489   [(set (match_operand 0 "" "")
21490         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21491               (match_operand:SI 2 "" "")))]
21492   "!TARGET_64BIT"
21493 {
21494   if (SIBLING_CALL_P (insn))
21495     return "jmp\t%P1";
21496   else
21497     return "call\t%P1";
21498 }
21499   [(set_attr "type" "callv")])
21500
21501 (define_insn "*call_value_0_rex64"
21502   [(set (match_operand 0 "" "")
21503         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21504               (match_operand:DI 2 "const_int_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_0_rex64_ms_sysv"
21515   [(set (match_operand 0 "" "")
21516         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21517               (match_operand:DI 2 "const_int_operand" "")))
21518    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21519    (clobber (reg:TI XMM6_REG))
21520    (clobber (reg:TI XMM7_REG))
21521    (clobber (reg:TI XMM8_REG))
21522    (clobber (reg:TI XMM9_REG))
21523    (clobber (reg:TI XMM10_REG))
21524    (clobber (reg:TI XMM11_REG))
21525    (clobber (reg:TI XMM12_REG))
21526    (clobber (reg:TI XMM13_REG))
21527    (clobber (reg:TI XMM14_REG))
21528    (clobber (reg:TI XMM15_REG))
21529    (clobber (reg:DI SI_REG))
21530    (clobber (reg:DI DI_REG))]
21531   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21532 {
21533   if (SIBLING_CALL_P (insn))
21534     return "jmp\t%P1";
21535   else
21536     return "call\t%P1";
21537 }
21538   [(set_attr "type" "callv")])
21539
21540 (define_insn "*call_value_1"
21541   [(set (match_operand 0 "" "")
21542         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21543               (match_operand:SI 2 "" "")))]
21544   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21545 {
21546   if (constant_call_address_operand (operands[1], Pmode))
21547     return "call\t%P1";
21548   return "call\t%A1";
21549 }
21550   [(set_attr "type" "callv")])
21551
21552 (define_insn "*sibcall_value_1"
21553   [(set (match_operand 0 "" "")
21554         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21555               (match_operand:SI 2 "" "")))]
21556   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21557   "@
21558    jmp\t%P1
21559    jmp\t%A1"
21560   [(set_attr "type" "callv")])
21561
21562 (define_insn "*call_value_1_rex64"
21563   [(set (match_operand 0 "" "")
21564         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21565               (match_operand:DI 2 "" "")))]
21566   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21567    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21568 {
21569   if (constant_call_address_operand (operands[1], Pmode))
21570     return "call\t%P1";
21571   return "call\t%A1";
21572 }
21573   [(set_attr "type" "callv")])
21574
21575 (define_insn "*call_value_1_rex64_ms_sysv"
21576   [(set (match_operand 0 "" "")
21577         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21578               (match_operand:DI 2 "" "")))
21579    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21580    (clobber (reg:TI 27))
21581    (clobber (reg:TI 28))
21582    (clobber (reg:TI 45))
21583    (clobber (reg:TI 46))
21584    (clobber (reg:TI 47))
21585    (clobber (reg:TI 48))
21586    (clobber (reg:TI 49))
21587    (clobber (reg:TI 50))
21588    (clobber (reg:TI 51))
21589    (clobber (reg:TI 52))
21590    (clobber (reg:DI SI_REG))
21591    (clobber (reg:DI DI_REG))]
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 "*call_value_1_rex64_large"
21601   [(set (match_operand 0 "" "")
21602         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21603               (match_operand:DI 2 "" "")))]
21604   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21605   "call\t%A1"
21606   [(set_attr "type" "callv")])
21607
21608 (define_insn "*sibcall_value_1_rex64"
21609   [(set (match_operand 0 "" "")
21610         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21611               (match_operand:DI 2 "" "")))]
21612   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21613   "@
21614    jmp\t%P1
21615    jmp\t%A1"
21616   [(set_attr "type" "callv")])
21617 \f
21618 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21619 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21620 ;; caught for use by garbage collectors and the like.  Using an insn that
21621 ;; maps to SIGILL makes it more likely the program will rightfully die.
21622 ;; Keeping with tradition, "6" is in honor of #UD.
21623 (define_insn "trap"
21624   [(trap_if (const_int 1) (const_int 6))]
21625   ""
21626   { return ASM_SHORT "0x0b0f"; }
21627   [(set_attr "length" "2")])
21628
21629 (define_expand "sse_prologue_save"
21630   [(parallel [(set (match_operand:BLK 0 "" "")
21631                    (unspec:BLK [(reg:DI 21)
21632                                 (reg:DI 22)
21633                                 (reg:DI 23)
21634                                 (reg:DI 24)
21635                                 (reg:DI 25)
21636                                 (reg:DI 26)
21637                                 (reg:DI 27)
21638                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21639               (use (match_operand:DI 1 "register_operand" ""))
21640               (use (match_operand:DI 2 "immediate_operand" ""))
21641               (use (label_ref:DI (match_operand 3 "" "")))])]
21642   "TARGET_64BIT"
21643   "")
21644
21645 (define_insn "*sse_prologue_save_insn"
21646   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21647                           (match_operand:DI 4 "const_int_operand" "n")))
21648         (unspec:BLK [(reg:DI 21)
21649                      (reg:DI 22)
21650                      (reg:DI 23)
21651                      (reg:DI 24)
21652                      (reg:DI 25)
21653                      (reg:DI 26)
21654                      (reg:DI 27)
21655                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21656    (use (match_operand:DI 1 "register_operand" "r"))
21657    (use (match_operand:DI 2 "const_int_operand" "i"))
21658    (use (label_ref:DI (match_operand 3 "" "X")))]
21659   "TARGET_64BIT
21660    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21661    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21662 {
21663   int i;
21664   operands[0] = gen_rtx_MEM (Pmode,
21665                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21666   /* VEX instruction with a REX prefix will #UD.  */
21667   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21668     gcc_unreachable ();
21669
21670   output_asm_insn ("jmp\t%A1", operands);
21671   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21672     {
21673       operands[4] = adjust_address (operands[0], DImode, i*16);
21674       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21675       PUT_MODE (operands[4], TImode);
21676       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21677         output_asm_insn ("rex", operands);
21678       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21679     }
21680   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21681                                      CODE_LABEL_NUMBER (operands[3]));
21682   return "";
21683 }
21684   [(set_attr "type" "other")
21685    (set_attr "length_immediate" "0")
21686    (set_attr "length_address" "0")
21687    (set (attr "length")
21688      (if_then_else
21689        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21690        (const_string "34")
21691        (const_string "42")))
21692    (set_attr "memory" "store")
21693    (set_attr "modrm" "0")
21694    (set_attr "prefix" "maybe_vex")
21695    (set_attr "mode" "DI")])
21696
21697 (define_expand "prefetch"
21698   [(prefetch (match_operand 0 "address_operand" "")
21699              (match_operand:SI 1 "const_int_operand" "")
21700              (match_operand:SI 2 "const_int_operand" ""))]
21701   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21702 {
21703   int rw = INTVAL (operands[1]);
21704   int locality = INTVAL (operands[2]);
21705
21706   gcc_assert (rw == 0 || rw == 1);
21707   gcc_assert (locality >= 0 && locality <= 3);
21708   gcc_assert (GET_MODE (operands[0]) == Pmode
21709               || GET_MODE (operands[0]) == VOIDmode);
21710
21711   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21712      supported by SSE counterpart or the SSE prefetch is not available
21713      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21714      of locality.  */
21715   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21716     operands[2] = GEN_INT (3);
21717   else
21718     operands[1] = const0_rtx;
21719 })
21720
21721 (define_insn "*prefetch_sse"
21722   [(prefetch (match_operand:SI 0 "address_operand" "p")
21723              (const_int 0)
21724              (match_operand:SI 1 "const_int_operand" ""))]
21725   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21726 {
21727   static const char * const patterns[4] = {
21728    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21729   };
21730
21731   int locality = INTVAL (operands[1]);
21732   gcc_assert (locality >= 0 && locality <= 3);
21733
21734   return patterns[locality];
21735 }
21736   [(set_attr "type" "sse")
21737    (set_attr "memory" "none")])
21738
21739 (define_insn "*prefetch_sse_rex"
21740   [(prefetch (match_operand:DI 0 "address_operand" "p")
21741              (const_int 0)
21742              (match_operand:SI 1 "const_int_operand" ""))]
21743   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21744 {
21745   static const char * const patterns[4] = {
21746    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21747   };
21748
21749   int locality = INTVAL (operands[1]);
21750   gcc_assert (locality >= 0 && locality <= 3);
21751
21752   return patterns[locality];
21753 }
21754   [(set_attr "type" "sse")
21755    (set_attr "memory" "none")])
21756
21757 (define_insn "*prefetch_3dnow"
21758   [(prefetch (match_operand:SI 0 "address_operand" "p")
21759              (match_operand:SI 1 "const_int_operand" "n")
21760              (const_int 3))]
21761   "TARGET_3DNOW && !TARGET_64BIT"
21762 {
21763   if (INTVAL (operands[1]) == 0)
21764     return "prefetch\t%a0";
21765   else
21766     return "prefetchw\t%a0";
21767 }
21768   [(set_attr "type" "mmx")
21769    (set_attr "memory" "none")])
21770
21771 (define_insn "*prefetch_3dnow_rex"
21772   [(prefetch (match_operand:DI 0 "address_operand" "p")
21773              (match_operand:SI 1 "const_int_operand" "n")
21774              (const_int 3))]
21775   "TARGET_3DNOW && TARGET_64BIT"
21776 {
21777   if (INTVAL (operands[1]) == 0)
21778     return "prefetch\t%a0";
21779   else
21780     return "prefetchw\t%a0";
21781 }
21782   [(set_attr "type" "mmx")
21783    (set_attr "memory" "none")])
21784
21785 (define_expand "stack_protect_set"
21786   [(match_operand 0 "memory_operand" "")
21787    (match_operand 1 "memory_operand" "")]
21788   ""
21789 {
21790 #ifdef TARGET_THREAD_SSP_OFFSET
21791   if (TARGET_64BIT)
21792     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21793                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21794   else
21795     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21796                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21797 #else
21798   if (TARGET_64BIT)
21799     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21800   else
21801     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21802 #endif
21803   DONE;
21804 })
21805
21806 (define_insn "stack_protect_set_si"
21807   [(set (match_operand:SI 0 "memory_operand" "=m")
21808         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21809    (set (match_scratch:SI 2 "=&r") (const_int 0))
21810    (clobber (reg:CC FLAGS_REG))]
21811   ""
21812   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21813   [(set_attr "type" "multi")])
21814
21815 (define_insn "stack_protect_set_di"
21816   [(set (match_operand:DI 0 "memory_operand" "=m")
21817         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21818    (set (match_scratch:DI 2 "=&r") (const_int 0))
21819    (clobber (reg:CC FLAGS_REG))]
21820   "TARGET_64BIT"
21821   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21822   [(set_attr "type" "multi")])
21823
21824 (define_insn "stack_tls_protect_set_si"
21825   [(set (match_operand:SI 0 "memory_operand" "=m")
21826         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21827    (set (match_scratch:SI 2 "=&r") (const_int 0))
21828    (clobber (reg:CC FLAGS_REG))]
21829   ""
21830   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21831   [(set_attr "type" "multi")])
21832
21833 (define_insn "stack_tls_protect_set_di"
21834   [(set (match_operand:DI 0 "memory_operand" "=m")
21835         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21836    (set (match_scratch:DI 2 "=&r") (const_int 0))
21837    (clobber (reg:CC FLAGS_REG))]
21838   "TARGET_64BIT"
21839   {
21840      /* The kernel uses a different segment register for performance reasons; a
21841         system call would not have to trash the userspace segment register,
21842         which would be expensive */
21843      if (ix86_cmodel != CM_KERNEL)
21844         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21845      else
21846         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21847   }
21848   [(set_attr "type" "multi")])
21849
21850 (define_expand "stack_protect_test"
21851   [(match_operand 0 "memory_operand" "")
21852    (match_operand 1 "memory_operand" "")
21853    (match_operand 2 "" "")]
21854   ""
21855 {
21856   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21857   ix86_compare_op0 = operands[0];
21858   ix86_compare_op1 = operands[1];
21859   ix86_compare_emitted = flags;
21860
21861 #ifdef TARGET_THREAD_SSP_OFFSET
21862   if (TARGET_64BIT)
21863     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21864                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21865   else
21866     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21867                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21868 #else
21869   if (TARGET_64BIT)
21870     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21871   else
21872     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21873 #endif
21874   emit_jump_insn (gen_beq (operands[2]));
21875   DONE;
21876 })
21877
21878 (define_insn "stack_protect_test_si"
21879   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21880         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21881                      (match_operand:SI 2 "memory_operand" "m")]
21882                     UNSPEC_SP_TEST))
21883    (clobber (match_scratch:SI 3 "=&r"))]
21884   ""
21885   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21886   [(set_attr "type" "multi")])
21887
21888 (define_insn "stack_protect_test_di"
21889   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21890         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21891                      (match_operand:DI 2 "memory_operand" "m")]
21892                     UNSPEC_SP_TEST))
21893    (clobber (match_scratch:DI 3 "=&r"))]
21894   "TARGET_64BIT"
21895   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21896   [(set_attr "type" "multi")])
21897
21898 (define_insn "stack_tls_protect_test_si"
21899   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21900         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21901                      (match_operand:SI 2 "const_int_operand" "i")]
21902                     UNSPEC_SP_TLS_TEST))
21903    (clobber (match_scratch:SI 3 "=r"))]
21904   ""
21905   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21906   [(set_attr "type" "multi")])
21907
21908 (define_insn "stack_tls_protect_test_di"
21909   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21910         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21911                      (match_operand:DI 2 "const_int_operand" "i")]
21912                     UNSPEC_SP_TLS_TEST))
21913    (clobber (match_scratch:DI 3 "=r"))]
21914   "TARGET_64BIT"
21915   {
21916      /* The kernel uses a different segment register for performance reasons; a
21917         system call would not have to trash the userspace segment register,
21918         which would be expensive */
21919      if (ix86_cmodel != CM_KERNEL)
21920         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21921      else
21922         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21923   }
21924   [(set_attr "type" "multi")])
21925
21926 (define_mode_iterator CRC32MODE [QI HI SI])
21927 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21928 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21929
21930 (define_insn "sse4_2_crc32<mode>"
21931   [(set (match_operand:SI 0 "register_operand" "=r")
21932         (unspec:SI
21933           [(match_operand:SI 1 "register_operand" "0")
21934            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21935           UNSPEC_CRC32))]
21936   "TARGET_SSE4_2"
21937   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21938   [(set_attr "type" "sselog1")
21939    (set_attr "prefix_rep" "1")
21940    (set_attr "prefix_extra" "1")
21941    (set_attr "mode" "SI")])
21942
21943 (define_insn "sse4_2_crc32di"
21944   [(set (match_operand:DI 0 "register_operand" "=r")
21945         (unspec:DI
21946           [(match_operand:DI 1 "register_operand" "0")
21947            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21948           UNSPEC_CRC32))]
21949   "TARGET_SSE4_2 && TARGET_64BIT"
21950   "crc32q\t{%2, %0|%0, %2}"
21951   [(set_attr "type" "sselog1")
21952    (set_attr "prefix_rep" "1")
21953    (set_attr "prefix_extra" "1")
21954    (set_attr "mode" "DI")])
21955
21956 (include "mmx.md")
21957 (include "sse.md")
21958 (include "sync.md")