OSDN Git Service

2009-05-18 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;;      otherwise nothing
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;;      delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;;      %b0 would print %al if operands[0] is reg 0.
47 ;; w --  likewise, print the HImode name of the register.
48 ;; k --  likewise, print the SImode name of the register.
49 ;; q --  likewise, print the DImode name of the register.
50 ;; x --  likewise, print the V4SFmode name of the register.
51 ;; t --  likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for SSE5 com* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63
64 ;; UNSPEC usage:
65
66 (define_constants
67   [; Relocation specifiers
68    (UNSPEC_GOT                  0)
69    (UNSPEC_GOTOFF               1)
70    (UNSPEC_GOTPCREL             2)
71    (UNSPEC_GOTTPOFF             3)
72    (UNSPEC_TPOFF                4)
73    (UNSPEC_NTPOFF               5)
74    (UNSPEC_DTPOFF               6)
75    (UNSPEC_GOTNTPOFF            7)
76    (UNSPEC_INDNTPOFF            8)
77    (UNSPEC_PLTOFF               9)
78    (UNSPEC_MACHOPIC_OFFSET      10)
79
80    ; Prologue support
81    (UNSPEC_STACK_ALLOC          11)
82    (UNSPEC_SET_GOT              12)
83    (UNSPEC_SSE_PROLOGUE_SAVE    13)
84    (UNSPEC_REG_SAVE             14)
85    (UNSPEC_DEF_CFA              15)
86    (UNSPEC_SET_RIP              16)
87    (UNSPEC_SET_GOT_OFFSET       17)
88    (UNSPEC_MEMORY_BLOCKAGE      18)
89
90    ; TLS support
91    (UNSPEC_TP                   20)
92    (UNSPEC_TLS_GD               21)
93    (UNSPEC_TLS_LD_BASE          22)
94    (UNSPEC_TLSDESC              23)
95
96    ; Other random patterns
97    (UNSPEC_SCAS                 30)
98    (UNSPEC_FNSTSW               31)
99    (UNSPEC_SAHF                 32)
100    (UNSPEC_FSTCW                33)
101    (UNSPEC_ADD_CARRY            34)
102    (UNSPEC_FLDCW                35)
103    (UNSPEC_REP                  36)
104    (UNSPEC_EH_RETURN            37)
105    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
106    (UNSPEC_TRUNC_NOOP           39)
107
108    ; For SSE/MMX support:
109    (UNSPEC_FIX_NOTRUNC          40)
110    (UNSPEC_MASKMOV              41)
111    (UNSPEC_MOVMSK               42)
112    (UNSPEC_MOVNT                43)
113    (UNSPEC_MOVU                 44)
114    (UNSPEC_RCP                  45)
115    (UNSPEC_RSQRT                46)
116    (UNSPEC_SFENCE               47)
117    (UNSPEC_PFRCP                49)
118    (UNSPEC_PFRCPIT1             40)
119    (UNSPEC_PFRCPIT2             41)
120    (UNSPEC_PFRSQRT              42)
121    (UNSPEC_PFRSQIT1             43)
122    (UNSPEC_MFENCE               44)
123    (UNSPEC_LFENCE               45)
124    (UNSPEC_PSADBW               46)
125    (UNSPEC_LDDQU                47)
126    (UNSPEC_MS_TO_SYSV_CALL      48)
127
128    ; Generic math support
129    (UNSPEC_COPYSIGN             50)
130    (UNSPEC_IEEE_MIN             51)     ; not commutative
131    (UNSPEC_IEEE_MAX             52)     ; not commutative
132
133    ; x87 Floating point
134    (UNSPEC_SIN                  60)
135    (UNSPEC_COS                  61)
136    (UNSPEC_FPATAN               62)
137    (UNSPEC_FYL2X                63)
138    (UNSPEC_FYL2XP1              64)
139    (UNSPEC_FRNDINT              65)
140    (UNSPEC_FIST                 66)
141    (UNSPEC_F2XM1                67)
142    (UNSPEC_TAN                  68)
143    (UNSPEC_FXAM                 69)
144
145    ; x87 Rounding
146    (UNSPEC_FRNDINT_FLOOR        70)
147    (UNSPEC_FRNDINT_CEIL         71)
148    (UNSPEC_FRNDINT_TRUNC        72)
149    (UNSPEC_FRNDINT_MASK_PM      73)
150    (UNSPEC_FIST_FLOOR           74)
151    (UNSPEC_FIST_CEIL            75)
152
153    ; x87 Double output FP
154    (UNSPEC_SINCOS_COS           80)
155    (UNSPEC_SINCOS_SIN           81)
156    (UNSPEC_XTRACT_FRACT         84)
157    (UNSPEC_XTRACT_EXP           85)
158    (UNSPEC_FSCALE_FRACT         86)
159    (UNSPEC_FSCALE_EXP           87)
160    (UNSPEC_FPREM_F              88)
161    (UNSPEC_FPREM_U              89)
162    (UNSPEC_FPREM1_F             90)
163    (UNSPEC_FPREM1_U             91)
164
165    (UNSPEC_C2_FLAG              95)
166    (UNSPEC_FXAM_MEM             96)
167
168    ; SSP patterns
169    (UNSPEC_SP_SET               100)
170    (UNSPEC_SP_TEST              101)
171    (UNSPEC_SP_TLS_SET           102)
172    (UNSPEC_SP_TLS_TEST          103)
173
174    ; SSSE3
175    (UNSPEC_PSHUFB               120)
176    (UNSPEC_PSIGN                121)
177    (UNSPEC_PALIGNR              122)
178
179    ; For SSE4A support
180    (UNSPEC_EXTRQI               130)
181    (UNSPEC_EXTRQ                131)
182    (UNSPEC_INSERTQI             132)
183    (UNSPEC_INSERTQ              133)
184
185    ; For SSE4.1 support
186    (UNSPEC_BLENDV               134)
187    (UNSPEC_INSERTPS             135)
188    (UNSPEC_DP                   136)
189    (UNSPEC_MOVNTDQA             137)
190    (UNSPEC_MPSADBW              138)
191    (UNSPEC_PHMINPOSUW           139)
192    (UNSPEC_PTEST                140)
193    (UNSPEC_ROUND                141)
194
195    ; For SSE4.2 support
196    (UNSPEC_CRC32                143)
197    (UNSPEC_PCMPESTR             144)
198    (UNSPEC_PCMPISTR             145)
199
200    ;; For SSE5
201    (UNSPEC_SSE5_INTRINSIC       150)
202    (UNSPEC_SSE5_UNSIGNED_CMP    151)
203    (UNSPEC_SSE5_TRUEFALSE       152)
204    (UNSPEC_SSE5_PERMUTE         153)
205    (UNSPEC_FRCZ                 154)
206    (UNSPEC_CVTPH2PS             155)
207    (UNSPEC_CVTPS2PH             156)
208
209    ; For AES support
210    (UNSPEC_AESENC               159)
211    (UNSPEC_AESENCLAST           160)
212    (UNSPEC_AESDEC               161)
213    (UNSPEC_AESDECLAST           162)
214    (UNSPEC_AESIMC               163)
215    (UNSPEC_AESKEYGENASSIST      164)
216
217    ; For PCLMUL support
218    (UNSPEC_PCLMUL               165)
219
220    ; For AVX support
221    (UNSPEC_PCMP                 166)
222    (UNSPEC_VPERMIL              167)
223    (UNSPEC_VPERMIL2F128         168)
224    (UNSPEC_MASKLOAD             169)
225    (UNSPEC_MASKSTORE            170)
226    (UNSPEC_CAST                 171)
227    (UNSPEC_VTESTP               172)
228   ])
229
230 (define_constants
231   [(UNSPECV_BLOCKAGE            0)
232    (UNSPECV_STACK_PROBE         1)
233    (UNSPECV_EMMS                2)
234    (UNSPECV_LDMXCSR             3)
235    (UNSPECV_STMXCSR             4)
236    (UNSPECV_FEMMS               5)
237    (UNSPECV_CLFLUSH             6)
238    (UNSPECV_ALIGN               7)
239    (UNSPECV_MONITOR             8)
240    (UNSPECV_MWAIT               9)
241    (UNSPECV_CMPXCHG             10)
242    (UNSPECV_XCHG                12)
243    (UNSPECV_LOCK                13)
244    (UNSPECV_PROLOGUE_USE        14)
245    (UNSPECV_CLD                 15)
246    (UNSPECV_VZEROALL            16)
247    (UNSPECV_VZEROUPPER          17)
248   ])
249
250 ;; Constants to represent pcomtrue/pcomfalse variants
251 (define_constants
252   [(PCOM_FALSE                  0)
253    (PCOM_TRUE                   1)
254    (COM_FALSE_S                 2)
255    (COM_FALSE_P                 3)
256    (COM_TRUE_S                  4)
257    (COM_TRUE_P                  5)
258   ])
259
260 ;; Constants used in the SSE5 pperm instruction
261 (define_constants
262   [(PPERM_SRC                   0x00)   /* copy source */
263    (PPERM_INVERT                0x20)   /* invert source */
264    (PPERM_REVERSE               0x40)   /* bit reverse source */
265    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
266    (PPERM_ZERO                  0x80)   /* all 0's */
267    (PPERM_ONES                  0xa0)   /* all 1's */
268    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
269    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
270    (PPERM_SRC1                  0x00)   /* use first source byte */
271    (PPERM_SRC2                  0x10)   /* use second source byte */
272    ])
273
274 ;; Registers by name.
275 (define_constants
276   [(AX_REG                       0)
277    (DX_REG                       1)
278    (CX_REG                       2)
279    (BX_REG                       3)
280    (SI_REG                       4)
281    (DI_REG                       5)
282    (BP_REG                       6)
283    (SP_REG                       7)
284    (ST0_REG                      8)
285    (ST1_REG                      9)
286    (ST2_REG                     10)
287    (ST3_REG                     11)
288    (ST4_REG                     12)
289    (ST5_REG                     13)
290    (ST6_REG                     14)
291    (ST7_REG                     15)
292    (FLAGS_REG                   17)
293    (FPSR_REG                    18)
294    (FPCR_REG                    19)
295    (XMM0_REG                    21)
296    (XMM1_REG                    22)
297    (XMM2_REG                    23)
298    (XMM3_REG                    24)
299    (XMM4_REG                    25)
300    (XMM5_REG                    26)
301    (XMM6_REG                    27)
302    (XMM7_REG                    28)
303    (MM0_REG                     29)
304    (MM1_REG                     30)
305    (MM2_REG                     31)
306    (MM3_REG                     32)
307    (MM4_REG                     33)
308    (MM5_REG                     34)
309    (MM6_REG                     35)
310    (MM7_REG                     36)
311    (R8_REG                      37)
312    (R9_REG                      38)
313    (R10_REG                     39)
314    (R11_REG                     40)
315    (R13_REG                     42)
316    (XMM8_REG                    45)
317    (XMM9_REG                    46)
318    (XMM10_REG                   47)
319    (XMM11_REG                   48)
320    (XMM12_REG                   49)
321    (XMM13_REG                   50)
322    (XMM14_REG                   51)
323    (XMM15_REG                   52)
324   ])
325
326 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
327 ;; from i386.c.
328
329 ;; In C guard expressions, put expressions which may be compile-time
330 ;; constants first.  This allows for better optimization.  For
331 ;; example, write "TARGET_64BIT && reload_completed", not
332 ;; "reload_completed && TARGET_64BIT".
333
334 \f
335 ;; Processor type.
336 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
337                     generic64,amdfam10"
338   (const (symbol_ref "ix86_schedule")))
339
340 ;; A basic instruction type.  Refinements due to arguments to be
341 ;; provided in other attributes.
342 (define_attr "type"
343   "other,multi,
344    alu,alu1,negnot,imov,imovx,lea,
345    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
346    icmp,test,ibr,setcc,icmov,
347    push,pop,call,callv,leave,
348    str,bitmanip,
349    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
350    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
351    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
352    ssemuladd,sse4arg,
353    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
354   (const_string "other"))
355
356 ;; Main data type used by the insn
357 (define_attr "mode"
358   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
359   (const_string "unknown"))
360
361 ;; The CPU unit operations uses.
362 (define_attr "unit" "integer,i387,sse,mmx,unknown"
363   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
364            (const_string "i387")
365          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
366                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
367                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
368            (const_string "sse")
369          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
370            (const_string "mmx")
371          (eq_attr "type" "other")
372            (const_string "unknown")]
373          (const_string "integer")))
374
375 ;; The (bounding maximum) length of an instruction immediate.
376 (define_attr "length_immediate" ""
377   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
378                           bitmanip")
379            (const_int 0)
380          (eq_attr "unit" "i387,sse,mmx")
381            (const_int 0)
382          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
383                           imul,icmp,push,pop")
384            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
385          (eq_attr "type" "imov,test")
386            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
387          (eq_attr "type" "call")
388            (if_then_else (match_operand 0 "constant_call_address_operand" "")
389              (const_int 4)
390              (const_int 0))
391          (eq_attr "type" "callv")
392            (if_then_else (match_operand 1 "constant_call_address_operand" "")
393              (const_int 4)
394              (const_int 0))
395          ;; We don't know the size before shorten_branches.  Expect
396          ;; the instruction to fit for better scheduling.
397          (eq_attr "type" "ibr")
398            (const_int 1)
399          ]
400          (symbol_ref "/* Update immediate_length and other attributes! */
401                       gcc_unreachable (),1")))
402
403 ;; The (bounding maximum) length of an instruction address.
404 (define_attr "length_address" ""
405   (cond [(eq_attr "type" "str,other,multi,fxch")
406            (const_int 0)
407          (and (eq_attr "type" "call")
408               (match_operand 0 "constant_call_address_operand" ""))
409              (const_int 0)
410          (and (eq_attr "type" "callv")
411               (match_operand 1 "constant_call_address_operand" ""))
412              (const_int 0)
413          ]
414          (symbol_ref "ix86_attr_length_address_default (insn)")))
415
416 ;; Set when length prefix is used.
417 (define_attr "prefix_data16" ""
418   (if_then_else (ior (eq_attr "mode" "HI")
419                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
420     (const_int 1)
421     (const_int 0)))
422
423 ;; Set when string REP prefix is used.
424 (define_attr "prefix_rep" ""
425   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
426     (const_int 1)
427     (const_int 0)))
428
429 ;; Set when 0f opcode prefix is used.
430 (define_attr "prefix_0f" ""
431   (if_then_else
432     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
433          (eq_attr "unit" "sse,mmx"))
434     (const_int 1)
435     (const_int 0)))
436
437 ;; Set when REX opcode prefix is used.
438 (define_attr "prefix_rex" ""
439   (cond [(and (eq_attr "mode" "DI")
440               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
441            (const_int 1)
442          (and (eq_attr "mode" "QI")
443               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
444                   (const_int 0)))
445            (const_int 1)
446          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
447              (const_int 0))
448            (const_int 1)
449         ]
450         (const_int 0)))
451
452 ;; There are also additional prefixes in SSSE3.
453 (define_attr "prefix_extra" "" (const_int 0))
454
455 ;; Prefix used: original, VEX or maybe VEX.
456 (define_attr "prefix" "orig,vex,maybe_vex"
457   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
458     (const_string "vex")
459     (const_string "orig")))
460
461 ;; There is a 8bit immediate for VEX.
462 (define_attr "prefix_vex_imm8" "" (const_int 0))
463
464 ;; VEX W bit is used.
465 (define_attr "prefix_vex_w" "" (const_int 0))
466
467 ;; The length of VEX prefix
468 (define_attr "length_vex" ""
469   (if_then_else (eq_attr "prefix_0f" "1")
470     (if_then_else (eq_attr "prefix_vex_w" "1")
471       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
472       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
473     (if_then_else (eq_attr "prefix_vex_w" "1")
474       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
475       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
476
477 ;; Set when modrm byte is used.
478 (define_attr "modrm" ""
479   (cond [(eq_attr "type" "str,leave")
480            (const_int 0)
481          (eq_attr "unit" "i387")
482            (const_int 0)
483          (and (eq_attr "type" "incdec")
484               (ior (match_operand:SI 1 "register_operand" "")
485                    (match_operand:HI 1 "register_operand" "")))
486            (const_int 0)
487          (and (eq_attr "type" "push")
488               (not (match_operand 1 "memory_operand" "")))
489            (const_int 0)
490          (and (eq_attr "type" "pop")
491               (not (match_operand 0 "memory_operand" "")))
492            (const_int 0)
493          (and (eq_attr "type" "imov")
494               (ior (and (match_operand 0 "register_operand" "")
495                         (match_operand 1 "immediate_operand" ""))
496                    (ior (and (match_operand 0 "ax_reg_operand" "")
497                              (match_operand 1 "memory_displacement_only_operand" ""))
498                         (and (match_operand 0 "memory_displacement_only_operand" "")
499                              (match_operand 1 "ax_reg_operand" "")))))
500            (const_int 0)
501          (and (eq_attr "type" "call")
502               (match_operand 0 "constant_call_address_operand" ""))
503              (const_int 0)
504          (and (eq_attr "type" "callv")
505               (match_operand 1 "constant_call_address_operand" ""))
506              (const_int 0)
507          ]
508          (const_int 1)))
509
510 ;; The (bounding maximum) length of an instruction in bytes.
511 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
512 ;; Later we may want to split them and compute proper length as for
513 ;; other insns.
514 (define_attr "length" ""
515   (cond [(eq_attr "type" "other,multi,fistp,frndint")
516            (const_int 16)
517          (eq_attr "type" "fcmp")
518            (const_int 4)
519          (eq_attr "unit" "i387")
520            (plus (const_int 2)
521                  (plus (attr "prefix_data16")
522                        (attr "length_address")))
523          (ior (eq_attr "prefix" "vex")
524               (and (eq_attr "prefix" "maybe_vex")
525                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
526            (plus (attr "length_vex")
527                  (plus (attr "prefix_vex_imm8")
528                        (plus (attr "modrm")
529                              (attr "length_address"))))]
530          (plus (plus (attr "modrm")
531                      (plus (attr "prefix_0f")
532                            (plus (attr "prefix_rex")
533                                  (plus (attr "prefix_extra")
534                                        (const_int 1)))))
535                (plus (attr "prefix_rep")
536                      (plus (attr "prefix_data16")
537                            (plus (attr "length_immediate")
538                                  (attr "length_address")))))))
539
540 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
541 ;; `store' if there is a simple memory reference therein, or `unknown'
542 ;; if the instruction is complex.
543
544 (define_attr "memory" "none,load,store,both,unknown"
545   (cond [(eq_attr "type" "other,multi,str")
546            (const_string "unknown")
547          (eq_attr "type" "lea,fcmov,fpspc")
548            (const_string "none")
549          (eq_attr "type" "fistp,leave")
550            (const_string "both")
551          (eq_attr "type" "frndint")
552            (const_string "load")
553          (eq_attr "type" "push")
554            (if_then_else (match_operand 1 "memory_operand" "")
555              (const_string "both")
556              (const_string "store"))
557          (eq_attr "type" "pop")
558            (if_then_else (match_operand 0 "memory_operand" "")
559              (const_string "both")
560              (const_string "load"))
561          (eq_attr "type" "setcc")
562            (if_then_else (match_operand 0 "memory_operand" "")
563              (const_string "store")
564              (const_string "none"))
565          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
566            (if_then_else (ior (match_operand 0 "memory_operand" "")
567                               (match_operand 1 "memory_operand" ""))
568              (const_string "load")
569              (const_string "none"))
570          (eq_attr "type" "ibr")
571            (if_then_else (match_operand 0 "memory_operand" "")
572              (const_string "load")
573              (const_string "none"))
574          (eq_attr "type" "call")
575            (if_then_else (match_operand 0 "constant_call_address_operand" "")
576              (const_string "none")
577              (const_string "load"))
578          (eq_attr "type" "callv")
579            (if_then_else (match_operand 1 "constant_call_address_operand" "")
580              (const_string "none")
581              (const_string "load"))
582          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
583               (match_operand 1 "memory_operand" ""))
584            (const_string "both")
585          (and (match_operand 0 "memory_operand" "")
586               (match_operand 1 "memory_operand" ""))
587            (const_string "both")
588          (match_operand 0 "memory_operand" "")
589            (const_string "store")
590          (match_operand 1 "memory_operand" "")
591            (const_string "load")
592          (and (eq_attr "type"
593                  "!alu1,negnot,ishift1,
594                    imov,imovx,icmp,test,bitmanip,
595                    fmov,fcmp,fsgn,
596                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
597                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
598               (match_operand 2 "memory_operand" ""))
599            (const_string "load")
600          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
601               (match_operand 3 "memory_operand" ""))
602            (const_string "load")
603         ]
604         (const_string "none")))
605
606 ;; Indicates if an instruction has both an immediate and a displacement.
607
608 (define_attr "imm_disp" "false,true,unknown"
609   (cond [(eq_attr "type" "other,multi")
610            (const_string "unknown")
611          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
612               (and (match_operand 0 "memory_displacement_operand" "")
613                    (match_operand 1 "immediate_operand" "")))
614            (const_string "true")
615          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
616               (and (match_operand 0 "memory_displacement_operand" "")
617                    (match_operand 2 "immediate_operand" "")))
618            (const_string "true")
619         ]
620         (const_string "false")))
621
622 ;; Indicates if an FP operation has an integer source.
623
624 (define_attr "fp_int_src" "false,true"
625   (const_string "false"))
626
627 ;; Defines rounding mode of an FP operation.
628
629 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
630   (const_string "any"))
631
632 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
633 (define_attr "use_carry" "0,1" (const_string "0"))
634
635 ;; Define attribute to indicate unaligned ssemov insns
636 (define_attr "movu" "0,1" (const_string "0"))
637
638 ;; Describe a user's asm statement.
639 (define_asm_attributes
640   [(set_attr "length" "128")
641    (set_attr "type" "multi")])
642
643 ;; All integer comparison codes.
644 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
645
646 ;; All floating-point comparison codes.
647 (define_code_iterator fp_cond [unordered ordered
648                                uneq unge ungt unle unlt ltgt ])
649
650 (define_code_iterator plusminus [plus minus])
651
652 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
653
654 ;; Base name for define_insn
655 (define_code_attr plusminus_insn
656   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
657    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
658
659 ;; Base name for insn mnemonic.
660 (define_code_attr plusminus_mnemonic
661   [(plus "add") (ss_plus "adds") (us_plus "addus")
662    (minus "sub") (ss_minus "subs") (us_minus "subus")])
663
664 ;; Mark commutative operators as such in constraints.
665 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
666                         (minus "") (ss_minus "") (us_minus "")])
667
668 ;; Mapping of signed max and min
669 (define_code_iterator smaxmin [smax smin])
670
671 ;; Mapping of unsigned max and min
672 (define_code_iterator umaxmin [umax umin])
673
674 ;; Mapping of signed/unsigned max and min
675 (define_code_iterator maxmin [smax smin umax umin])
676
677 ;; Base name for integer and FP insn mnemonic
678 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
679                                  (umax "maxu") (umin "minu")])
680 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
681
682 ;; Mapping of parallel logic operators
683 (define_code_iterator plogic [and ior xor])
684
685 ;; Base name for insn mnemonic.
686 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
687
688 ;; Mapping of abs neg operators
689 (define_code_iterator absneg [abs neg])
690
691 ;; Base name for x87 insn mnemonic.
692 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
693
694 ;; All single word integer modes.
695 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
696
697 ;; Single word integer modes without QImode.
698 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
699
700 ;; Instruction suffix for integer modes.
701 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
702
703 ;; Register class for integer modes.
704 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
705
706 ;; Immediate operand constraint for integer modes.
707 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
708
709 ;; General operand predicate for integer modes.
710 (define_mode_attr general_operand
711         [(QI "general_operand")
712          (HI "general_operand")
713          (SI "general_operand")
714          (DI "x86_64_general_operand")])
715
716 ;; SSE and x87 SFmode and DFmode floating point modes
717 (define_mode_iterator MODEF [SF DF])
718
719 ;; All x87 floating point modes
720 (define_mode_iterator X87MODEF [SF DF XF])
721
722 ;; All integer modes handled by x87 fisttp operator.
723 (define_mode_iterator X87MODEI [HI SI DI])
724
725 ;; All integer modes handled by integer x87 operators.
726 (define_mode_iterator X87MODEI12 [HI SI])
727
728 ;; All integer modes handled by SSE cvtts?2si* operators.
729 (define_mode_iterator SSEMODEI24 [SI DI])
730
731 ;; SSE asm suffix for floating point modes
732 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
733
734 ;; SSE vector mode corresponding to a scalar mode
735 (define_mode_attr ssevecmode
736   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
737
738 ;; Instruction suffix for REX 64bit operators.
739 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
740
741 ;; This mode iterator allows :P to be used for patterns that operate on
742 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
743 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
744
745 \f
746 ;; Scheduling descriptions
747
748 (include "pentium.md")
749 (include "ppro.md")
750 (include "k6.md")
751 (include "athlon.md")
752 (include "geode.md")
753 (include "atom.md")
754
755 \f
756 ;; Operand and operator predicates and constraints
757
758 (include "predicates.md")
759 (include "constraints.md")
760
761 \f
762 ;; Compare and branch/compare and store instructions.
763
764 (define_expand "cbranchti4"
765   [(set (reg:CC FLAGS_REG)
766         (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
767                     (match_operand:TI 2 "x86_64_general_operand" "")))
768    (set (pc) (if_then_else
769               (match_operator 0 "comparison_operator"
770                [(reg:CC FLAGS_REG)
771                 (const_int 0)])
772               (label_ref (match_operand 3 "" ""))
773               (pc)))]
774   "TARGET_64BIT"
775 {
776   if (MEM_P (operands[1]) && MEM_P (operands[2]))
777     operands[1] = force_reg (TImode, operands[1]);
778   ix86_compare_op0 = operands[1];
779   ix86_compare_op1 = operands[2];
780   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
781   DONE;
782 })
783
784 (define_expand "cbranchdi4"
785   [(set (reg:CC FLAGS_REG)
786         (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
787                     (match_operand:DI 2 "x86_64_general_operand" "")))
788    (set (pc) (if_then_else
789               (match_operator 0 "comparison_operator"
790                [(reg:CC FLAGS_REG)
791                 (const_int 0)])
792               (label_ref (match_operand 3 "" ""))
793               (pc)))]
794   ""
795 {
796   if (MEM_P (operands[1]) && MEM_P (operands[2]))
797     operands[1] = force_reg (DImode, operands[1]);
798   ix86_compare_op0 = operands[1];
799   ix86_compare_op1 = operands[2];
800   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
801   DONE;
802 })
803
804 (define_expand "cstoredi4"
805   [(set (reg:CC FLAGS_REG)
806         (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
807                     (match_operand:DI 3 "x86_64_general_operand" "")))
808    (set (match_operand:QI 0 "register_operand" "")
809               (match_operator 1 "comparison_operator"
810                [(reg:CC FLAGS_REG)
811                 (const_int 0)]))]
812   "TARGET_64BIT"
813 {
814   if (MEM_P (operands[2]) && MEM_P (operands[3]))
815     operands[2] = force_reg (DImode, operands[2]);
816   ix86_compare_op0 = operands[2];
817   ix86_compare_op1 = operands[3];
818   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
819   DONE;
820 })
821
822 (define_expand "cbranchsi4"
823   [(set (reg:CC FLAGS_REG)
824         (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
825                     (match_operand:SI 2 "general_operand" "")))
826    (set (pc) (if_then_else
827               (match_operator 0 "comparison_operator"
828                [(reg:CC FLAGS_REG)
829                 (const_int 0)])
830               (label_ref (match_operand 3 "" ""))
831               (pc)))]
832   ""
833 {
834   if (MEM_P (operands[1]) && MEM_P (operands[2]))
835     operands[1] = force_reg (SImode, operands[1]);
836   ix86_compare_op0 = operands[1];
837   ix86_compare_op1 = operands[2];
838   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
839   DONE;
840 })
841
842 (define_expand "cstoresi4"
843   [(set (reg:CC FLAGS_REG)
844         (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
845                     (match_operand:SI 3 "general_operand" "")))
846    (set (match_operand:QI 0 "register_operand" "")
847               (match_operator 1 "comparison_operator"
848                [(reg:CC FLAGS_REG)
849                 (const_int 0)]))]
850   ""
851 {
852   if (MEM_P (operands[2]) && MEM_P (operands[3]))
853     operands[2] = force_reg (SImode, operands[2]);
854   ix86_compare_op0 = operands[2];
855   ix86_compare_op1 = operands[3];
856   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
857   DONE;
858 })
859
860 (define_expand "cbranchhi4"
861   [(set (reg:CC FLAGS_REG)
862         (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
863                     (match_operand:HI 2 "general_operand" "")))
864    (set (pc) (if_then_else
865               (match_operator 0 "comparison_operator"
866                [(reg:CC FLAGS_REG)
867                 (const_int 0)])
868               (label_ref (match_operand 3 "" ""))
869               (pc)))]
870   ""
871 {
872   if (MEM_P (operands[1]) && MEM_P (operands[2]))
873     operands[1] = force_reg (HImode, operands[1]);
874   ix86_compare_op0 = operands[1];
875   ix86_compare_op1 = operands[2];
876   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
877   DONE;
878 })
879
880 (define_expand "cstorehi4"
881   [(set (reg:CC FLAGS_REG)
882         (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
883                     (match_operand:HI 3 "general_operand" "")))
884    (set (match_operand:QI 0 "register_operand" "")
885               (match_operator 1 "comparison_operator"
886                [(reg:CC FLAGS_REG)
887                 (const_int 0)]))]
888   ""
889 {
890   if (MEM_P (operands[2]) && MEM_P (operands[3]))
891     operands[2] = force_reg (HImode, operands[2]);
892   ix86_compare_op0 = operands[2];
893   ix86_compare_op1 = operands[3];
894   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
895   DONE;
896 })
897
898
899 (define_expand "cbranchqi4"
900   [(set (reg:CC FLAGS_REG)
901         (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
902                     (match_operand:QI 2 "general_operand" "")))
903    (set (pc) (if_then_else
904               (match_operator 0 "comparison_operator"
905                [(reg:CC FLAGS_REG)
906                 (const_int 0)])
907               (label_ref (match_operand 3 "" ""))
908               (pc)))]
909   ""
910 {
911   if (MEM_P (operands[1]) && MEM_P (operands[2]))
912     operands[1] = force_reg (QImode, operands[1]);
913   ix86_compare_op0 = operands[1];
914   ix86_compare_op1 = operands[2];
915   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
916   DONE;
917 })
918
919
920 (define_expand "cstoreqi4"
921   [(set (reg:CC FLAGS_REG)
922         (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
923                     (match_operand:QI 3 "general_operand" "")))
924    (set (match_operand:QI 0 "register_operand" "")
925               (match_operator 1 "comparison_operator"
926                [(reg:CC FLAGS_REG)
927                 (const_int 0)]))]
928   ""
929 {
930   if (MEM_P (operands[2]) && MEM_P (operands[3]))
931     operands[2] = force_reg (QImode, operands[2]);
932   ix86_compare_op0 = operands[2];
933   ix86_compare_op1 = operands[3];
934   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
935   DONE;
936 })
937
938
939 (define_insn "cmpdi_ccno_1_rex64"
940   [(set (reg FLAGS_REG)
941         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
942                  (match_operand:DI 1 "const0_operand" "")))]
943   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
944   "@
945    test{q}\t%0, %0
946    cmp{q}\t{%1, %0|%0, %1}"
947   [(set_attr "type" "test,icmp")
948    (set_attr "length_immediate" "0,1")
949    (set_attr "mode" "DI")])
950
951 (define_insn "*cmpdi_minus_1_rex64"
952   [(set (reg FLAGS_REG)
953         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
954                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
955                  (const_int 0)))]
956   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
957   "cmp{q}\t{%1, %0|%0, %1}"
958   [(set_attr "type" "icmp")
959    (set_attr "mode" "DI")])
960
961 (define_expand "cmpdi_1_rex64"
962   [(set (reg:CC FLAGS_REG)
963         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
964                     (match_operand:DI 1 "general_operand" "")))]
965   "TARGET_64BIT"
966   "")
967
968 (define_insn "cmpdi_1_insn_rex64"
969   [(set (reg FLAGS_REG)
970         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
971                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
972   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
973   "cmp{q}\t{%1, %0|%0, %1}"
974   [(set_attr "type" "icmp")
975    (set_attr "mode" "DI")])
976
977
978 (define_insn "*cmpsi_ccno_1"
979   [(set (reg FLAGS_REG)
980         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
981                  (match_operand:SI 1 "const0_operand" "")))]
982   "ix86_match_ccmode (insn, CCNOmode)"
983   "@
984    test{l}\t%0, %0
985    cmp{l}\t{%1, %0|%0, %1}"
986   [(set_attr "type" "test,icmp")
987    (set_attr "length_immediate" "0,1")
988    (set_attr "mode" "SI")])
989
990 (define_insn "*cmpsi_minus_1"
991   [(set (reg FLAGS_REG)
992         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
993                            (match_operand:SI 1 "general_operand" "ri,mr"))
994                  (const_int 0)))]
995   "ix86_match_ccmode (insn, CCGOCmode)"
996   "cmp{l}\t{%1, %0|%0, %1}"
997   [(set_attr "type" "icmp")
998    (set_attr "mode" "SI")])
999
1000 (define_expand "cmpsi_1"
1001   [(set (reg:CC FLAGS_REG)
1002         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1003                     (match_operand:SI 1 "general_operand" "")))]
1004   ""
1005   "")
1006
1007 (define_insn "*cmpsi_1_insn"
1008   [(set (reg FLAGS_REG)
1009         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1010                  (match_operand:SI 1 "general_operand" "ri,mr")))]
1011   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1012     && ix86_match_ccmode (insn, CCmode)"
1013   "cmp{l}\t{%1, %0|%0, %1}"
1014   [(set_attr "type" "icmp")
1015    (set_attr "mode" "SI")])
1016
1017 (define_insn "*cmphi_ccno_1"
1018   [(set (reg FLAGS_REG)
1019         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1020                  (match_operand:HI 1 "const0_operand" "")))]
1021   "ix86_match_ccmode (insn, CCNOmode)"
1022   "@
1023    test{w}\t%0, %0
1024    cmp{w}\t{%1, %0|%0, %1}"
1025   [(set_attr "type" "test,icmp")
1026    (set_attr "length_immediate" "0,1")
1027    (set_attr "mode" "HI")])
1028
1029 (define_insn "*cmphi_minus_1"
1030   [(set (reg FLAGS_REG)
1031         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1032                            (match_operand:HI 1 "general_operand" "rn,mr"))
1033                  (const_int 0)))]
1034   "ix86_match_ccmode (insn, CCGOCmode)"
1035   "cmp{w}\t{%1, %0|%0, %1}"
1036   [(set_attr "type" "icmp")
1037    (set_attr "mode" "HI")])
1038
1039 (define_insn "*cmphi_1"
1040   [(set (reg FLAGS_REG)
1041         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1042                  (match_operand:HI 1 "general_operand" "rn,mr")))]
1043   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1044    && ix86_match_ccmode (insn, CCmode)"
1045   "cmp{w}\t{%1, %0|%0, %1}"
1046   [(set_attr "type" "icmp")
1047    (set_attr "mode" "HI")])
1048
1049 (define_insn "*cmpqi_ccno_1"
1050   [(set (reg FLAGS_REG)
1051         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1052                  (match_operand:QI 1 "const0_operand" "")))]
1053   "ix86_match_ccmode (insn, CCNOmode)"
1054   "@
1055    test{b}\t%0, %0
1056    cmp{b}\t{$0, %0|%0, 0}"
1057   [(set_attr "type" "test,icmp")
1058    (set_attr "length_immediate" "0,1")
1059    (set_attr "mode" "QI")])
1060
1061 (define_insn "*cmpqi_1"
1062   [(set (reg FLAGS_REG)
1063         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1064                  (match_operand:QI 1 "general_operand" "qn,mq")))]
1065   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1066     && ix86_match_ccmode (insn, CCmode)"
1067   "cmp{b}\t{%1, %0|%0, %1}"
1068   [(set_attr "type" "icmp")
1069    (set_attr "mode" "QI")])
1070
1071 (define_insn "*cmpqi_minus_1"
1072   [(set (reg FLAGS_REG)
1073         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1074                            (match_operand:QI 1 "general_operand" "qn,mq"))
1075                  (const_int 0)))]
1076   "ix86_match_ccmode (insn, CCGOCmode)"
1077   "cmp{b}\t{%1, %0|%0, %1}"
1078   [(set_attr "type" "icmp")
1079    (set_attr "mode" "QI")])
1080
1081 (define_insn "*cmpqi_ext_1"
1082   [(set (reg FLAGS_REG)
1083         (compare
1084           (match_operand:QI 0 "general_operand" "Qm")
1085           (subreg:QI
1086             (zero_extract:SI
1087               (match_operand 1 "ext_register_operand" "Q")
1088               (const_int 8)
1089               (const_int 8)) 0)))]
1090   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1091   "cmp{b}\t{%h1, %0|%0, %h1}"
1092   [(set_attr "type" "icmp")
1093    (set_attr "mode" "QI")])
1094
1095 (define_insn "*cmpqi_ext_1_rex64"
1096   [(set (reg FLAGS_REG)
1097         (compare
1098           (match_operand:QI 0 "register_operand" "Q")
1099           (subreg:QI
1100             (zero_extract:SI
1101               (match_operand 1 "ext_register_operand" "Q")
1102               (const_int 8)
1103               (const_int 8)) 0)))]
1104   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1105   "cmp{b}\t{%h1, %0|%0, %h1}"
1106   [(set_attr "type" "icmp")
1107    (set_attr "mode" "QI")])
1108
1109 (define_insn "*cmpqi_ext_2"
1110   [(set (reg FLAGS_REG)
1111         (compare
1112           (subreg:QI
1113             (zero_extract:SI
1114               (match_operand 0 "ext_register_operand" "Q")
1115               (const_int 8)
1116               (const_int 8)) 0)
1117           (match_operand:QI 1 "const0_operand" "")))]
1118   "ix86_match_ccmode (insn, CCNOmode)"
1119   "test{b}\t%h0, %h0"
1120   [(set_attr "type" "test")
1121    (set_attr "length_immediate" "0")
1122    (set_attr "mode" "QI")])
1123
1124 (define_expand "cmpqi_ext_3"
1125   [(set (reg:CC FLAGS_REG)
1126         (compare:CC
1127           (subreg:QI
1128             (zero_extract:SI
1129               (match_operand 0 "ext_register_operand" "")
1130               (const_int 8)
1131               (const_int 8)) 0)
1132           (match_operand:QI 1 "general_operand" "")))]
1133   ""
1134   "")
1135
1136 (define_insn "cmpqi_ext_3_insn"
1137   [(set (reg FLAGS_REG)
1138         (compare
1139           (subreg:QI
1140             (zero_extract:SI
1141               (match_operand 0 "ext_register_operand" "Q")
1142               (const_int 8)
1143               (const_int 8)) 0)
1144           (match_operand:QI 1 "general_operand" "Qmn")))]
1145   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1146   "cmp{b}\t{%1, %h0|%h0, %1}"
1147   [(set_attr "type" "icmp")
1148    (set_attr "mode" "QI")])
1149
1150 (define_insn "cmpqi_ext_3_insn_rex64"
1151   [(set (reg FLAGS_REG)
1152         (compare
1153           (subreg:QI
1154             (zero_extract:SI
1155               (match_operand 0 "ext_register_operand" "Q")
1156               (const_int 8)
1157               (const_int 8)) 0)
1158           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1159   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1160   "cmp{b}\t{%1, %h0|%h0, %1}"
1161   [(set_attr "type" "icmp")
1162    (set_attr "mode" "QI")])
1163
1164 (define_insn "*cmpqi_ext_4"
1165   [(set (reg FLAGS_REG)
1166         (compare
1167           (subreg:QI
1168             (zero_extract:SI
1169               (match_operand 0 "ext_register_operand" "Q")
1170               (const_int 8)
1171               (const_int 8)) 0)
1172           (subreg:QI
1173             (zero_extract:SI
1174               (match_operand 1 "ext_register_operand" "Q")
1175               (const_int 8)
1176               (const_int 8)) 0)))]
1177   "ix86_match_ccmode (insn, CCmode)"
1178   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1179   [(set_attr "type" "icmp")
1180    (set_attr "mode" "QI")])
1181
1182 ;; These implement float point compares.
1183 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1184 ;; which would allow mix and match FP modes on the compares.  Which is what
1185 ;; the old patterns did, but with many more of them.
1186
1187 (define_expand "cbranchxf4"
1188   [(set (reg:CC FLAGS_REG)
1189         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1190                     (match_operand:XF 2 "nonmemory_operand" "")))
1191    (set (pc) (if_then_else
1192               (match_operator 0 "comparison_operator"
1193                [(reg:CC FLAGS_REG)
1194                 (const_int 0)])
1195               (label_ref (match_operand 3 "" ""))
1196               (pc)))]
1197   "TARGET_80387"
1198 {
1199   ix86_compare_op0 = operands[1];
1200   ix86_compare_op1 = operands[2];
1201   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1202   DONE;
1203 })
1204
1205 (define_expand "cstorexf4"
1206   [(set (reg:CC FLAGS_REG)
1207         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1208                     (match_operand:XF 3 "nonmemory_operand" "")))
1209    (set (match_operand:QI 0 "register_operand" "")
1210               (match_operator 1 "comparison_operator"
1211                [(reg:CC FLAGS_REG)
1212                 (const_int 0)]))]
1213   "TARGET_80387"
1214 {
1215   ix86_compare_op0 = operands[2];
1216   ix86_compare_op1 = operands[3];
1217   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1218   DONE;
1219 })
1220
1221 (define_expand "cbranch<mode>4"
1222   [(set (reg:CC FLAGS_REG)
1223         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1224                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1225    (set (pc) (if_then_else
1226               (match_operator 0 "comparison_operator"
1227                [(reg:CC FLAGS_REG)
1228                 (const_int 0)])
1229               (label_ref (match_operand 3 "" ""))
1230               (pc)))]
1231   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1232 {
1233   ix86_compare_op0 = operands[1];
1234   ix86_compare_op1 = operands[2];
1235   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1236   DONE;
1237 })
1238
1239 (define_expand "cstore<mode>4"
1240   [(set (reg:CC FLAGS_REG)
1241         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1242                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1243    (set (match_operand:QI 0 "register_operand" "")
1244               (match_operator 1 "comparison_operator"
1245                [(reg:CC FLAGS_REG)
1246                 (const_int 0)]))]
1247   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1248 {
1249   ix86_compare_op0 = operands[2];
1250   ix86_compare_op1 = operands[3];
1251   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1252   DONE;
1253 })
1254
1255 (define_expand "cbranchcc4"
1256   [(set (pc) (if_then_else
1257               (match_operator 0 "comparison_operator"
1258                [(match_operand 1 "flags_reg_operand" "")
1259                 (match_operand 2 "const0_operand" "")])
1260               (label_ref (match_operand 3 "" ""))
1261               (pc)))]
1262   ""
1263 {
1264   ix86_compare_op0 = operands[1];
1265   ix86_compare_op1 = operands[2];
1266   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1267   DONE;
1268 })
1269
1270 (define_expand "cstorecc4"
1271   [(set (match_operand:QI 0 "register_operand" "")
1272               (match_operator 1 "comparison_operator"
1273                [(match_operand 2 "flags_reg_operand" "")
1274                 (match_operand 3 "const0_operand" "")]))]
1275   ""
1276 {
1277   ix86_compare_op0 = operands[2];
1278   ix86_compare_op1 = operands[3];
1279   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1280   DONE;
1281 })
1282
1283
1284 ;; FP compares, step 1:
1285 ;; Set the FP condition codes.
1286 ;;
1287 ;; CCFPmode     compare with exceptions
1288 ;; CCFPUmode    compare with no exceptions
1289
1290 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1291 ;; used to manage the reg stack popping would not be preserved.
1292
1293 (define_insn "*cmpfp_0"
1294   [(set (match_operand:HI 0 "register_operand" "=a")
1295         (unspec:HI
1296           [(compare:CCFP
1297              (match_operand 1 "register_operand" "f")
1298              (match_operand 2 "const0_operand" ""))]
1299         UNSPEC_FNSTSW))]
1300   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1301    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1302   "* return output_fp_compare (insn, operands, 0, 0);"
1303   [(set_attr "type" "multi")
1304    (set_attr "unit" "i387")
1305    (set (attr "mode")
1306      (cond [(match_operand:SF 1 "" "")
1307               (const_string "SF")
1308             (match_operand:DF 1 "" "")
1309               (const_string "DF")
1310            ]
1311            (const_string "XF")))])
1312
1313 (define_insn_and_split "*cmpfp_0_cc"
1314   [(set (reg:CCFP FLAGS_REG)
1315         (compare:CCFP
1316           (match_operand 1 "register_operand" "f")
1317           (match_operand 2 "const0_operand" "")))
1318    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1319   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1320    && TARGET_SAHF && !TARGET_CMOVE
1321    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1322   "#"
1323   "&& reload_completed"
1324   [(set (match_dup 0)
1325         (unspec:HI
1326           [(compare:CCFP (match_dup 1)(match_dup 2))]
1327         UNSPEC_FNSTSW))
1328    (set (reg:CC FLAGS_REG)
1329         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1330   ""
1331   [(set_attr "type" "multi")
1332    (set_attr "unit" "i387")
1333    (set (attr "mode")
1334      (cond [(match_operand:SF 1 "" "")
1335               (const_string "SF")
1336             (match_operand:DF 1 "" "")
1337               (const_string "DF")
1338            ]
1339            (const_string "XF")))])
1340
1341 (define_insn "*cmpfp_xf"
1342   [(set (match_operand:HI 0 "register_operand" "=a")
1343         (unspec:HI
1344           [(compare:CCFP
1345              (match_operand:XF 1 "register_operand" "f")
1346              (match_operand:XF 2 "register_operand" "f"))]
1347           UNSPEC_FNSTSW))]
1348   "TARGET_80387"
1349   "* return output_fp_compare (insn, operands, 0, 0);"
1350   [(set_attr "type" "multi")
1351    (set_attr "unit" "i387")
1352    (set_attr "mode" "XF")])
1353
1354 (define_insn_and_split "*cmpfp_xf_cc"
1355   [(set (reg:CCFP FLAGS_REG)
1356         (compare:CCFP
1357           (match_operand:XF 1 "register_operand" "f")
1358           (match_operand:XF 2 "register_operand" "f")))
1359    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1360   "TARGET_80387
1361    && TARGET_SAHF && !TARGET_CMOVE"
1362   "#"
1363   "&& reload_completed"
1364   [(set (match_dup 0)
1365         (unspec:HI
1366           [(compare:CCFP (match_dup 1)(match_dup 2))]
1367         UNSPEC_FNSTSW))
1368    (set (reg:CC FLAGS_REG)
1369         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1370   ""
1371   [(set_attr "type" "multi")
1372    (set_attr "unit" "i387")
1373    (set_attr "mode" "XF")])
1374
1375 (define_insn "*cmpfp_<mode>"
1376   [(set (match_operand:HI 0 "register_operand" "=a")
1377         (unspec:HI
1378           [(compare:CCFP
1379              (match_operand:MODEF 1 "register_operand" "f")
1380              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1381           UNSPEC_FNSTSW))]
1382   "TARGET_80387"
1383   "* return output_fp_compare (insn, operands, 0, 0);"
1384   [(set_attr "type" "multi")
1385    (set_attr "unit" "i387")
1386    (set_attr "mode" "<MODE>")])
1387
1388 (define_insn_and_split "*cmpfp_<mode>_cc"
1389   [(set (reg:CCFP FLAGS_REG)
1390         (compare:CCFP
1391           (match_operand:MODEF 1 "register_operand" "f")
1392           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1393    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394   "TARGET_80387
1395    && TARGET_SAHF && !TARGET_CMOVE"
1396   "#"
1397   "&& reload_completed"
1398   [(set (match_dup 0)
1399         (unspec:HI
1400           [(compare:CCFP (match_dup 1)(match_dup 2))]
1401         UNSPEC_FNSTSW))
1402    (set (reg:CC FLAGS_REG)
1403         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1404   ""
1405   [(set_attr "type" "multi")
1406    (set_attr "unit" "i387")
1407    (set_attr "mode" "<MODE>")])
1408
1409 (define_insn "*cmpfp_u"
1410   [(set (match_operand:HI 0 "register_operand" "=a")
1411         (unspec:HI
1412           [(compare:CCFPU
1413              (match_operand 1 "register_operand" "f")
1414              (match_operand 2 "register_operand" "f"))]
1415           UNSPEC_FNSTSW))]
1416   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1417    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1418   "* return output_fp_compare (insn, operands, 0, 1);"
1419   [(set_attr "type" "multi")
1420    (set_attr "unit" "i387")
1421    (set (attr "mode")
1422      (cond [(match_operand:SF 1 "" "")
1423               (const_string "SF")
1424             (match_operand:DF 1 "" "")
1425               (const_string "DF")
1426            ]
1427            (const_string "XF")))])
1428
1429 (define_insn_and_split "*cmpfp_u_cc"
1430   [(set (reg:CCFPU FLAGS_REG)
1431         (compare:CCFPU
1432           (match_operand 1 "register_operand" "f")
1433           (match_operand 2 "register_operand" "f")))
1434    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1435   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1436    && TARGET_SAHF && !TARGET_CMOVE
1437    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1438   "#"
1439   "&& reload_completed"
1440   [(set (match_dup 0)
1441         (unspec:HI
1442           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1443         UNSPEC_FNSTSW))
1444    (set (reg:CC FLAGS_REG)
1445         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1446   ""
1447   [(set_attr "type" "multi")
1448    (set_attr "unit" "i387")
1449    (set (attr "mode")
1450      (cond [(match_operand:SF 1 "" "")
1451               (const_string "SF")
1452             (match_operand:DF 1 "" "")
1453               (const_string "DF")
1454            ]
1455            (const_string "XF")))])
1456
1457 (define_insn "*cmpfp_<mode>"
1458   [(set (match_operand:HI 0 "register_operand" "=a")
1459         (unspec:HI
1460           [(compare:CCFP
1461              (match_operand 1 "register_operand" "f")
1462              (match_operator 3 "float_operator"
1463                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1464           UNSPEC_FNSTSW))]
1465   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1466    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1467    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1468   "* return output_fp_compare (insn, operands, 0, 0);"
1469   [(set_attr "type" "multi")
1470    (set_attr "unit" "i387")
1471    (set_attr "fp_int_src" "true")
1472    (set_attr "mode" "<MODE>")])
1473
1474 (define_insn_and_split "*cmpfp_<mode>_cc"
1475   [(set (reg:CCFP FLAGS_REG)
1476         (compare:CCFP
1477           (match_operand 1 "register_operand" "f")
1478           (match_operator 3 "float_operator"
1479             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1480    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1481   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1482    && TARGET_SAHF && !TARGET_CMOVE
1483    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1484    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1485   "#"
1486   "&& reload_completed"
1487   [(set (match_dup 0)
1488         (unspec:HI
1489           [(compare:CCFP
1490              (match_dup 1)
1491              (match_op_dup 3 [(match_dup 2)]))]
1492         UNSPEC_FNSTSW))
1493    (set (reg:CC FLAGS_REG)
1494         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1495   ""
1496   [(set_attr "type" "multi")
1497    (set_attr "unit" "i387")
1498    (set_attr "fp_int_src" "true")
1499    (set_attr "mode" "<MODE>")])
1500
1501 ;; FP compares, step 2
1502 ;; Move the fpsw to ax.
1503
1504 (define_insn "x86_fnstsw_1"
1505   [(set (match_operand:HI 0 "register_operand" "=a")
1506         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1507   "TARGET_80387"
1508   "fnstsw\t%0"
1509   [(set_attr "length" "2")
1510    (set_attr "mode" "SI")
1511    (set_attr "unit" "i387")])
1512
1513 ;; FP compares, step 3
1514 ;; Get ax into flags, general case.
1515
1516 (define_insn "x86_sahf_1"
1517   [(set (reg:CC FLAGS_REG)
1518         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1519                    UNSPEC_SAHF))]
1520   "TARGET_SAHF"
1521 {
1522 #ifdef HAVE_AS_IX86_SAHF
1523   return "sahf";
1524 #else
1525   return ".byte\t0x9e";
1526 #endif
1527 }
1528   [(set_attr "length" "1")
1529    (set_attr "athlon_decode" "vector")
1530    (set_attr "amdfam10_decode" "direct")
1531    (set_attr "mode" "SI")])
1532
1533 ;; Pentium Pro can do steps 1 through 3 in one go.
1534 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1535 (define_insn "*cmpfp_i_mixed"
1536   [(set (reg:CCFP FLAGS_REG)
1537         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1538                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1539   "TARGET_MIX_SSE_I387
1540    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1541    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1542   "* return output_fp_compare (insn, operands, 1, 0);"
1543   [(set_attr "type" "fcmp,ssecomi")
1544    (set_attr "prefix" "orig,maybe_vex")
1545    (set (attr "mode")
1546      (if_then_else (match_operand:SF 1 "" "")
1547         (const_string "SF")
1548         (const_string "DF")))
1549    (set_attr "athlon_decode" "vector")
1550    (set_attr "amdfam10_decode" "direct")])
1551
1552 (define_insn "*cmpfp_i_sse"
1553   [(set (reg:CCFP FLAGS_REG)
1554         (compare:CCFP (match_operand 0 "register_operand" "x")
1555                       (match_operand 1 "nonimmediate_operand" "xm")))]
1556   "TARGET_SSE_MATH
1557    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1558    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1559   "* return output_fp_compare (insn, operands, 1, 0);"
1560   [(set_attr "type" "ssecomi")
1561    (set_attr "prefix" "maybe_vex")
1562    (set (attr "mode")
1563      (if_then_else (match_operand:SF 1 "" "")
1564         (const_string "SF")
1565         (const_string "DF")))
1566    (set_attr "athlon_decode" "vector")
1567    (set_attr "amdfam10_decode" "direct")])
1568
1569 (define_insn "*cmpfp_i_i387"
1570   [(set (reg:CCFP FLAGS_REG)
1571         (compare:CCFP (match_operand 0 "register_operand" "f")
1572                       (match_operand 1 "register_operand" "f")))]
1573   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1574    && TARGET_CMOVE
1575    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1576    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1577   "* return output_fp_compare (insn, operands, 1, 0);"
1578   [(set_attr "type" "fcmp")
1579    (set (attr "mode")
1580      (cond [(match_operand:SF 1 "" "")
1581               (const_string "SF")
1582             (match_operand:DF 1 "" "")
1583               (const_string "DF")
1584            ]
1585            (const_string "XF")))
1586    (set_attr "athlon_decode" "vector")
1587    (set_attr "amdfam10_decode" "direct")])
1588
1589 (define_insn "*cmpfp_iu_mixed"
1590   [(set (reg:CCFPU FLAGS_REG)
1591         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1592                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1593   "TARGET_MIX_SSE_I387
1594    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1595    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1596   "* return output_fp_compare (insn, operands, 1, 1);"
1597   [(set_attr "type" "fcmp,ssecomi")
1598    (set_attr "prefix" "orig,maybe_vex")
1599    (set (attr "mode")
1600      (if_then_else (match_operand:SF 1 "" "")
1601         (const_string "SF")
1602         (const_string "DF")))
1603    (set_attr "athlon_decode" "vector")
1604    (set_attr "amdfam10_decode" "direct")])
1605
1606 (define_insn "*cmpfp_iu_sse"
1607   [(set (reg:CCFPU FLAGS_REG)
1608         (compare:CCFPU (match_operand 0 "register_operand" "x")
1609                        (match_operand 1 "nonimmediate_operand" "xm")))]
1610   "TARGET_SSE_MATH
1611    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1612    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1613   "* return output_fp_compare (insn, operands, 1, 1);"
1614   [(set_attr "type" "ssecomi")
1615    (set_attr "prefix" "maybe_vex")
1616    (set (attr "mode")
1617      (if_then_else (match_operand:SF 1 "" "")
1618         (const_string "SF")
1619         (const_string "DF")))
1620    (set_attr "athlon_decode" "vector")
1621    (set_attr "amdfam10_decode" "direct")])
1622
1623 (define_insn "*cmpfp_iu_387"
1624   [(set (reg:CCFPU FLAGS_REG)
1625         (compare:CCFPU (match_operand 0 "register_operand" "f")
1626                        (match_operand 1 "register_operand" "f")))]
1627   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1628    && TARGET_CMOVE
1629    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1630    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1631   "* return output_fp_compare (insn, operands, 1, 1);"
1632   [(set_attr "type" "fcmp")
1633    (set (attr "mode")
1634      (cond [(match_operand:SF 1 "" "")
1635               (const_string "SF")
1636             (match_operand:DF 1 "" "")
1637               (const_string "DF")
1638            ]
1639            (const_string "XF")))
1640    (set_attr "athlon_decode" "vector")
1641    (set_attr "amdfam10_decode" "direct")])
1642 \f
1643 ;; Move instructions.
1644
1645 ;; General case of fullword move.
1646
1647 (define_expand "movsi"
1648   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1649         (match_operand:SI 1 "general_operand" ""))]
1650   ""
1651   "ix86_expand_move (SImode, operands); DONE;")
1652
1653 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1654 ;; general_operand.
1655 ;;
1656 ;; %%% We don't use a post-inc memory reference because x86 is not a
1657 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1658 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1659 ;; targets without our curiosities, and it is just as easy to represent
1660 ;; this differently.
1661
1662 (define_insn "*pushsi2"
1663   [(set (match_operand:SI 0 "push_operand" "=<")
1664         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1665   "!TARGET_64BIT"
1666   "push{l}\t%1"
1667   [(set_attr "type" "push")
1668    (set_attr "mode" "SI")])
1669
1670 ;; For 64BIT abi we always round up to 8 bytes.
1671 (define_insn "*pushsi2_rex64"
1672   [(set (match_operand:SI 0 "push_operand" "=X")
1673         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1674   "TARGET_64BIT"
1675   "push{q}\t%q1"
1676   [(set_attr "type" "push")
1677    (set_attr "mode" "SI")])
1678
1679 (define_insn "*pushsi2_prologue"
1680   [(set (match_operand:SI 0 "push_operand" "=<")
1681         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1682    (clobber (mem:BLK (scratch)))]
1683   "!TARGET_64BIT"
1684   "push{l}\t%1"
1685   [(set_attr "type" "push")
1686    (set_attr "mode" "SI")])
1687
1688 (define_insn "*popsi1_epilogue"
1689   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1690         (mem:SI (reg:SI SP_REG)))
1691    (set (reg:SI SP_REG)
1692         (plus:SI (reg:SI SP_REG) (const_int 4)))
1693    (clobber (mem:BLK (scratch)))]
1694   "!TARGET_64BIT"
1695   "pop{l}\t%0"
1696   [(set_attr "type" "pop")
1697    (set_attr "mode" "SI")])
1698
1699 (define_insn "popsi1"
1700   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1701         (mem:SI (reg:SI SP_REG)))
1702    (set (reg:SI SP_REG)
1703         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1704   "!TARGET_64BIT"
1705   "pop{l}\t%0"
1706   [(set_attr "type" "pop")
1707    (set_attr "mode" "SI")])
1708
1709 (define_insn "*movsi_xor"
1710   [(set (match_operand:SI 0 "register_operand" "=r")
1711         (match_operand:SI 1 "const0_operand" ""))
1712    (clobber (reg:CC FLAGS_REG))]
1713   "reload_completed"
1714   "xor{l}\t%0, %0"
1715   [(set_attr "type" "alu1")
1716    (set_attr "mode" "SI")
1717    (set_attr "length_immediate" "0")])
1718
1719 (define_insn "*movsi_or"
1720   [(set (match_operand:SI 0 "register_operand" "=r")
1721         (match_operand:SI 1 "immediate_operand" "i"))
1722    (clobber (reg:CC FLAGS_REG))]
1723   "reload_completed
1724    && operands[1] == constm1_rtx"
1725 {
1726   operands[1] = constm1_rtx;
1727   return "or{l}\t{%1, %0|%0, %1}";
1728 }
1729   [(set_attr "type" "alu1")
1730    (set_attr "mode" "SI")
1731    (set_attr "length_immediate" "1")])
1732
1733 (define_insn "*movsi_1"
1734   [(set (match_operand:SI 0 "nonimmediate_operand"
1735                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1736         (match_operand:SI 1 "general_operand"
1737                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1738   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1739 {
1740   switch (get_attr_type (insn))
1741     {
1742     case TYPE_SSELOG1:
1743       if (get_attr_mode (insn) == MODE_TI)
1744         return "%vpxor\t%0, %d0";
1745       return "%vxorps\t%0, %d0";
1746
1747     case TYPE_SSEMOV:
1748       switch (get_attr_mode (insn))
1749         {
1750         case MODE_TI:
1751           return "%vmovdqa\t{%1, %0|%0, %1}";
1752         case MODE_V4SF:
1753           return "%vmovaps\t{%1, %0|%0, %1}";
1754         case MODE_SI:
1755           return "%vmovd\t{%1, %0|%0, %1}";
1756         case MODE_SF:
1757           return "%vmovss\t{%1, %0|%0, %1}";
1758         default:
1759           gcc_unreachable ();
1760         }
1761
1762     case TYPE_MMX:
1763       return "pxor\t%0, %0";
1764
1765     case TYPE_MMXMOV:
1766       if (get_attr_mode (insn) == MODE_DI)
1767         return "movq\t{%1, %0|%0, %1}";
1768       return "movd\t{%1, %0|%0, %1}";
1769
1770     case TYPE_LEA:
1771       return "lea{l}\t{%1, %0|%0, %1}";
1772
1773     default:
1774       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1775       return "mov{l}\t{%1, %0|%0, %1}";
1776     }
1777 }
1778   [(set (attr "type")
1779      (cond [(eq_attr "alternative" "2")
1780               (const_string "mmx")
1781             (eq_attr "alternative" "3,4,5")
1782               (const_string "mmxmov")
1783             (eq_attr "alternative" "6")
1784               (const_string "sselog1")
1785             (eq_attr "alternative" "7,8,9,10,11")
1786               (const_string "ssemov")
1787             (match_operand:DI 1 "pic_32bit_operand" "")
1788               (const_string "lea")
1789            ]
1790            (const_string "imov")))
1791    (set (attr "prefix")
1792      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1793        (const_string "orig")
1794        (const_string "maybe_vex")))
1795    (set (attr "mode")
1796      (cond [(eq_attr "alternative" "2,3")
1797               (const_string "DI")
1798             (eq_attr "alternative" "6,7")
1799               (if_then_else
1800                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1801                 (const_string "V4SF")
1802                 (const_string "TI"))
1803             (and (eq_attr "alternative" "8,9,10,11")
1804                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1805               (const_string "SF")
1806            ]
1807            (const_string "SI")))])
1808
1809 ;; Stores and loads of ax to arbitrary constant address.
1810 ;; We fake an second form of instruction to force reload to load address
1811 ;; into register when rax is not available
1812 (define_insn "*movabssi_1_rex64"
1813   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1814         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1815   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1816   "@
1817    movabs{l}\t{%1, %P0|%P0, %1}
1818    mov{l}\t{%1, %a0|%a0, %1}"
1819   [(set_attr "type" "imov")
1820    (set_attr "modrm" "0,*")
1821    (set_attr "length_address" "8,0")
1822    (set_attr "length_immediate" "0,*")
1823    (set_attr "memory" "store")
1824    (set_attr "mode" "SI")])
1825
1826 (define_insn "*movabssi_2_rex64"
1827   [(set (match_operand:SI 0 "register_operand" "=a,r")
1828         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1829   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1830   "@
1831    movabs{l}\t{%P1, %0|%0, %P1}
1832    mov{l}\t{%a1, %0|%0, %a1}"
1833   [(set_attr "type" "imov")
1834    (set_attr "modrm" "0,*")
1835    (set_attr "length_address" "8,0")
1836    (set_attr "length_immediate" "0")
1837    (set_attr "memory" "load")
1838    (set_attr "mode" "SI")])
1839
1840 (define_insn "*swapsi"
1841   [(set (match_operand:SI 0 "register_operand" "+r")
1842         (match_operand:SI 1 "register_operand" "+r"))
1843    (set (match_dup 1)
1844         (match_dup 0))]
1845   ""
1846   "xchg{l}\t%1, %0"
1847   [(set_attr "type" "imov")
1848    (set_attr "mode" "SI")
1849    (set_attr "pent_pair" "np")
1850    (set_attr "athlon_decode" "vector")
1851    (set_attr "amdfam10_decode" "double")])
1852
1853 (define_expand "movhi"
1854   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1855         (match_operand:HI 1 "general_operand" ""))]
1856   ""
1857   "ix86_expand_move (HImode, operands); DONE;")
1858
1859 (define_insn "*pushhi2"
1860   [(set (match_operand:HI 0 "push_operand" "=X")
1861         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1862   "!TARGET_64BIT"
1863   "push{l}\t%k1"
1864   [(set_attr "type" "push")
1865    (set_attr "mode" "SI")])
1866
1867 ;; For 64BIT abi we always round up to 8 bytes.
1868 (define_insn "*pushhi2_rex64"
1869   [(set (match_operand:HI 0 "push_operand" "=X")
1870         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1871   "TARGET_64BIT"
1872   "push{q}\t%q1"
1873   [(set_attr "type" "push")
1874    (set_attr "mode" "DI")])
1875
1876 (define_insn "*movhi_1"
1877   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1878         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1879   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1880 {
1881   switch (get_attr_type (insn))
1882     {
1883     case TYPE_IMOVX:
1884       /* movzwl is faster than movw on p2 due to partial word stalls,
1885          though not as fast as an aligned movl.  */
1886       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1887     default:
1888       if (get_attr_mode (insn) == MODE_SI)
1889         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1890       else
1891         return "mov{w}\t{%1, %0|%0, %1}";
1892     }
1893 }
1894   [(set (attr "type")
1895      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1896               (const_string "imov")
1897             (and (eq_attr "alternative" "0")
1898                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1899                           (const_int 0))
1900                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1901                           (const_int 0))))
1902               (const_string "imov")
1903             (and (eq_attr "alternative" "1,2")
1904                  (match_operand:HI 1 "aligned_operand" ""))
1905               (const_string "imov")
1906             (and (ne (symbol_ref "TARGET_MOVX")
1907                      (const_int 0))
1908                  (eq_attr "alternative" "0,2"))
1909               (const_string "imovx")
1910            ]
1911            (const_string "imov")))
1912     (set (attr "mode")
1913       (cond [(eq_attr "type" "imovx")
1914                (const_string "SI")
1915              (and (eq_attr "alternative" "1,2")
1916                   (match_operand:HI 1 "aligned_operand" ""))
1917                (const_string "SI")
1918              (and (eq_attr "alternative" "0")
1919                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1920                            (const_int 0))
1921                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1922                            (const_int 0))))
1923                (const_string "SI")
1924             ]
1925             (const_string "HI")))])
1926
1927 ;; Stores and loads of ax to arbitrary constant address.
1928 ;; We fake an second form of instruction to force reload to load address
1929 ;; into register when rax is not available
1930 (define_insn "*movabshi_1_rex64"
1931   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1932         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1933   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1934   "@
1935    movabs{w}\t{%1, %P0|%P0, %1}
1936    mov{w}\t{%1, %a0|%a0, %1}"
1937   [(set_attr "type" "imov")
1938    (set_attr "modrm" "0,*")
1939    (set_attr "length_address" "8,0")
1940    (set_attr "length_immediate" "0,*")
1941    (set_attr "memory" "store")
1942    (set_attr "mode" "HI")])
1943
1944 (define_insn "*movabshi_2_rex64"
1945   [(set (match_operand:HI 0 "register_operand" "=a,r")
1946         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1947   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1948   "@
1949    movabs{w}\t{%P1, %0|%0, %P1}
1950    mov{w}\t{%a1, %0|%0, %a1}"
1951   [(set_attr "type" "imov")
1952    (set_attr "modrm" "0,*")
1953    (set_attr "length_address" "8,0")
1954    (set_attr "length_immediate" "0")
1955    (set_attr "memory" "load")
1956    (set_attr "mode" "HI")])
1957
1958 (define_insn "*swaphi_1"
1959   [(set (match_operand:HI 0 "register_operand" "+r")
1960         (match_operand:HI 1 "register_operand" "+r"))
1961    (set (match_dup 1)
1962         (match_dup 0))]
1963   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1964   "xchg{l}\t%k1, %k0"
1965   [(set_attr "type" "imov")
1966    (set_attr "mode" "SI")
1967    (set_attr "pent_pair" "np")
1968    (set_attr "athlon_decode" "vector")
1969    (set_attr "amdfam10_decode" "double")])
1970
1971 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1972 (define_insn "*swaphi_2"
1973   [(set (match_operand:HI 0 "register_operand" "+r")
1974         (match_operand:HI 1 "register_operand" "+r"))
1975    (set (match_dup 1)
1976         (match_dup 0))]
1977   "TARGET_PARTIAL_REG_STALL"
1978   "xchg{w}\t%1, %0"
1979   [(set_attr "type" "imov")
1980    (set_attr "mode" "HI")
1981    (set_attr "pent_pair" "np")
1982    (set_attr "athlon_decode" "vector")])
1983
1984 (define_expand "movstricthi"
1985   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1986         (match_operand:HI 1 "general_operand" ""))]
1987   ""
1988 {
1989   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1990     FAIL;
1991   /* Don't generate memory->memory moves, go through a register */
1992   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1993     operands[1] = force_reg (HImode, operands[1]);
1994 })
1995
1996 (define_insn "*movstricthi_1"
1997   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1998         (match_operand:HI 1 "general_operand" "rn,m"))]
1999   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2000    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2001   "mov{w}\t{%1, %0|%0, %1}"
2002   [(set_attr "type" "imov")
2003    (set_attr "mode" "HI")])
2004
2005 (define_insn "*movstricthi_xor"
2006   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
2007         (match_operand:HI 1 "const0_operand" ""))
2008    (clobber (reg:CC FLAGS_REG))]
2009   "reload_completed"
2010   "xor{w}\t%0, %0"
2011   [(set_attr "type" "alu1")
2012    (set_attr "mode" "HI")
2013    (set_attr "length_immediate" "0")])
2014
2015 (define_expand "movqi"
2016   [(set (match_operand:QI 0 "nonimmediate_operand" "")
2017         (match_operand:QI 1 "general_operand" ""))]
2018   ""
2019   "ix86_expand_move (QImode, operands); DONE;")
2020
2021 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2022 ;; "push a byte".  But actually we use pushl, which has the effect
2023 ;; of rounding the amount pushed up to a word.
2024
2025 (define_insn "*pushqi2"
2026   [(set (match_operand:QI 0 "push_operand" "=X")
2027         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
2028   "!TARGET_64BIT"
2029   "push{l}\t%k1"
2030   [(set_attr "type" "push")
2031    (set_attr "mode" "SI")])
2032
2033 ;; For 64BIT abi we always round up to 8 bytes.
2034 (define_insn "*pushqi2_rex64"
2035   [(set (match_operand:QI 0 "push_operand" "=X")
2036         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
2037   "TARGET_64BIT"
2038   "push{q}\t%q1"
2039   [(set_attr "type" "push")
2040    (set_attr "mode" "DI")])
2041
2042 ;; Situation is quite tricky about when to choose full sized (SImode) move
2043 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2044 ;; partial register dependency machines (such as AMD Athlon), where QImode
2045 ;; moves issue extra dependency and for partial register stalls machines
2046 ;; that don't use QImode patterns (and QImode move cause stall on the next
2047 ;; instruction).
2048 ;;
2049 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2050 ;; register stall machines with, where we use QImode instructions, since
2051 ;; partial register stall can be caused there.  Then we use movzx.
2052 (define_insn "*movqi_1"
2053   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2054         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2055   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2056 {
2057   switch (get_attr_type (insn))
2058     {
2059     case TYPE_IMOVX:
2060       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2061       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2062     default:
2063       if (get_attr_mode (insn) == MODE_SI)
2064         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2065       else
2066         return "mov{b}\t{%1, %0|%0, %1}";
2067     }
2068 }
2069   [(set (attr "type")
2070      (cond [(and (eq_attr "alternative" "5")
2071                  (not (match_operand:QI 1 "aligned_operand" "")))
2072               (const_string "imovx")
2073             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2074               (const_string "imov")
2075             (and (eq_attr "alternative" "3")
2076                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2077                           (const_int 0))
2078                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2079                           (const_int 0))))
2080               (const_string "imov")
2081             (eq_attr "alternative" "3,5")
2082               (const_string "imovx")
2083             (and (ne (symbol_ref "TARGET_MOVX")
2084                      (const_int 0))
2085                  (eq_attr "alternative" "2"))
2086               (const_string "imovx")
2087            ]
2088            (const_string "imov")))
2089    (set (attr "mode")
2090       (cond [(eq_attr "alternative" "3,4,5")
2091                (const_string "SI")
2092              (eq_attr "alternative" "6")
2093                (const_string "QI")
2094              (eq_attr "type" "imovx")
2095                (const_string "SI")
2096              (and (eq_attr "type" "imov")
2097                   (and (eq_attr "alternative" "0,1")
2098                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2099                                 (const_int 0))
2100                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2101                                      (const_int 0))
2102                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2103                                      (const_int 0))))))
2104                (const_string "SI")
2105              ;; Avoid partial register stalls when not using QImode arithmetic
2106              (and (eq_attr "type" "imov")
2107                   (and (eq_attr "alternative" "0,1")
2108                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2109                                 (const_int 0))
2110                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2111                                 (const_int 0)))))
2112                (const_string "SI")
2113            ]
2114            (const_string "QI")))])
2115
2116 (define_insn "*swapqi_1"
2117   [(set (match_operand:QI 0 "register_operand" "+r")
2118         (match_operand:QI 1 "register_operand" "+r"))
2119    (set (match_dup 1)
2120         (match_dup 0))]
2121   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2122   "xchg{l}\t%k1, %k0"
2123   [(set_attr "type" "imov")
2124    (set_attr "mode" "SI")
2125    (set_attr "pent_pair" "np")
2126    (set_attr "athlon_decode" "vector")
2127    (set_attr "amdfam10_decode" "vector")])
2128
2129 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2130 (define_insn "*swapqi_2"
2131   [(set (match_operand:QI 0 "register_operand" "+q")
2132         (match_operand:QI 1 "register_operand" "+q"))
2133    (set (match_dup 1)
2134         (match_dup 0))]
2135   "TARGET_PARTIAL_REG_STALL"
2136   "xchg{b}\t%1, %0"
2137   [(set_attr "type" "imov")
2138    (set_attr "mode" "QI")
2139    (set_attr "pent_pair" "np")
2140    (set_attr "athlon_decode" "vector")])
2141
2142 (define_expand "movstrictqi"
2143   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2144         (match_operand:QI 1 "general_operand" ""))]
2145   ""
2146 {
2147   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2148     FAIL;
2149   /* Don't generate memory->memory moves, go through a register.  */
2150   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2151     operands[1] = force_reg (QImode, operands[1]);
2152 })
2153
2154 (define_insn "*movstrictqi_1"
2155   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2156         (match_operand:QI 1 "general_operand" "*qn,m"))]
2157   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2158    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2159   "mov{b}\t{%1, %0|%0, %1}"
2160   [(set_attr "type" "imov")
2161    (set_attr "mode" "QI")])
2162
2163 (define_insn "*movstrictqi_xor"
2164   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2165         (match_operand:QI 1 "const0_operand" ""))
2166    (clobber (reg:CC FLAGS_REG))]
2167   "reload_completed"
2168   "xor{b}\t%0, %0"
2169   [(set_attr "type" "alu1")
2170    (set_attr "mode" "QI")
2171    (set_attr "length_immediate" "0")])
2172
2173 (define_insn "*movsi_extv_1"
2174   [(set (match_operand:SI 0 "register_operand" "=R")
2175         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2176                          (const_int 8)
2177                          (const_int 8)))]
2178   ""
2179   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2180   [(set_attr "type" "imovx")
2181    (set_attr "mode" "SI")])
2182
2183 (define_insn "*movhi_extv_1"
2184   [(set (match_operand:HI 0 "register_operand" "=R")
2185         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2186                          (const_int 8)
2187                          (const_int 8)))]
2188   ""
2189   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2190   [(set_attr "type" "imovx")
2191    (set_attr "mode" "SI")])
2192
2193 (define_insn "*movqi_extv_1"
2194   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2195         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2196                          (const_int 8)
2197                          (const_int 8)))]
2198   "!TARGET_64BIT"
2199 {
2200   switch (get_attr_type (insn))
2201     {
2202     case TYPE_IMOVX:
2203       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2204     default:
2205       return "mov{b}\t{%h1, %0|%0, %h1}";
2206     }
2207 }
2208   [(set (attr "type")
2209      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2210                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2211                              (ne (symbol_ref "TARGET_MOVX")
2212                                  (const_int 0))))
2213         (const_string "imovx")
2214         (const_string "imov")))
2215    (set (attr "mode")
2216      (if_then_else (eq_attr "type" "imovx")
2217         (const_string "SI")
2218         (const_string "QI")))])
2219
2220 (define_insn "*movqi_extv_1_rex64"
2221   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2222         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2223                          (const_int 8)
2224                          (const_int 8)))]
2225   "TARGET_64BIT"
2226 {
2227   switch (get_attr_type (insn))
2228     {
2229     case TYPE_IMOVX:
2230       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2231     default:
2232       return "mov{b}\t{%h1, %0|%0, %h1}";
2233     }
2234 }
2235   [(set (attr "type")
2236      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2237                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2238                              (ne (symbol_ref "TARGET_MOVX")
2239                                  (const_int 0))))
2240         (const_string "imovx")
2241         (const_string "imov")))
2242    (set (attr "mode")
2243      (if_then_else (eq_attr "type" "imovx")
2244         (const_string "SI")
2245         (const_string "QI")))])
2246
2247 ;; Stores and loads of ax to arbitrary constant address.
2248 ;; We fake an second form of instruction to force reload to load address
2249 ;; into register when rax is not available
2250 (define_insn "*movabsqi_1_rex64"
2251   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2252         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2253   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2254   "@
2255    movabs{b}\t{%1, %P0|%P0, %1}
2256    mov{b}\t{%1, %a0|%a0, %1}"
2257   [(set_attr "type" "imov")
2258    (set_attr "modrm" "0,*")
2259    (set_attr "length_address" "8,0")
2260    (set_attr "length_immediate" "0,*")
2261    (set_attr "memory" "store")
2262    (set_attr "mode" "QI")])
2263
2264 (define_insn "*movabsqi_2_rex64"
2265   [(set (match_operand:QI 0 "register_operand" "=a,r")
2266         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2267   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2268   "@
2269    movabs{b}\t{%P1, %0|%0, %P1}
2270    mov{b}\t{%a1, %0|%0, %a1}"
2271   [(set_attr "type" "imov")
2272    (set_attr "modrm" "0,*")
2273    (set_attr "length_address" "8,0")
2274    (set_attr "length_immediate" "0")
2275    (set_attr "memory" "load")
2276    (set_attr "mode" "QI")])
2277
2278 (define_insn "*movdi_extzv_1"
2279   [(set (match_operand:DI 0 "register_operand" "=R")
2280         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2281                          (const_int 8)
2282                          (const_int 8)))]
2283   "TARGET_64BIT"
2284   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2285   [(set_attr "type" "imovx")
2286    (set_attr "mode" "DI")])
2287
2288 (define_insn "*movsi_extzv_1"
2289   [(set (match_operand:SI 0 "register_operand" "=R")
2290         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2291                          (const_int 8)
2292                          (const_int 8)))]
2293   ""
2294   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2295   [(set_attr "type" "imovx")
2296    (set_attr "mode" "SI")])
2297
2298 (define_insn "*movqi_extzv_2"
2299   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2300         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2301                                     (const_int 8)
2302                                     (const_int 8)) 0))]
2303   "!TARGET_64BIT"
2304 {
2305   switch (get_attr_type (insn))
2306     {
2307     case TYPE_IMOVX:
2308       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2309     default:
2310       return "mov{b}\t{%h1, %0|%0, %h1}";
2311     }
2312 }
2313   [(set (attr "type")
2314      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2315                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2316                              (ne (symbol_ref "TARGET_MOVX")
2317                                  (const_int 0))))
2318         (const_string "imovx")
2319         (const_string "imov")))
2320    (set (attr "mode")
2321      (if_then_else (eq_attr "type" "imovx")
2322         (const_string "SI")
2323         (const_string "QI")))])
2324
2325 (define_insn "*movqi_extzv_2_rex64"
2326   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2327         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2328                                     (const_int 8)
2329                                     (const_int 8)) 0))]
2330   "TARGET_64BIT"
2331 {
2332   switch (get_attr_type (insn))
2333     {
2334     case TYPE_IMOVX:
2335       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2336     default:
2337       return "mov{b}\t{%h1, %0|%0, %h1}";
2338     }
2339 }
2340   [(set (attr "type")
2341      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2342                         (ne (symbol_ref "TARGET_MOVX")
2343                             (const_int 0)))
2344         (const_string "imovx")
2345         (const_string "imov")))
2346    (set (attr "mode")
2347      (if_then_else (eq_attr "type" "imovx")
2348         (const_string "SI")
2349         (const_string "QI")))])
2350
2351 (define_insn "movsi_insv_1"
2352   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2353                          (const_int 8)
2354                          (const_int 8))
2355         (match_operand:SI 1 "general_operand" "Qmn"))]
2356   "!TARGET_64BIT"
2357   "mov{b}\t{%b1, %h0|%h0, %b1}"
2358   [(set_attr "type" "imov")
2359    (set_attr "mode" "QI")])
2360
2361 (define_insn "*movsi_insv_1_rex64"
2362   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2363                          (const_int 8)
2364                          (const_int 8))
2365         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2366   "TARGET_64BIT"
2367   "mov{b}\t{%b1, %h0|%h0, %b1}"
2368   [(set_attr "type" "imov")
2369    (set_attr "mode" "QI")])
2370
2371 (define_insn "movdi_insv_1_rex64"
2372   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2373                          (const_int 8)
2374                          (const_int 8))
2375         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2376   "TARGET_64BIT"
2377   "mov{b}\t{%b1, %h0|%h0, %b1}"
2378   [(set_attr "type" "imov")
2379    (set_attr "mode" "QI")])
2380
2381 (define_insn "*movqi_insv_2"
2382   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2383                          (const_int 8)
2384                          (const_int 8))
2385         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2386                      (const_int 8)))]
2387   ""
2388   "mov{b}\t{%h1, %h0|%h0, %h1}"
2389   [(set_attr "type" "imov")
2390    (set_attr "mode" "QI")])
2391
2392 (define_expand "movdi"
2393   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2394         (match_operand:DI 1 "general_operand" ""))]
2395   ""
2396   "ix86_expand_move (DImode, operands); DONE;")
2397
2398 (define_insn "*pushdi"
2399   [(set (match_operand:DI 0 "push_operand" "=<")
2400         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2401   "!TARGET_64BIT"
2402   "#")
2403
2404 (define_insn "*pushdi2_rex64"
2405   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2406         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2407   "TARGET_64BIT"
2408   "@
2409    push{q}\t%1
2410    #"
2411   [(set_attr "type" "push,multi")
2412    (set_attr "mode" "DI")])
2413
2414 ;; Convert impossible pushes of immediate to existing instructions.
2415 ;; First try to get scratch register and go through it.  In case this
2416 ;; fails, push sign extended lower part first and then overwrite
2417 ;; upper part by 32bit move.
2418 (define_peephole2
2419   [(match_scratch:DI 2 "r")
2420    (set (match_operand:DI 0 "push_operand" "")
2421         (match_operand:DI 1 "immediate_operand" ""))]
2422   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2423    && !x86_64_immediate_operand (operands[1], DImode)"
2424   [(set (match_dup 2) (match_dup 1))
2425    (set (match_dup 0) (match_dup 2))]
2426   "")
2427
2428 ;; We need to define this as both peepholer and splitter for case
2429 ;; peephole2 pass is not run.
2430 ;; "&& 1" is needed to keep it from matching the previous pattern.
2431 (define_peephole2
2432   [(set (match_operand:DI 0 "push_operand" "")
2433         (match_operand:DI 1 "immediate_operand" ""))]
2434   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2435    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2436   [(set (match_dup 0) (match_dup 1))
2437    (set (match_dup 2) (match_dup 3))]
2438   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2439    operands[1] = gen_lowpart (DImode, operands[2]);
2440    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2441                                                     GEN_INT (4)));
2442   ")
2443
2444 (define_split
2445   [(set (match_operand:DI 0 "push_operand" "")
2446         (match_operand:DI 1 "immediate_operand" ""))]
2447   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2448                     ? epilogue_completed : reload_completed)
2449    && !symbolic_operand (operands[1], DImode)
2450    && !x86_64_immediate_operand (operands[1], DImode)"
2451   [(set (match_dup 0) (match_dup 1))
2452    (set (match_dup 2) (match_dup 3))]
2453   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2454    operands[1] = gen_lowpart (DImode, operands[2]);
2455    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2456                                                     GEN_INT (4)));
2457   ")
2458
2459 (define_insn "*pushdi2_prologue_rex64"
2460   [(set (match_operand:DI 0 "push_operand" "=<")
2461         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2462    (clobber (mem:BLK (scratch)))]
2463   "TARGET_64BIT"
2464   "push{q}\t%1"
2465   [(set_attr "type" "push")
2466    (set_attr "mode" "DI")])
2467
2468 (define_insn "*popdi1_epilogue_rex64"
2469   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2470         (mem:DI (reg:DI SP_REG)))
2471    (set (reg:DI SP_REG)
2472         (plus:DI (reg:DI SP_REG) (const_int 8)))
2473    (clobber (mem:BLK (scratch)))]
2474   "TARGET_64BIT"
2475   "pop{q}\t%0"
2476   [(set_attr "type" "pop")
2477    (set_attr "mode" "DI")])
2478
2479 (define_insn "popdi1"
2480   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2481         (mem:DI (reg:DI SP_REG)))
2482    (set (reg:DI SP_REG)
2483         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2484   "TARGET_64BIT"
2485   "pop{q}\t%0"
2486   [(set_attr "type" "pop")
2487    (set_attr "mode" "DI")])
2488
2489 (define_insn "*movdi_xor_rex64"
2490   [(set (match_operand:DI 0 "register_operand" "=r")
2491         (match_operand:DI 1 "const0_operand" ""))
2492    (clobber (reg:CC FLAGS_REG))]
2493   "TARGET_64BIT
2494    && reload_completed"
2495   "xor{l}\t%k0, %k0";
2496   [(set_attr "type" "alu1")
2497    (set_attr "mode" "SI")
2498    (set_attr "length_immediate" "0")])
2499
2500 (define_insn "*movdi_or_rex64"
2501   [(set (match_operand:DI 0 "register_operand" "=r")
2502         (match_operand:DI 1 "const_int_operand" "i"))
2503    (clobber (reg:CC FLAGS_REG))]
2504   "TARGET_64BIT
2505    && reload_completed
2506    && operands[1] == constm1_rtx"
2507 {
2508   operands[1] = constm1_rtx;
2509   return "or{q}\t{%1, %0|%0, %1}";
2510 }
2511   [(set_attr "type" "alu1")
2512    (set_attr "mode" "DI")
2513    (set_attr "length_immediate" "1")])
2514
2515 (define_insn "*movdi_2"
2516   [(set (match_operand:DI 0 "nonimmediate_operand"
2517                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2518         (match_operand:DI 1 "general_operand"
2519                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2520   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2521   "@
2522    #
2523    #
2524    pxor\t%0, %0
2525    movq\t{%1, %0|%0, %1}
2526    movq\t{%1, %0|%0, %1}
2527    %vpxor\t%0, %d0
2528    %vmovq\t{%1, %0|%0, %1}
2529    %vmovdqa\t{%1, %0|%0, %1}
2530    %vmovq\t{%1, %0|%0, %1}
2531    xorps\t%0, %0
2532    movlps\t{%1, %0|%0, %1}
2533    movaps\t{%1, %0|%0, %1}
2534    movlps\t{%1, %0|%0, %1}"
2535   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2536    (set (attr "prefix")
2537      (if_then_else (eq_attr "alternative" "5,6,7,8")
2538        (const_string "vex")
2539        (const_string "orig")))
2540    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2541
2542 (define_split
2543   [(set (match_operand:DI 0 "push_operand" "")
2544         (match_operand:DI 1 "general_operand" ""))]
2545   "!TARGET_64BIT && reload_completed
2546    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2547   [(const_int 0)]
2548   "ix86_split_long_move (operands); DONE;")
2549
2550 ;; %%% This multiword shite has got to go.
2551 (define_split
2552   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2553         (match_operand:DI 1 "general_operand" ""))]
2554   "!TARGET_64BIT && reload_completed
2555    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2556    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2557   [(const_int 0)]
2558   "ix86_split_long_move (operands); DONE;")
2559
2560 (define_insn "*movdi_1_rex64"
2561   [(set (match_operand:DI 0 "nonimmediate_operand"
2562           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2563         (match_operand:DI 1 "general_operand"
2564           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2565   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2566 {
2567   switch (get_attr_type (insn))
2568     {
2569     case TYPE_SSECVT:
2570       if (SSE_REG_P (operands[0]))
2571         return "movq2dq\t{%1, %0|%0, %1}";
2572       else
2573         return "movdq2q\t{%1, %0|%0, %1}";
2574
2575     case TYPE_SSEMOV:
2576       if (TARGET_AVX)
2577         {
2578           if (get_attr_mode (insn) == MODE_TI)
2579             return "vmovdqa\t{%1, %0|%0, %1}";
2580           else
2581             return "vmovq\t{%1, %0|%0, %1}";
2582         }
2583
2584       if (get_attr_mode (insn) == MODE_TI)
2585         return "movdqa\t{%1, %0|%0, %1}";
2586       /* FALLTHRU */
2587
2588     case TYPE_MMXMOV:
2589       /* Moves from and into integer register is done using movd
2590          opcode with REX prefix.  */
2591       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2592         return "movd\t{%1, %0|%0, %1}";
2593       return "movq\t{%1, %0|%0, %1}";
2594
2595     case TYPE_SSELOG1:
2596       return "%vpxor\t%0, %d0";
2597
2598     case TYPE_MMX:
2599       return "pxor\t%0, %0";
2600
2601     case TYPE_MULTI:
2602       return "#";
2603
2604     case TYPE_LEA:
2605       return "lea{q}\t{%a1, %0|%0, %a1}";
2606
2607     default:
2608       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2609       if (get_attr_mode (insn) == MODE_SI)
2610         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2611       else if (which_alternative == 2)
2612         return "movabs{q}\t{%1, %0|%0, %1}";
2613       else
2614         return "mov{q}\t{%1, %0|%0, %1}";
2615     }
2616 }
2617   [(set (attr "type")
2618      (cond [(eq_attr "alternative" "5")
2619               (const_string "mmx")
2620             (eq_attr "alternative" "6,7,8,9,10")
2621               (const_string "mmxmov")
2622             (eq_attr "alternative" "11")
2623               (const_string "sselog1")
2624             (eq_attr "alternative" "12,13,14,15,16")
2625               (const_string "ssemov")
2626             (eq_attr "alternative" "17,18")
2627               (const_string "ssecvt")
2628             (eq_attr "alternative" "4")
2629               (const_string "multi")
2630             (match_operand:DI 1 "pic_32bit_operand" "")
2631               (const_string "lea")
2632            ]
2633            (const_string "imov")))
2634    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2635    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2636    (set (attr "prefix")
2637      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2638        (const_string "maybe_vex")
2639        (const_string "orig")))
2640    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2641
2642 ;; Stores and loads of ax to arbitrary constant address.
2643 ;; We fake an second form of instruction to force reload to load address
2644 ;; into register when rax is not available
2645 (define_insn "*movabsdi_1_rex64"
2646   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2647         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2648   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2649   "@
2650    movabs{q}\t{%1, %P0|%P0, %1}
2651    mov{q}\t{%1, %a0|%a0, %1}"
2652   [(set_attr "type" "imov")
2653    (set_attr "modrm" "0,*")
2654    (set_attr "length_address" "8,0")
2655    (set_attr "length_immediate" "0,*")
2656    (set_attr "memory" "store")
2657    (set_attr "mode" "DI")])
2658
2659 (define_insn "*movabsdi_2_rex64"
2660   [(set (match_operand:DI 0 "register_operand" "=a,r")
2661         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2662   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2663   "@
2664    movabs{q}\t{%P1, %0|%0, %P1}
2665    mov{q}\t{%a1, %0|%0, %a1}"
2666   [(set_attr "type" "imov")
2667    (set_attr "modrm" "0,*")
2668    (set_attr "length_address" "8,0")
2669    (set_attr "length_immediate" "0")
2670    (set_attr "memory" "load")
2671    (set_attr "mode" "DI")])
2672
2673 ;; Convert impossible stores of immediate to existing instructions.
2674 ;; First try to get scratch register and go through it.  In case this
2675 ;; fails, move by 32bit parts.
2676 (define_peephole2
2677   [(match_scratch:DI 2 "r")
2678    (set (match_operand:DI 0 "memory_operand" "")
2679         (match_operand:DI 1 "immediate_operand" ""))]
2680   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2681    && !x86_64_immediate_operand (operands[1], DImode)"
2682   [(set (match_dup 2) (match_dup 1))
2683    (set (match_dup 0) (match_dup 2))]
2684   "")
2685
2686 ;; We need to define this as both peepholer and splitter for case
2687 ;; peephole2 pass is not run.
2688 ;; "&& 1" is needed to keep it from matching the previous pattern.
2689 (define_peephole2
2690   [(set (match_operand:DI 0 "memory_operand" "")
2691         (match_operand:DI 1 "immediate_operand" ""))]
2692   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2693    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2694   [(set (match_dup 2) (match_dup 3))
2695    (set (match_dup 4) (match_dup 5))]
2696   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2697
2698 (define_split
2699   [(set (match_operand:DI 0 "memory_operand" "")
2700         (match_operand:DI 1 "immediate_operand" ""))]
2701   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2702                     ? epilogue_completed : reload_completed)
2703    && !symbolic_operand (operands[1], DImode)
2704    && !x86_64_immediate_operand (operands[1], DImode)"
2705   [(set (match_dup 2) (match_dup 3))
2706    (set (match_dup 4) (match_dup 5))]
2707   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2708
2709 (define_insn "*swapdi_rex64"
2710   [(set (match_operand:DI 0 "register_operand" "+r")
2711         (match_operand:DI 1 "register_operand" "+r"))
2712    (set (match_dup 1)
2713         (match_dup 0))]
2714   "TARGET_64BIT"
2715   "xchg{q}\t%1, %0"
2716   [(set_attr "type" "imov")
2717    (set_attr "mode" "DI")
2718    (set_attr "pent_pair" "np")
2719    (set_attr "athlon_decode" "vector")
2720    (set_attr "amdfam10_decode" "double")])
2721
2722 (define_expand "movoi"
2723   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2724         (match_operand:OI 1 "general_operand" ""))]
2725   "TARGET_AVX"
2726   "ix86_expand_move (OImode, operands); DONE;")
2727
2728 (define_insn "*movoi_internal"
2729   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2730         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2731   "TARGET_AVX
2732    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2733 {
2734   switch (which_alternative)
2735     {
2736     case 0:
2737       return "vxorps\t%0, %0, %0";
2738     case 1:
2739     case 2:
2740       if (misaligned_operand (operands[0], OImode)
2741           || misaligned_operand (operands[1], OImode))
2742         return "vmovdqu\t{%1, %0|%0, %1}";
2743       else
2744         return "vmovdqa\t{%1, %0|%0, %1}";
2745     default:
2746       gcc_unreachable ();
2747     }
2748 }
2749   [(set_attr "type" "sselog1,ssemov,ssemov")
2750    (set_attr "prefix" "vex")
2751    (set_attr "mode" "OI")])
2752
2753 (define_expand "movti"
2754   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2755         (match_operand:TI 1 "nonimmediate_operand" ""))]
2756   "TARGET_SSE || TARGET_64BIT"
2757 {
2758   if (TARGET_64BIT)
2759     ix86_expand_move (TImode, operands);
2760   else if (push_operand (operands[0], TImode))
2761     ix86_expand_push (TImode, operands[1]);
2762   else
2763     ix86_expand_vector_move (TImode, operands);
2764   DONE;
2765 })
2766
2767 (define_insn "*movti_internal"
2768   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2769         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2770   "TARGET_SSE && !TARGET_64BIT
2771    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2772 {
2773   switch (which_alternative)
2774     {
2775     case 0:
2776       if (get_attr_mode (insn) == MODE_V4SF)
2777         return "%vxorps\t%0, %d0";
2778       else
2779         return "%vpxor\t%0, %d0";
2780     case 1:
2781     case 2:
2782       /* TDmode values are passed as TImode on the stack.  Moving them
2783          to stack may result in unaligned memory access.  */
2784       if (misaligned_operand (operands[0], TImode)
2785           || misaligned_operand (operands[1], TImode))
2786         {
2787           if (get_attr_mode (insn) == MODE_V4SF)
2788             return "%vmovups\t{%1, %0|%0, %1}";
2789          else
2790            return "%vmovdqu\t{%1, %0|%0, %1}";
2791         }
2792       else
2793         {
2794           if (get_attr_mode (insn) == MODE_V4SF)
2795             return "%vmovaps\t{%1, %0|%0, %1}";
2796          else
2797            return "%vmovdqa\t{%1, %0|%0, %1}";
2798         }
2799     default:
2800       gcc_unreachable ();
2801     }
2802 }
2803   [(set_attr "type" "sselog1,ssemov,ssemov")
2804    (set_attr "prefix" "maybe_vex")
2805    (set (attr "mode")
2806         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2807                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2808                  (const_string "V4SF")
2809                (and (eq_attr "alternative" "2")
2810                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2811                         (const_int 0)))
2812                  (const_string "V4SF")]
2813               (const_string "TI")))])
2814
2815 (define_insn "*movti_rex64"
2816   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2817         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2818   "TARGET_64BIT
2819    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2820 {
2821   switch (which_alternative)
2822     {
2823     case 0:
2824     case 1:
2825       return "#";
2826     case 2:
2827       if (get_attr_mode (insn) == MODE_V4SF)
2828         return "%vxorps\t%0, %d0";
2829       else
2830         return "%vpxor\t%0, %d0";
2831     case 3:
2832     case 4:
2833       /* TDmode values are passed as TImode on the stack.  Moving them
2834          to stack may result in unaligned memory access.  */
2835       if (misaligned_operand (operands[0], TImode)
2836           || misaligned_operand (operands[1], TImode))
2837         {
2838           if (get_attr_mode (insn) == MODE_V4SF)
2839             return "%vmovups\t{%1, %0|%0, %1}";
2840          else
2841            return "%vmovdqu\t{%1, %0|%0, %1}";
2842         }
2843       else
2844         {
2845           if (get_attr_mode (insn) == MODE_V4SF)
2846             return "%vmovaps\t{%1, %0|%0, %1}";
2847          else
2848            return "%vmovdqa\t{%1, %0|%0, %1}";
2849         }
2850     default:
2851       gcc_unreachable ();
2852     }
2853 }
2854   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2855    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2856    (set (attr "mode")
2857         (cond [(eq_attr "alternative" "2,3")
2858                  (if_then_else
2859                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2860                        (const_int 0))
2861                    (const_string "V4SF")
2862                    (const_string "TI"))
2863                (eq_attr "alternative" "4")
2864                  (if_then_else
2865                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2866                             (const_int 0))
2867                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2868                             (const_int 0)))
2869                    (const_string "V4SF")
2870                    (const_string "TI"))]
2871                (const_string "DI")))])
2872
2873 (define_split
2874   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2875         (match_operand:TI 1 "general_operand" ""))]
2876   "reload_completed && !SSE_REG_P (operands[0])
2877    && !SSE_REG_P (operands[1])"
2878   [(const_int 0)]
2879   "ix86_split_long_move (operands); DONE;")
2880
2881 ;; This expands to what emit_move_complex would generate if we didn't
2882 ;; have a movti pattern.  Having this avoids problems with reload on
2883 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2884 ;; to have around all the time.
2885 (define_expand "movcdi"
2886   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2887         (match_operand:CDI 1 "general_operand" ""))]
2888   ""
2889 {
2890   if (push_operand (operands[0], CDImode))
2891     emit_move_complex_push (CDImode, operands[0], operands[1]);
2892   else
2893     emit_move_complex_parts (operands[0], operands[1]);
2894   DONE;
2895 })
2896
2897 (define_expand "movsf"
2898   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2899         (match_operand:SF 1 "general_operand" ""))]
2900   ""
2901   "ix86_expand_move (SFmode, operands); DONE;")
2902
2903 (define_insn "*pushsf"
2904   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2905         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2906   "!TARGET_64BIT"
2907 {
2908   /* Anything else should be already split before reg-stack.  */
2909   gcc_assert (which_alternative == 1);
2910   return "push{l}\t%1";
2911 }
2912   [(set_attr "type" "multi,push,multi")
2913    (set_attr "unit" "i387,*,*")
2914    (set_attr "mode" "SF,SI,SF")])
2915
2916 (define_insn "*pushsf_rex64"
2917   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2918         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2919   "TARGET_64BIT"
2920 {
2921   /* Anything else should be already split before reg-stack.  */
2922   gcc_assert (which_alternative == 1);
2923   return "push{q}\t%q1";
2924 }
2925   [(set_attr "type" "multi,push,multi")
2926    (set_attr "unit" "i387,*,*")
2927    (set_attr "mode" "SF,DI,SF")])
2928
2929 (define_split
2930   [(set (match_operand:SF 0 "push_operand" "")
2931         (match_operand:SF 1 "memory_operand" ""))]
2932   "reload_completed
2933    && MEM_P (operands[1])
2934    && (operands[2] = find_constant_src (insn))"
2935   [(set (match_dup 0)
2936         (match_dup 2))])
2937
2938
2939 ;; %%% Kill this when call knows how to work this out.
2940 (define_split
2941   [(set (match_operand:SF 0 "push_operand" "")
2942         (match_operand:SF 1 "any_fp_register_operand" ""))]
2943   "!TARGET_64BIT"
2944   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2945    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2946
2947 (define_split
2948   [(set (match_operand:SF 0 "push_operand" "")
2949         (match_operand:SF 1 "any_fp_register_operand" ""))]
2950   "TARGET_64BIT"
2951   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2952    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2953
2954 (define_insn "*movsf_1"
2955   [(set (match_operand:SF 0 "nonimmediate_operand"
2956           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2957         (match_operand:SF 1 "general_operand"
2958           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2959   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2960    && (reload_in_progress || reload_completed
2961        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2962        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2963            && standard_80387_constant_p (operands[1]))
2964        || GET_CODE (operands[1]) != CONST_DOUBLE
2965        || memory_operand (operands[0], SFmode))"
2966 {
2967   switch (which_alternative)
2968     {
2969     case 0:
2970     case 1:
2971       return output_387_reg_move (insn, operands);
2972
2973     case 2:
2974       return standard_80387_constant_opcode (operands[1]);
2975
2976     case 3:
2977     case 4:
2978       return "mov{l}\t{%1, %0|%0, %1}";
2979     case 5:
2980       if (get_attr_mode (insn) == MODE_TI)
2981         return "%vpxor\t%0, %d0";
2982       else
2983         return "%vxorps\t%0, %d0";
2984     case 6:
2985       if (get_attr_mode (insn) == MODE_V4SF)
2986         return "%vmovaps\t{%1, %0|%0, %1}";
2987       else
2988         return "%vmovss\t{%1, %d0|%d0, %1}";
2989     case 7:
2990       if (TARGET_AVX)
2991         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2992                                    : "vmovss\t{%1, %0|%0, %1}";
2993       else
2994         return "movss\t{%1, %0|%0, %1}";
2995     case 8:
2996       return "%vmovss\t{%1, %0|%0, %1}";
2997
2998     case 9: case 10: case 14: case 15:
2999       return "movd\t{%1, %0|%0, %1}";
3000     case 12: case 13:
3001       return "%vmovd\t{%1, %0|%0, %1}";
3002
3003     case 11:
3004       return "movq\t{%1, %0|%0, %1}";
3005
3006     default:
3007       gcc_unreachable ();
3008     }
3009 }
3010   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3011    (set (attr "prefix")
3012      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3013        (const_string "maybe_vex")
3014        (const_string "orig")))
3015    (set (attr "mode")
3016         (cond [(eq_attr "alternative" "3,4,9,10")
3017                  (const_string "SI")
3018                (eq_attr "alternative" "5")
3019                  (if_then_else
3020                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3021                                  (const_int 0))
3022                              (ne (symbol_ref "TARGET_SSE2")
3023                                  (const_int 0)))
3024                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3025                             (const_int 0)))
3026                    (const_string "TI")
3027                    (const_string "V4SF"))
3028                /* For architectures resolving dependencies on
3029                   whole SSE registers use APS move to break dependency
3030                   chains, otherwise use short move to avoid extra work.
3031
3032                   Do the same for architectures resolving dependencies on
3033                   the parts.  While in DF mode it is better to always handle
3034                   just register parts, the SF mode is different due to lack
3035                   of instructions to load just part of the register.  It is
3036                   better to maintain the whole registers in single format
3037                   to avoid problems on using packed logical operations.  */
3038                (eq_attr "alternative" "6")
3039                  (if_then_else
3040                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3041                             (const_int 0))
3042                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3043                             (const_int 0)))
3044                    (const_string "V4SF")
3045                    (const_string "SF"))
3046                (eq_attr "alternative" "11")
3047                  (const_string "DI")]
3048                (const_string "SF")))])
3049
3050 (define_insn "*swapsf"
3051   [(set (match_operand:SF 0 "fp_register_operand" "+f")
3052         (match_operand:SF 1 "fp_register_operand" "+f"))
3053    (set (match_dup 1)
3054         (match_dup 0))]
3055   "reload_completed || TARGET_80387"
3056 {
3057   if (STACK_TOP_P (operands[0]))
3058     return "fxch\t%1";
3059   else
3060     return "fxch\t%0";
3061 }
3062   [(set_attr "type" "fxch")
3063    (set_attr "mode" "SF")])
3064
3065 (define_expand "movdf"
3066   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3067         (match_operand:DF 1 "general_operand" ""))]
3068   ""
3069   "ix86_expand_move (DFmode, operands); DONE;")
3070
3071 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3072 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3073 ;; On the average, pushdf using integers can be still shorter.  Allow this
3074 ;; pattern for optimize_size too.
3075
3076 (define_insn "*pushdf_nointeger"
3077   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3078         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3079   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3080 {
3081   /* This insn should be already split before reg-stack.  */
3082   gcc_unreachable ();
3083 }
3084   [(set_attr "type" "multi")
3085    (set_attr "unit" "i387,*,*,*")
3086    (set_attr "mode" "DF,SI,SI,DF")])
3087
3088 (define_insn "*pushdf_integer"
3089   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3090         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3091   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3092 {
3093   /* This insn should be already split before reg-stack.  */
3094   gcc_unreachable ();
3095 }
3096   [(set_attr "type" "multi")
3097    (set_attr "unit" "i387,*,*")
3098    (set_attr "mode" "DF,SI,DF")])
3099
3100 ;; %%% Kill this when call knows how to work this out.
3101 (define_split
3102   [(set (match_operand:DF 0 "push_operand" "")
3103         (match_operand:DF 1 "any_fp_register_operand" ""))]
3104   "reload_completed"
3105   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3106    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3107   "")
3108
3109 (define_split
3110   [(set (match_operand:DF 0 "push_operand" "")
3111         (match_operand:DF 1 "general_operand" ""))]
3112   "reload_completed"
3113   [(const_int 0)]
3114   "ix86_split_long_move (operands); DONE;")
3115
3116 ;; Moving is usually shorter when only FP registers are used. This separate
3117 ;; movdf pattern avoids the use of integer registers for FP operations
3118 ;; when optimizing for size.
3119
3120 (define_insn "*movdf_nointeger"
3121   [(set (match_operand:DF 0 "nonimmediate_operand"
3122                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3123         (match_operand:DF 1 "general_operand"
3124                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3125   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3126    && ((optimize_function_for_size_p (cfun)
3127        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3128    && (reload_in_progress || reload_completed
3129        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3130        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3131            && optimize_function_for_size_p (cfun)
3132            && !memory_operand (operands[0], DFmode)
3133            && standard_80387_constant_p (operands[1]))
3134        || GET_CODE (operands[1]) != CONST_DOUBLE
3135        || ((optimize_function_for_size_p (cfun)
3136             || !TARGET_MEMORY_MISMATCH_STALL
3137             || reload_in_progress || reload_completed)
3138            && memory_operand (operands[0], DFmode)))"
3139 {
3140   switch (which_alternative)
3141     {
3142     case 0:
3143     case 1:
3144       return output_387_reg_move (insn, operands);
3145
3146     case 2:
3147       return standard_80387_constant_opcode (operands[1]);
3148
3149     case 3:
3150     case 4:
3151       return "#";
3152     case 5:
3153       switch (get_attr_mode (insn))
3154         {
3155         case MODE_V4SF:
3156           return "%vxorps\t%0, %d0";
3157         case MODE_V2DF:
3158           return "%vxorpd\t%0, %d0";
3159         case MODE_TI:
3160           return "%vpxor\t%0, %d0";
3161         default:
3162           gcc_unreachable ();
3163         }
3164     case 6:
3165     case 7:
3166     case 8:
3167       switch (get_attr_mode (insn))
3168         {
3169         case MODE_V4SF:
3170           return "%vmovaps\t{%1, %0|%0, %1}";
3171         case MODE_V2DF:
3172           return "%vmovapd\t{%1, %0|%0, %1}";
3173         case MODE_TI:
3174           return "%vmovdqa\t{%1, %0|%0, %1}";
3175         case MODE_DI:
3176           return "%vmovq\t{%1, %0|%0, %1}";
3177         case MODE_DF:
3178           if (TARGET_AVX)
3179             {
3180               if (REG_P (operands[0]) && REG_P (operands[1]))
3181                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3182               else
3183                 return "vmovsd\t{%1, %0|%0, %1}";
3184             }
3185           else
3186             return "movsd\t{%1, %0|%0, %1}";
3187         case MODE_V1DF:
3188           if (TARGET_AVX)
3189             {
3190               if (REG_P (operands[0]))
3191                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3192               else
3193                 return "vmovlpd\t{%1, %0|%0, %1}";
3194             }
3195           else
3196             return "movlpd\t{%1, %0|%0, %1}";
3197         case MODE_V2SF:
3198           if (TARGET_AVX)
3199             {
3200               if (REG_P (operands[0]))
3201                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3202               else
3203                 return "vmovlps\t{%1, %0|%0, %1}";
3204             }
3205           else
3206             return "movlps\t{%1, %0|%0, %1}";
3207         default:
3208           gcc_unreachable ();
3209         }
3210
3211     default:
3212       gcc_unreachable ();
3213     }
3214 }
3215   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3216    (set (attr "prefix")
3217      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3218        (const_string "orig")
3219        (const_string "maybe_vex")))
3220    (set (attr "mode")
3221         (cond [(eq_attr "alternative" "0,1,2")
3222                  (const_string "DF")
3223                (eq_attr "alternative" "3,4")
3224                  (const_string "SI")
3225
3226                /* For SSE1, we have many fewer alternatives.  */
3227                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3228                  (cond [(eq_attr "alternative" "5,6")
3229                           (const_string "V4SF")
3230                        ]
3231                    (const_string "V2SF"))
3232
3233                /* xorps is one byte shorter.  */
3234                (eq_attr "alternative" "5")
3235                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3236                             (const_int 0))
3237                           (const_string "V4SF")
3238                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3239                             (const_int 0))
3240                           (const_string "TI")
3241                        ]
3242                        (const_string "V2DF"))
3243
3244                /* For architectures resolving dependencies on
3245                   whole SSE registers use APD move to break dependency
3246                   chains, otherwise use short move to avoid extra work.
3247
3248                   movaps encodes one byte shorter.  */
3249                (eq_attr "alternative" "6")
3250                  (cond
3251                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3252                         (const_int 0))
3253                       (const_string "V4SF")
3254                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3255                         (const_int 0))
3256                       (const_string "V2DF")
3257                    ]
3258                    (const_string "DF"))
3259                /* For architectures resolving dependencies on register
3260                   parts we may avoid extra work to zero out upper part
3261                   of register.  */
3262                (eq_attr "alternative" "7")
3263                  (if_then_else
3264                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3265                        (const_int 0))
3266                    (const_string "V1DF")
3267                    (const_string "DF"))
3268               ]
3269               (const_string "DF")))])
3270
3271 (define_insn "*movdf_integer_rex64"
3272   [(set (match_operand:DF 0 "nonimmediate_operand"
3273                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3274         (match_operand:DF 1 "general_operand"
3275                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3276   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3277    && (reload_in_progress || reload_completed
3278        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3279        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3280            && optimize_function_for_size_p (cfun)
3281            && standard_80387_constant_p (operands[1]))
3282        || GET_CODE (operands[1]) != CONST_DOUBLE
3283        || memory_operand (operands[0], DFmode))"
3284 {
3285   switch (which_alternative)
3286     {
3287     case 0:
3288     case 1:
3289       return output_387_reg_move (insn, operands);
3290
3291     case 2:
3292       return standard_80387_constant_opcode (operands[1]);
3293
3294     case 3:
3295     case 4:
3296       return "#";
3297
3298     case 5:
3299       switch (get_attr_mode (insn))
3300         {
3301         case MODE_V4SF:
3302           return "%vxorps\t%0, %d0";
3303         case MODE_V2DF:
3304           return "%vxorpd\t%0, %d0";
3305         case MODE_TI:
3306           return "%vpxor\t%0, %d0";
3307         default:
3308           gcc_unreachable ();
3309         }
3310     case 6:
3311     case 7:
3312     case 8:
3313       switch (get_attr_mode (insn))
3314         {
3315         case MODE_V4SF:
3316           return "%vmovaps\t{%1, %0|%0, %1}";
3317         case MODE_V2DF:
3318           return "%vmovapd\t{%1, %0|%0, %1}";
3319         case MODE_TI:
3320           return "%vmovdqa\t{%1, %0|%0, %1}";
3321         case MODE_DI:
3322           return "%vmovq\t{%1, %0|%0, %1}";
3323         case MODE_DF:
3324           if (TARGET_AVX)
3325             {
3326               if (REG_P (operands[0]) && REG_P (operands[1]))
3327                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3328               else
3329                 return "vmovsd\t{%1, %0|%0, %1}";
3330             }
3331           else
3332             return "movsd\t{%1, %0|%0, %1}";
3333         case MODE_V1DF:
3334           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3335         case MODE_V2SF:
3336           return "%vmovlps\t{%1, %d0|%d0, %1}";
3337         default:
3338           gcc_unreachable ();
3339         }
3340
3341     case 9:
3342     case 10:
3343     return "%vmovd\t{%1, %0|%0, %1}";
3344
3345     default:
3346       gcc_unreachable();
3347     }
3348 }
3349   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3350    (set (attr "prefix")
3351      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3352        (const_string "orig")
3353        (const_string "maybe_vex")))
3354    (set (attr "mode")
3355         (cond [(eq_attr "alternative" "0,1,2")
3356                  (const_string "DF")
3357                (eq_attr "alternative" "3,4,9,10")
3358                  (const_string "DI")
3359
3360                /* For SSE1, we have many fewer alternatives.  */
3361                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3362                  (cond [(eq_attr "alternative" "5,6")
3363                           (const_string "V4SF")
3364                        ]
3365                    (const_string "V2SF"))
3366
3367                /* xorps is one byte shorter.  */
3368                (eq_attr "alternative" "5")
3369                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3370                             (const_int 0))
3371                           (const_string "V4SF")
3372                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3373                             (const_int 0))
3374                           (const_string "TI")
3375                        ]
3376                        (const_string "V2DF"))
3377
3378                /* For architectures resolving dependencies on
3379                   whole SSE registers use APD move to break dependency
3380                   chains, otherwise use short move to avoid extra work.
3381
3382                   movaps encodes one byte shorter.  */
3383                (eq_attr "alternative" "6")
3384                  (cond
3385                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3386                         (const_int 0))
3387                       (const_string "V4SF")
3388                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3389                         (const_int 0))
3390                       (const_string "V2DF")
3391                    ]
3392                    (const_string "DF"))
3393                /* For architectures resolving dependencies on register
3394                   parts we may avoid extra work to zero out upper part
3395                   of register.  */
3396                (eq_attr "alternative" "7")
3397                  (if_then_else
3398                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3399                        (const_int 0))
3400                    (const_string "V1DF")
3401                    (const_string "DF"))
3402               ]
3403               (const_string "DF")))])
3404
3405 (define_insn "*movdf_integer"
3406   [(set (match_operand:DF 0 "nonimmediate_operand"
3407                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3408         (match_operand:DF 1 "general_operand"
3409                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3410   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3411    && optimize_function_for_speed_p (cfun)
3412    && TARGET_INTEGER_DFMODE_MOVES
3413    && (reload_in_progress || reload_completed
3414        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3415        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3416            && optimize_function_for_size_p (cfun)
3417            && standard_80387_constant_p (operands[1]))
3418        || GET_CODE (operands[1]) != CONST_DOUBLE
3419        || memory_operand (operands[0], DFmode))"
3420 {
3421   switch (which_alternative)
3422     {
3423     case 0:
3424     case 1:
3425       return output_387_reg_move (insn, operands);
3426
3427     case 2:
3428       return standard_80387_constant_opcode (operands[1]);
3429
3430     case 3:
3431     case 4:
3432       return "#";
3433
3434     case 5:
3435       switch (get_attr_mode (insn))
3436         {
3437         case MODE_V4SF:
3438           return "xorps\t%0, %0";
3439         case MODE_V2DF:
3440           return "xorpd\t%0, %0";
3441         case MODE_TI:
3442           return "pxor\t%0, %0";
3443         default:
3444           gcc_unreachable ();
3445         }
3446     case 6:
3447     case 7:
3448     case 8:
3449       switch (get_attr_mode (insn))
3450         {
3451         case MODE_V4SF:
3452           return "movaps\t{%1, %0|%0, %1}";
3453         case MODE_V2DF:
3454           return "movapd\t{%1, %0|%0, %1}";
3455         case MODE_TI:
3456           return "movdqa\t{%1, %0|%0, %1}";
3457         case MODE_DI:
3458           return "movq\t{%1, %0|%0, %1}";
3459         case MODE_DF:
3460           return "movsd\t{%1, %0|%0, %1}";
3461         case MODE_V1DF:
3462           return "movlpd\t{%1, %0|%0, %1}";
3463         case MODE_V2SF:
3464           return "movlps\t{%1, %0|%0, %1}";
3465         default:
3466           gcc_unreachable ();
3467         }
3468
3469     default:
3470       gcc_unreachable();
3471     }
3472 }
3473   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3474    (set (attr "mode")
3475         (cond [(eq_attr "alternative" "0,1,2")
3476                  (const_string "DF")
3477                (eq_attr "alternative" "3,4")
3478                  (const_string "SI")
3479
3480                /* For SSE1, we have many fewer alternatives.  */
3481                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3482                  (cond [(eq_attr "alternative" "5,6")
3483                           (const_string "V4SF")
3484                        ]
3485                    (const_string "V2SF"))
3486
3487                /* xorps is one byte shorter.  */
3488                (eq_attr "alternative" "5")
3489                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3490                             (const_int 0))
3491                           (const_string "V4SF")
3492                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3493                             (const_int 0))
3494                           (const_string "TI")
3495                        ]
3496                        (const_string "V2DF"))
3497
3498                /* For architectures resolving dependencies on
3499                   whole SSE registers use APD move to break dependency
3500                   chains, otherwise use short move to avoid extra work.
3501
3502                   movaps encodes one byte shorter.  */
3503                (eq_attr "alternative" "6")
3504                  (cond
3505                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3506                         (const_int 0))
3507                       (const_string "V4SF")
3508                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3509                         (const_int 0))
3510                       (const_string "V2DF")
3511                    ]
3512                    (const_string "DF"))
3513                /* For architectures resolving dependencies on register
3514                   parts we may avoid extra work to zero out upper part
3515                   of register.  */
3516                (eq_attr "alternative" "7")
3517                  (if_then_else
3518                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3519                        (const_int 0))
3520                    (const_string "V1DF")
3521                    (const_string "DF"))
3522               ]
3523               (const_string "DF")))])
3524
3525 (define_split
3526   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3527         (match_operand:DF 1 "general_operand" ""))]
3528   "reload_completed
3529    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3530    && ! (ANY_FP_REG_P (operands[0]) ||
3531          (GET_CODE (operands[0]) == SUBREG
3532           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3533    && ! (ANY_FP_REG_P (operands[1]) ||
3534          (GET_CODE (operands[1]) == SUBREG
3535           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3536   [(const_int 0)]
3537   "ix86_split_long_move (operands); DONE;")
3538
3539 (define_insn "*swapdf"
3540   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3541         (match_operand:DF 1 "fp_register_operand" "+f"))
3542    (set (match_dup 1)
3543         (match_dup 0))]
3544   "reload_completed || TARGET_80387"
3545 {
3546   if (STACK_TOP_P (operands[0]))
3547     return "fxch\t%1";
3548   else
3549     return "fxch\t%0";
3550 }
3551   [(set_attr "type" "fxch")
3552    (set_attr "mode" "DF")])
3553
3554 (define_expand "movxf"
3555   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3556         (match_operand:XF 1 "general_operand" ""))]
3557   ""
3558   "ix86_expand_move (XFmode, operands); DONE;")
3559
3560 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3561 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3562 ;; Pushing using integer instructions is longer except for constants
3563 ;; and direct memory references.
3564 ;; (assuming that any given constant is pushed only once, but this ought to be
3565 ;;  handled elsewhere).
3566
3567 (define_insn "*pushxf_nointeger"
3568   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3569         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3570   "optimize_function_for_size_p (cfun)"
3571 {
3572   /* This insn should be already split before reg-stack.  */
3573   gcc_unreachable ();
3574 }
3575   [(set_attr "type" "multi")
3576    (set_attr "unit" "i387,*,*")
3577    (set_attr "mode" "XF,SI,SI")])
3578
3579 (define_insn "*pushxf_integer"
3580   [(set (match_operand:XF 0 "push_operand" "=<,<")
3581         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3582   "optimize_function_for_speed_p (cfun)"
3583 {
3584   /* This insn should be already split before reg-stack.  */
3585   gcc_unreachable ();
3586 }
3587   [(set_attr "type" "multi")
3588    (set_attr "unit" "i387,*")
3589    (set_attr "mode" "XF,SI")])
3590
3591 (define_split
3592   [(set (match_operand 0 "push_operand" "")
3593         (match_operand 1 "general_operand" ""))]
3594   "reload_completed
3595    && (GET_MODE (operands[0]) == XFmode
3596        || GET_MODE (operands[0]) == DFmode)
3597    && !ANY_FP_REG_P (operands[1])"
3598   [(const_int 0)]
3599   "ix86_split_long_move (operands); DONE;")
3600
3601 (define_split
3602   [(set (match_operand:XF 0 "push_operand" "")
3603         (match_operand:XF 1 "any_fp_register_operand" ""))]
3604   ""
3605   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3606    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3607   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3608
3609 ;; Do not use integer registers when optimizing for size
3610 (define_insn "*movxf_nointeger"
3611   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3612         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3613   "optimize_function_for_size_p (cfun)
3614    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3615    && (reload_in_progress || reload_completed
3616        || standard_80387_constant_p (operands[1])
3617        || GET_CODE (operands[1]) != CONST_DOUBLE
3618        || memory_operand (operands[0], XFmode))"
3619 {
3620   switch (which_alternative)
3621     {
3622     case 0:
3623     case 1:
3624       return output_387_reg_move (insn, operands);
3625
3626     case 2:
3627       return standard_80387_constant_opcode (operands[1]);
3628
3629     case 3: case 4:
3630       return "#";
3631     default:
3632       gcc_unreachable ();
3633     }
3634 }
3635   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3636    (set_attr "mode" "XF,XF,XF,SI,SI")])
3637
3638 (define_insn "*movxf_integer"
3639   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3640         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3641   "optimize_function_for_speed_p (cfun)
3642    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3643    && (reload_in_progress || reload_completed
3644        || GET_CODE (operands[1]) != CONST_DOUBLE
3645        || memory_operand (operands[0], XFmode))"
3646 {
3647   switch (which_alternative)
3648     {
3649     case 0:
3650     case 1:
3651       return output_387_reg_move (insn, operands);
3652
3653     case 2:
3654       return standard_80387_constant_opcode (operands[1]);
3655
3656     case 3: case 4:
3657       return "#";
3658
3659     default:
3660       gcc_unreachable ();
3661     }
3662 }
3663   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3664    (set_attr "mode" "XF,XF,XF,SI,SI")])
3665
3666 (define_expand "movtf"
3667   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3668         (match_operand:TF 1 "nonimmediate_operand" ""))]
3669   "TARGET_SSE2"
3670 {
3671   ix86_expand_move (TFmode, operands);
3672   DONE;
3673 })
3674
3675 (define_insn "*movtf_internal"
3676   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3677         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3678   "TARGET_SSE2
3679    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3680 {
3681   switch (which_alternative)
3682     {
3683     case 0:
3684     case 1:
3685       if (get_attr_mode (insn) == MODE_V4SF)
3686         return "%vmovaps\t{%1, %0|%0, %1}";
3687       else
3688         return "%vmovdqa\t{%1, %0|%0, %1}";
3689     case 2:
3690       if (get_attr_mode (insn) == MODE_V4SF)
3691         return "%vxorps\t%0, %d0";
3692       else
3693         return "%vpxor\t%0, %d0";
3694     case 3:
3695     case 4:
3696         return "#";
3697     default:
3698       gcc_unreachable ();
3699     }
3700 }
3701   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3702    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3703    (set (attr "mode")
3704         (cond [(eq_attr "alternative" "0,2")
3705                  (if_then_else
3706                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3707                        (const_int 0))
3708                    (const_string "V4SF")
3709                    (const_string "TI"))
3710                (eq_attr "alternative" "1")
3711                  (if_then_else
3712                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3713                             (const_int 0))
3714                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3715                             (const_int 0)))
3716                    (const_string "V4SF")
3717                    (const_string "TI"))]
3718                (const_string "DI")))])
3719
3720 (define_insn "*pushtf_sse"
3721   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3722         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3723   "TARGET_SSE2"
3724 {
3725   /* This insn should be already split before reg-stack.  */
3726   gcc_unreachable ();
3727 }
3728   [(set_attr "type" "multi")
3729    (set_attr "unit" "sse,*,*")
3730    (set_attr "mode" "TF,SI,SI")])
3731
3732 (define_split
3733   [(set (match_operand:TF 0 "push_operand" "")
3734         (match_operand:TF 1 "general_operand" ""))]
3735   "TARGET_SSE2 && reload_completed
3736    && !SSE_REG_P (operands[1])"
3737   [(const_int 0)]
3738   "ix86_split_long_move (operands); DONE;")
3739
3740 (define_split
3741   [(set (match_operand:TF 0 "push_operand" "")
3742         (match_operand:TF 1 "any_fp_register_operand" ""))]
3743   "TARGET_SSE2"
3744   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3745    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3746   "")
3747
3748 (define_split
3749   [(set (match_operand 0 "nonimmediate_operand" "")
3750         (match_operand 1 "general_operand" ""))]
3751   "reload_completed
3752    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3753    && GET_MODE (operands[0]) == XFmode
3754    && ! (ANY_FP_REG_P (operands[0]) ||
3755          (GET_CODE (operands[0]) == SUBREG
3756           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3757    && ! (ANY_FP_REG_P (operands[1]) ||
3758          (GET_CODE (operands[1]) == SUBREG
3759           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3760   [(const_int 0)]
3761   "ix86_split_long_move (operands); DONE;")
3762
3763 (define_split
3764   [(set (match_operand 0 "register_operand" "")
3765         (match_operand 1 "memory_operand" ""))]
3766   "reload_completed
3767    && MEM_P (operands[1])
3768    && (GET_MODE (operands[0]) == TFmode
3769        || GET_MODE (operands[0]) == XFmode
3770        || GET_MODE (operands[0]) == SFmode
3771        || GET_MODE (operands[0]) == DFmode)
3772    && (operands[2] = find_constant_src (insn))"
3773   [(set (match_dup 0) (match_dup 2))]
3774 {
3775   rtx c = operands[2];
3776   rtx r = operands[0];
3777
3778   if (GET_CODE (r) == SUBREG)
3779     r = SUBREG_REG (r);
3780
3781   if (SSE_REG_P (r))
3782     {
3783       if (!standard_sse_constant_p (c))
3784         FAIL;
3785     }
3786   else if (FP_REG_P (r))
3787     {
3788       if (!standard_80387_constant_p (c))
3789         FAIL;
3790     }
3791   else if (MMX_REG_P (r))
3792     FAIL;
3793 })
3794
3795 (define_split
3796   [(set (match_operand 0 "register_operand" "")
3797         (float_extend (match_operand 1 "memory_operand" "")))]
3798   "reload_completed
3799    && MEM_P (operands[1])
3800    && (GET_MODE (operands[0]) == TFmode
3801        || GET_MODE (operands[0]) == XFmode
3802        || GET_MODE (operands[0]) == SFmode
3803        || GET_MODE (operands[0]) == DFmode)
3804    && (operands[2] = find_constant_src (insn))"
3805   [(set (match_dup 0) (match_dup 2))]
3806 {
3807   rtx c = operands[2];
3808   rtx r = operands[0];
3809
3810   if (GET_CODE (r) == SUBREG)
3811     r = SUBREG_REG (r);
3812
3813   if (SSE_REG_P (r))
3814     {
3815       if (!standard_sse_constant_p (c))
3816         FAIL;
3817     }
3818   else if (FP_REG_P (r))
3819     {
3820       if (!standard_80387_constant_p (c))
3821         FAIL;
3822     }
3823   else if (MMX_REG_P (r))
3824     FAIL;
3825 })
3826
3827 (define_insn "swapxf"
3828   [(set (match_operand:XF 0 "register_operand" "+f")
3829         (match_operand:XF 1 "register_operand" "+f"))
3830    (set (match_dup 1)
3831         (match_dup 0))]
3832   "TARGET_80387"
3833 {
3834   if (STACK_TOP_P (operands[0]))
3835     return "fxch\t%1";
3836   else
3837     return "fxch\t%0";
3838 }
3839   [(set_attr "type" "fxch")
3840    (set_attr "mode" "XF")])
3841
3842 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3843 (define_split
3844   [(set (match_operand:X87MODEF 0 "register_operand" "")
3845         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3846   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3847    && (standard_80387_constant_p (operands[1]) == 8
3848        || standard_80387_constant_p (operands[1]) == 9)"
3849   [(set (match_dup 0)(match_dup 1))
3850    (set (match_dup 0)
3851         (neg:X87MODEF (match_dup 0)))]
3852 {
3853   REAL_VALUE_TYPE r;
3854
3855   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3856   if (real_isnegzero (&r))
3857     operands[1] = CONST0_RTX (<MODE>mode);
3858   else
3859     operands[1] = CONST1_RTX (<MODE>mode);
3860 })
3861
3862 (define_split
3863   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3864         (match_operand:TF 1 "general_operand" ""))]
3865   "reload_completed
3866    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3867   [(const_int 0)]
3868   "ix86_split_long_move (operands); DONE;")
3869 \f
3870 ;; Zero extension instructions
3871
3872 (define_expand "zero_extendhisi2"
3873   [(set (match_operand:SI 0 "register_operand" "")
3874      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3875   ""
3876 {
3877   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3878     {
3879       operands[1] = force_reg (HImode, operands[1]);
3880       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3881       DONE;
3882     }
3883 })
3884
3885 (define_insn "zero_extendhisi2_and"
3886   [(set (match_operand:SI 0 "register_operand" "=r")
3887      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3888    (clobber (reg:CC FLAGS_REG))]
3889   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3890   "#"
3891   [(set_attr "type" "alu1")
3892    (set_attr "mode" "SI")])
3893
3894 (define_split
3895   [(set (match_operand:SI 0 "register_operand" "")
3896         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3897    (clobber (reg:CC FLAGS_REG))]
3898   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3899    && optimize_function_for_speed_p (cfun)"
3900   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3901               (clobber (reg:CC FLAGS_REG))])]
3902   "")
3903
3904 (define_insn "*zero_extendhisi2_movzwl"
3905   [(set (match_operand:SI 0 "register_operand" "=r")
3906      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3907   "!TARGET_ZERO_EXTEND_WITH_AND
3908    || optimize_function_for_size_p (cfun)"
3909   "movz{wl|x}\t{%1, %0|%0, %1}"
3910   [(set_attr "type" "imovx")
3911    (set_attr "mode" "SI")])
3912
3913 (define_expand "zero_extendqihi2"
3914   [(parallel
3915     [(set (match_operand:HI 0 "register_operand" "")
3916        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3917      (clobber (reg:CC FLAGS_REG))])]
3918   ""
3919   "")
3920
3921 (define_insn "*zero_extendqihi2_and"
3922   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3923      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3924    (clobber (reg:CC FLAGS_REG))]
3925   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3926   "#"
3927   [(set_attr "type" "alu1")
3928    (set_attr "mode" "HI")])
3929
3930 (define_insn "*zero_extendqihi2_movzbw_and"
3931   [(set (match_operand:HI 0 "register_operand" "=r,r")
3932      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3933    (clobber (reg:CC FLAGS_REG))]
3934   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3935   "#"
3936   [(set_attr "type" "imovx,alu1")
3937    (set_attr "mode" "HI")])
3938
3939 ; zero extend to SImode here to avoid partial register stalls
3940 (define_insn "*zero_extendqihi2_movzbl"
3941   [(set (match_operand:HI 0 "register_operand" "=r")
3942      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3943   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3944    && reload_completed"
3945   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3946   [(set_attr "type" "imovx")
3947    (set_attr "mode" "SI")])
3948
3949 ;; For the movzbw case strip only the clobber
3950 (define_split
3951   [(set (match_operand:HI 0 "register_operand" "")
3952         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3953    (clobber (reg:CC FLAGS_REG))]
3954   "reload_completed
3955    && (!TARGET_ZERO_EXTEND_WITH_AND
3956        || optimize_function_for_size_p (cfun))
3957    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3958   [(set (match_operand:HI 0 "register_operand" "")
3959         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3960
3961 ;; When source and destination does not overlap, clear destination
3962 ;; first and then do the movb
3963 (define_split
3964   [(set (match_operand:HI 0 "register_operand" "")
3965         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3966    (clobber (reg:CC FLAGS_REG))]
3967   "reload_completed
3968    && ANY_QI_REG_P (operands[0])
3969    && (TARGET_ZERO_EXTEND_WITH_AND
3970        && optimize_function_for_speed_p (cfun))
3971    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3972   [(set (match_dup 0) (const_int 0))
3973    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3974   "operands[2] = gen_lowpart (QImode, operands[0]);")
3975
3976 ;; Rest is handled by single and.
3977 (define_split
3978   [(set (match_operand:HI 0 "register_operand" "")
3979         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3980    (clobber (reg:CC FLAGS_REG))]
3981   "reload_completed
3982    && true_regnum (operands[0]) == true_regnum (operands[1])"
3983   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3984               (clobber (reg:CC FLAGS_REG))])]
3985   "")
3986
3987 (define_expand "zero_extendqisi2"
3988   [(parallel
3989     [(set (match_operand:SI 0 "register_operand" "")
3990        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3991      (clobber (reg:CC FLAGS_REG))])]
3992   ""
3993   "")
3994
3995 (define_insn "*zero_extendqisi2_and"
3996   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3997      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3998    (clobber (reg:CC FLAGS_REG))]
3999   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4000   "#"
4001   [(set_attr "type" "alu1")
4002    (set_attr "mode" "SI")])
4003
4004 (define_insn "*zero_extendqisi2_movzbw_and"
4005   [(set (match_operand:SI 0 "register_operand" "=r,r")
4006      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4007    (clobber (reg:CC FLAGS_REG))]
4008   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4009   "#"
4010   [(set_attr "type" "imovx,alu1")
4011    (set_attr "mode" "SI")])
4012
4013 (define_insn "*zero_extendqisi2_movzbw"
4014   [(set (match_operand:SI 0 "register_operand" "=r")
4015      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4016   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4017    && reload_completed"
4018   "movz{bl|x}\t{%1, %0|%0, %1}"
4019   [(set_attr "type" "imovx")
4020    (set_attr "mode" "SI")])
4021
4022 ;; For the movzbl case strip only the clobber
4023 (define_split
4024   [(set (match_operand:SI 0 "register_operand" "")
4025         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4026    (clobber (reg:CC FLAGS_REG))]
4027   "reload_completed
4028    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4029    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4030   [(set (match_dup 0)
4031         (zero_extend:SI (match_dup 1)))])
4032
4033 ;; When source and destination does not overlap, clear destination
4034 ;; first and then do the movb
4035 (define_split
4036   [(set (match_operand:SI 0 "register_operand" "")
4037         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4038    (clobber (reg:CC FLAGS_REG))]
4039   "reload_completed
4040    && ANY_QI_REG_P (operands[0])
4041    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4042    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4043    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4044   [(set (match_dup 0) (const_int 0))
4045    (set (strict_low_part (match_dup 2)) (match_dup 1))]
4046   "operands[2] = gen_lowpart (QImode, operands[0]);")
4047
4048 ;; Rest is handled by single and.
4049 (define_split
4050   [(set (match_operand:SI 0 "register_operand" "")
4051         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4052    (clobber (reg:CC FLAGS_REG))]
4053   "reload_completed
4054    && true_regnum (operands[0]) == true_regnum (operands[1])"
4055   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4056               (clobber (reg:CC FLAGS_REG))])]
4057   "")
4058
4059 ;; %%% Kill me once multi-word ops are sane.
4060 (define_expand "zero_extendsidi2"
4061   [(set (match_operand:DI 0 "register_operand" "")
4062      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4063   ""
4064 {
4065   if (!TARGET_64BIT)
4066     {
4067       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4068       DONE;
4069     }
4070 })
4071
4072 (define_insn "zero_extendsidi2_32"
4073   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4074         (zero_extend:DI
4075          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4076    (clobber (reg:CC FLAGS_REG))]
4077   "!TARGET_64BIT"
4078   "@
4079    #
4080    #
4081    #
4082    movd\t{%1, %0|%0, %1}
4083    movd\t{%1, %0|%0, %1}
4084    %vmovd\t{%1, %0|%0, %1}
4085    %vmovd\t{%1, %0|%0, %1}"
4086   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4087    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4088    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4089
4090 (define_insn "zero_extendsidi2_rex64"
4091   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4092      (zero_extend:DI
4093        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4094   "TARGET_64BIT"
4095   "@
4096    mov\t{%k1, %k0|%k0, %k1}
4097    #
4098    movd\t{%1, %0|%0, %1}
4099    movd\t{%1, %0|%0, %1}
4100    %vmovd\t{%1, %0|%0, %1}
4101    %vmovd\t{%1, %0|%0, %1}"
4102   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4103    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4104    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4105
4106 (define_split
4107   [(set (match_operand:DI 0 "memory_operand" "")
4108      (zero_extend:DI (match_dup 0)))]
4109   "TARGET_64BIT"
4110   [(set (match_dup 4) (const_int 0))]
4111   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4112
4113 (define_split
4114   [(set (match_operand:DI 0 "register_operand" "")
4115         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4116    (clobber (reg:CC FLAGS_REG))]
4117   "!TARGET_64BIT && reload_completed
4118    && true_regnum (operands[0]) == true_regnum (operands[1])"
4119   [(set (match_dup 4) (const_int 0))]
4120   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4121
4122 (define_split
4123   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4124         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4125    (clobber (reg:CC FLAGS_REG))]
4126   "!TARGET_64BIT && reload_completed
4127    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4128   [(set (match_dup 3) (match_dup 1))
4129    (set (match_dup 4) (const_int 0))]
4130   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4131
4132 (define_insn "zero_extendhidi2"
4133   [(set (match_operand:DI 0 "register_operand" "=r")
4134      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4135   "TARGET_64BIT"
4136   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4137   [(set_attr "type" "imovx")
4138    (set_attr "mode" "DI")])
4139
4140 (define_insn "zero_extendqidi2"
4141   [(set (match_operand:DI 0 "register_operand" "=r")
4142      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4143   "TARGET_64BIT"
4144   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4145   [(set_attr "type" "imovx")
4146    (set_attr "mode" "DI")])
4147 \f
4148 ;; Sign extension instructions
4149
4150 (define_expand "extendsidi2"
4151   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4152                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4153               (clobber (reg:CC FLAGS_REG))
4154               (clobber (match_scratch:SI 2 ""))])]
4155   ""
4156 {
4157   if (TARGET_64BIT)
4158     {
4159       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4160       DONE;
4161     }
4162 })
4163
4164 (define_insn "*extendsidi2_1"
4165   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4166         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4167    (clobber (reg:CC FLAGS_REG))
4168    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4169   "!TARGET_64BIT"
4170   "#")
4171
4172 (define_insn "extendsidi2_rex64"
4173   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4174         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4175   "TARGET_64BIT"
4176   "@
4177    {cltq|cdqe}
4178    movs{lq|x}\t{%1,%0|%0, %1}"
4179   [(set_attr "type" "imovx")
4180    (set_attr "mode" "DI")
4181    (set_attr "prefix_0f" "0")
4182    (set_attr "modrm" "0,1")])
4183
4184 (define_insn "extendhidi2"
4185   [(set (match_operand:DI 0 "register_operand" "=r")
4186         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4187   "TARGET_64BIT"
4188   "movs{wq|x}\t{%1,%0|%0, %1}"
4189   [(set_attr "type" "imovx")
4190    (set_attr "mode" "DI")])
4191
4192 (define_insn "extendqidi2"
4193   [(set (match_operand:DI 0 "register_operand" "=r")
4194         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4195   "TARGET_64BIT"
4196   "movs{bq|x}\t{%1,%0|%0, %1}"
4197    [(set_attr "type" "imovx")
4198     (set_attr "mode" "DI")])
4199
4200 ;; Extend to memory case when source register does die.
4201 (define_split
4202   [(set (match_operand:DI 0 "memory_operand" "")
4203         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4204    (clobber (reg:CC FLAGS_REG))
4205    (clobber (match_operand:SI 2 "register_operand" ""))]
4206   "(reload_completed
4207     && dead_or_set_p (insn, operands[1])
4208     && !reg_mentioned_p (operands[1], operands[0]))"
4209   [(set (match_dup 3) (match_dup 1))
4210    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4211               (clobber (reg:CC FLAGS_REG))])
4212    (set (match_dup 4) (match_dup 1))]
4213   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4214
4215 ;; Extend to memory case when source register does not die.
4216 (define_split
4217   [(set (match_operand:DI 0 "memory_operand" "")
4218         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4219    (clobber (reg:CC FLAGS_REG))
4220    (clobber (match_operand:SI 2 "register_operand" ""))]
4221   "reload_completed"
4222   [(const_int 0)]
4223 {
4224   split_di (&operands[0], 1, &operands[3], &operands[4]);
4225
4226   emit_move_insn (operands[3], operands[1]);
4227
4228   /* Generate a cltd if possible and doing so it profitable.  */
4229   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4230       && true_regnum (operands[1]) == AX_REG
4231       && true_regnum (operands[2]) == DX_REG)
4232     {
4233       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4234     }
4235   else
4236     {
4237       emit_move_insn (operands[2], operands[1]);
4238       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4239     }
4240   emit_move_insn (operands[4], operands[2]);
4241   DONE;
4242 })
4243
4244 ;; Extend to register case.  Optimize case where source and destination
4245 ;; registers match and cases where we can use cltd.
4246 (define_split
4247   [(set (match_operand:DI 0 "register_operand" "")
4248         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4249    (clobber (reg:CC FLAGS_REG))
4250    (clobber (match_scratch:SI 2 ""))]
4251   "reload_completed"
4252   [(const_int 0)]
4253 {
4254   split_di (&operands[0], 1, &operands[3], &operands[4]);
4255
4256   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4257     emit_move_insn (operands[3], operands[1]);
4258
4259   /* Generate a cltd if possible and doing so it profitable.  */
4260   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4261       && true_regnum (operands[3]) == AX_REG)
4262     {
4263       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4264       DONE;
4265     }
4266
4267   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4268     emit_move_insn (operands[4], operands[1]);
4269
4270   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4271   DONE;
4272 })
4273
4274 (define_insn "extendhisi2"
4275   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4276         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4277   ""
4278 {
4279   switch (get_attr_prefix_0f (insn))
4280     {
4281     case 0:
4282       return "{cwtl|cwde}";
4283     default:
4284       return "movs{wl|x}\t{%1,%0|%0, %1}";
4285     }
4286 }
4287   [(set_attr "type" "imovx")
4288    (set_attr "mode" "SI")
4289    (set (attr "prefix_0f")
4290      ;; movsx is short decodable while cwtl is vector decoded.
4291      (if_then_else (and (eq_attr "cpu" "!k6")
4292                         (eq_attr "alternative" "0"))
4293         (const_string "0")
4294         (const_string "1")))
4295    (set (attr "modrm")
4296      (if_then_else (eq_attr "prefix_0f" "0")
4297         (const_string "0")
4298         (const_string "1")))])
4299
4300 (define_insn "*extendhisi2_zext"
4301   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4302         (zero_extend:DI
4303           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4304   "TARGET_64BIT"
4305 {
4306   switch (get_attr_prefix_0f (insn))
4307     {
4308     case 0:
4309       return "{cwtl|cwde}";
4310     default:
4311       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4312     }
4313 }
4314   [(set_attr "type" "imovx")
4315    (set_attr "mode" "SI")
4316    (set (attr "prefix_0f")
4317      ;; movsx is short decodable while cwtl is vector decoded.
4318      (if_then_else (and (eq_attr "cpu" "!k6")
4319                         (eq_attr "alternative" "0"))
4320         (const_string "0")
4321         (const_string "1")))
4322    (set (attr "modrm")
4323      (if_then_else (eq_attr "prefix_0f" "0")
4324         (const_string "0")
4325         (const_string "1")))])
4326
4327 (define_insn "extendqihi2"
4328   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4329         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4330   ""
4331 {
4332   switch (get_attr_prefix_0f (insn))
4333     {
4334     case 0:
4335       return "{cbtw|cbw}";
4336     default:
4337       return "movs{bw|x}\t{%1,%0|%0, %1}";
4338     }
4339 }
4340   [(set_attr "type" "imovx")
4341    (set_attr "mode" "HI")
4342    (set (attr "prefix_0f")
4343      ;; movsx is short decodable while cwtl is vector decoded.
4344      (if_then_else (and (eq_attr "cpu" "!k6")
4345                         (eq_attr "alternative" "0"))
4346         (const_string "0")
4347         (const_string "1")))
4348    (set (attr "modrm")
4349      (if_then_else (eq_attr "prefix_0f" "0")
4350         (const_string "0")
4351         (const_string "1")))])
4352
4353 (define_insn "extendqisi2"
4354   [(set (match_operand:SI 0 "register_operand" "=r")
4355         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4356   ""
4357   "movs{bl|x}\t{%1,%0|%0, %1}"
4358    [(set_attr "type" "imovx")
4359     (set_attr "mode" "SI")])
4360
4361 (define_insn "*extendqisi2_zext"
4362   [(set (match_operand:DI 0 "register_operand" "=r")
4363         (zero_extend:DI
4364           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4365   "TARGET_64BIT"
4366   "movs{bl|x}\t{%1,%k0|%k0, %1}"
4367    [(set_attr "type" "imovx")
4368     (set_attr "mode" "SI")])
4369 \f
4370 ;; Conversions between float and double.
4371
4372 ;; These are all no-ops in the model used for the 80387.  So just
4373 ;; emit moves.
4374
4375 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4376 (define_insn "*dummy_extendsfdf2"
4377   [(set (match_operand:DF 0 "push_operand" "=<")
4378         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4379   "0"
4380   "#")
4381
4382 (define_split
4383   [(set (match_operand:DF 0 "push_operand" "")
4384         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4385   ""
4386   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4387    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4388
4389 (define_insn "*dummy_extendsfxf2"
4390   [(set (match_operand:XF 0 "push_operand" "=<")
4391         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4392   "0"
4393   "#")
4394
4395 (define_split
4396   [(set (match_operand:XF 0 "push_operand" "")
4397         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4398   ""
4399   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4400    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4401   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4402
4403 (define_split
4404   [(set (match_operand:XF 0 "push_operand" "")
4405         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4406   ""
4407   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4408    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4409   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4410
4411 (define_expand "extendsfdf2"
4412   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4413         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4414   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4415 {
4416   /* ??? Needed for compress_float_constant since all fp constants
4417      are LEGITIMATE_CONSTANT_P.  */
4418   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4419     {
4420       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4421           && standard_80387_constant_p (operands[1]) > 0)
4422         {
4423           operands[1] = simplify_const_unary_operation
4424             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4425           emit_move_insn_1 (operands[0], operands[1]);
4426           DONE;
4427         }
4428       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4429     }
4430 })
4431
4432 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4433    cvtss2sd:
4434       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4435       cvtps2pd xmm2,xmm1
4436    We do the conversion post reload to avoid producing of 128bit spills
4437    that might lead to ICE on 32bit target.  The sequence unlikely combine
4438    anyway.  */
4439 (define_split
4440   [(set (match_operand:DF 0 "register_operand" "")
4441         (float_extend:DF
4442           (match_operand:SF 1 "nonimmediate_operand" "")))]
4443   "TARGET_USE_VECTOR_FP_CONVERTS
4444    && optimize_insn_for_speed_p ()
4445    && reload_completed && SSE_REG_P (operands[0])"
4446    [(set (match_dup 2)
4447          (float_extend:V2DF
4448            (vec_select:V2SF
4449              (match_dup 3)
4450              (parallel [(const_int 0) (const_int 1)]))))]
4451 {
4452   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4453   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4454   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4455      Try to avoid move when unpacking can be done in source.  */
4456   if (REG_P (operands[1]))
4457     {
4458       /* If it is unsafe to overwrite upper half of source, we need
4459          to move to destination and unpack there.  */
4460       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4461            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4462           && true_regnum (operands[0]) != true_regnum (operands[1]))
4463         {
4464           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4465           emit_move_insn (tmp, operands[1]);
4466         }
4467       else
4468         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4469       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4470     }
4471   else
4472     emit_insn (gen_vec_setv4sf_0 (operands[3],
4473                                   CONST0_RTX (V4SFmode), operands[1]));
4474 })
4475
4476 (define_insn "*extendsfdf2_mixed"
4477   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4478         (float_extend:DF
4479           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4480   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4481 {
4482   switch (which_alternative)
4483     {
4484     case 0:
4485     case 1:
4486       return output_387_reg_move (insn, operands);
4487
4488     case 2:
4489       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4490
4491     default:
4492       gcc_unreachable ();
4493     }
4494 }
4495   [(set_attr "type" "fmov,fmov,ssecvt")
4496    (set_attr "prefix" "orig,orig,maybe_vex")
4497    (set_attr "mode" "SF,XF,DF")])
4498
4499 (define_insn "*extendsfdf2_sse"
4500   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4501         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4502   "TARGET_SSE2 && TARGET_SSE_MATH"
4503   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4504   [(set_attr "type" "ssecvt")
4505    (set_attr "prefix" "maybe_vex")
4506    (set_attr "mode" "DF")])
4507
4508 (define_insn "*extendsfdf2_i387"
4509   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4510         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4511   "TARGET_80387"
4512   "* return output_387_reg_move (insn, operands);"
4513   [(set_attr "type" "fmov")
4514    (set_attr "mode" "SF,XF")])
4515
4516 (define_expand "extend<mode>xf2"
4517   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4518         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4519   "TARGET_80387"
4520 {
4521   /* ??? Needed for compress_float_constant since all fp constants
4522      are LEGITIMATE_CONSTANT_P.  */
4523   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4524     {
4525       if (standard_80387_constant_p (operands[1]) > 0)
4526         {
4527           operands[1] = simplify_const_unary_operation
4528             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4529           emit_move_insn_1 (operands[0], operands[1]);
4530           DONE;
4531         }
4532       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4533     }
4534 })
4535
4536 (define_insn "*extend<mode>xf2_i387"
4537   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4538         (float_extend:XF
4539           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4540   "TARGET_80387"
4541   "* return output_387_reg_move (insn, operands);"
4542   [(set_attr "type" "fmov")
4543    (set_attr "mode" "<MODE>,XF")])
4544
4545 ;; %%% This seems bad bad news.
4546 ;; This cannot output into an f-reg because there is no way to be sure
4547 ;; of truncating in that case.  Otherwise this is just like a simple move
4548 ;; insn.  So we pretend we can output to a reg in order to get better
4549 ;; register preferencing, but we really use a stack slot.
4550
4551 ;; Conversion from DFmode to SFmode.
4552
4553 (define_expand "truncdfsf2"
4554   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4555         (float_truncate:SF
4556           (match_operand:DF 1 "nonimmediate_operand" "")))]
4557   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4558 {
4559   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4560     ;
4561   else if (flag_unsafe_math_optimizations)
4562     ;
4563   else
4564     {
4565       enum ix86_stack_slot slot = (virtuals_instantiated
4566                                    ? SLOT_TEMP
4567                                    : SLOT_VIRTUAL);
4568       rtx temp = assign_386_stack_local (SFmode, slot);
4569       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4570       DONE;
4571     }
4572 })
4573
4574 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4575    cvtsd2ss:
4576       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4577       cvtpd2ps xmm2,xmm1
4578    We do the conversion post reload to avoid producing of 128bit spills
4579    that might lead to ICE on 32bit target.  The sequence unlikely combine
4580    anyway.  */
4581 (define_split
4582   [(set (match_operand:SF 0 "register_operand" "")
4583         (float_truncate:SF
4584           (match_operand:DF 1 "nonimmediate_operand" "")))]
4585   "TARGET_USE_VECTOR_FP_CONVERTS
4586    && optimize_insn_for_speed_p ()
4587    && reload_completed && SSE_REG_P (operands[0])"
4588    [(set (match_dup 2)
4589          (vec_concat:V4SF
4590            (float_truncate:V2SF
4591              (match_dup 4))
4592            (match_dup 3)))]
4593 {
4594   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4595   operands[3] = CONST0_RTX (V2SFmode);
4596   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4597   /* Use movsd for loading from memory, unpcklpd for registers.
4598      Try to avoid move when unpacking can be done in source, or SSE3
4599      movddup is available.  */
4600   if (REG_P (operands[1]))
4601     {
4602       if (!TARGET_SSE3
4603           && true_regnum (operands[0]) != true_regnum (operands[1])
4604           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4605               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4606         {
4607           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4608           emit_move_insn (tmp, operands[1]);
4609           operands[1] = tmp;
4610         }
4611       else if (!TARGET_SSE3)
4612         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4613       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4614     }
4615   else
4616     emit_insn (gen_sse2_loadlpd (operands[4],
4617                                  CONST0_RTX (V2DFmode), operands[1]));
4618 })
4619
4620 (define_expand "truncdfsf2_with_temp"
4621   [(parallel [(set (match_operand:SF 0 "" "")
4622                    (float_truncate:SF (match_operand:DF 1 "" "")))
4623               (clobber (match_operand:SF 2 "" ""))])]
4624   "")
4625
4626 (define_insn "*truncdfsf_fast_mixed"
4627   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4628         (float_truncate:SF
4629           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4630   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4631 {
4632   switch (which_alternative)
4633     {
4634     case 0:
4635       return output_387_reg_move (insn, operands);
4636     case 1:
4637       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4638     default:
4639       gcc_unreachable ();
4640     }
4641 }
4642   [(set_attr "type" "fmov,ssecvt")
4643    (set_attr "prefix" "orig,maybe_vex")
4644    (set_attr "mode" "SF")])
4645
4646 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4647 ;; because nothing we do here is unsafe.
4648 (define_insn "*truncdfsf_fast_sse"
4649   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4650         (float_truncate:SF
4651           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4652   "TARGET_SSE2 && TARGET_SSE_MATH"
4653   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4654   [(set_attr "type" "ssecvt")
4655    (set_attr "prefix" "maybe_vex")
4656    (set_attr "mode" "SF")])
4657
4658 (define_insn "*truncdfsf_fast_i387"
4659   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4660         (float_truncate:SF
4661           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4662   "TARGET_80387 && flag_unsafe_math_optimizations"
4663   "* return output_387_reg_move (insn, operands);"
4664   [(set_attr "type" "fmov")
4665    (set_attr "mode" "SF")])
4666
4667 (define_insn "*truncdfsf_mixed"
4668   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4669         (float_truncate:SF
4670           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4671    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4672   "TARGET_MIX_SSE_I387"
4673 {
4674   switch (which_alternative)
4675     {
4676     case 0:
4677       return output_387_reg_move (insn, operands);
4678     case 1:
4679       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4680
4681     default:
4682       return "#";
4683     }
4684 }
4685   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4686    (set_attr "unit" "*,*,i387,i387,i387")
4687    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4688    (set_attr "mode" "SF")])
4689
4690 (define_insn "*truncdfsf_i387"
4691   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4692         (float_truncate:SF
4693           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4694    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4695   "TARGET_80387"
4696 {
4697   switch (which_alternative)
4698     {
4699     case 0:
4700       return output_387_reg_move (insn, operands);
4701
4702     default:
4703       return "#";
4704     }
4705 }
4706   [(set_attr "type" "fmov,multi,multi,multi")
4707    (set_attr "unit" "*,i387,i387,i387")
4708    (set_attr "mode" "SF")])
4709
4710 (define_insn "*truncdfsf2_i387_1"
4711   [(set (match_operand:SF 0 "memory_operand" "=m")
4712         (float_truncate:SF
4713           (match_operand:DF 1 "register_operand" "f")))]
4714   "TARGET_80387
4715    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4716    && !TARGET_MIX_SSE_I387"
4717   "* return output_387_reg_move (insn, operands);"
4718   [(set_attr "type" "fmov")
4719    (set_attr "mode" "SF")])
4720
4721 (define_split
4722   [(set (match_operand:SF 0 "register_operand" "")
4723         (float_truncate:SF
4724          (match_operand:DF 1 "fp_register_operand" "")))
4725    (clobber (match_operand 2 "" ""))]
4726   "reload_completed"
4727   [(set (match_dup 2) (match_dup 1))
4728    (set (match_dup 0) (match_dup 2))]
4729 {
4730   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4731 })
4732
4733 ;; Conversion from XFmode to {SF,DF}mode
4734
4735 (define_expand "truncxf<mode>2"
4736   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4737                    (float_truncate:MODEF
4738                      (match_operand:XF 1 "register_operand" "")))
4739               (clobber (match_dup 2))])]
4740   "TARGET_80387"
4741 {
4742   if (flag_unsafe_math_optimizations)
4743     {
4744       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4745       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4746       if (reg != operands[0])
4747         emit_move_insn (operands[0], reg);
4748       DONE;
4749     }
4750   else
4751     {
4752      enum ix86_stack_slot slot = (virtuals_instantiated
4753                                   ? SLOT_TEMP
4754                                   : SLOT_VIRTUAL);
4755       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4756     }
4757 })
4758
4759 (define_insn "*truncxfsf2_mixed"
4760   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4761         (float_truncate:SF
4762           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4763    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4764   "TARGET_80387"
4765 {
4766   gcc_assert (!which_alternative);
4767   return output_387_reg_move (insn, operands);
4768 }
4769   [(set_attr "type" "fmov,multi,multi,multi")
4770    (set_attr "unit" "*,i387,i387,i387")
4771    (set_attr "mode" "SF")])
4772
4773 (define_insn "*truncxfdf2_mixed"
4774   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4775         (float_truncate:DF
4776           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4777    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4778   "TARGET_80387"
4779 {
4780   gcc_assert (!which_alternative);
4781   return output_387_reg_move (insn, operands);
4782 }
4783   [(set_attr "type" "fmov,multi,multi,multi")
4784    (set_attr "unit" "*,i387,i387,i387")
4785    (set_attr "mode" "DF")])
4786
4787 (define_insn "truncxf<mode>2_i387_noop"
4788   [(set (match_operand:MODEF 0 "register_operand" "=f")
4789         (float_truncate:MODEF
4790           (match_operand:XF 1 "register_operand" "f")))]
4791   "TARGET_80387 && flag_unsafe_math_optimizations"
4792   "* return output_387_reg_move (insn, operands);"
4793   [(set_attr "type" "fmov")
4794    (set_attr "mode" "<MODE>")])
4795
4796 (define_insn "*truncxf<mode>2_i387"
4797   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4798         (float_truncate:MODEF
4799           (match_operand:XF 1 "register_operand" "f")))]
4800   "TARGET_80387"
4801   "* return output_387_reg_move (insn, operands);"
4802   [(set_attr "type" "fmov")
4803    (set_attr "mode" "<MODE>")])
4804
4805 (define_split
4806   [(set (match_operand:MODEF 0 "register_operand" "")
4807         (float_truncate:MODEF
4808           (match_operand:XF 1 "register_operand" "")))
4809    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4810   "TARGET_80387 && reload_completed"
4811   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4812    (set (match_dup 0) (match_dup 2))]
4813   "")
4814
4815 (define_split
4816   [(set (match_operand:MODEF 0 "memory_operand" "")
4817         (float_truncate:MODEF
4818           (match_operand:XF 1 "register_operand" "")))
4819    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4820   "TARGET_80387"
4821   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4822   "")
4823 \f
4824 ;; Signed conversion to DImode.
4825
4826 (define_expand "fix_truncxfdi2"
4827   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4828                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4829               (clobber (reg:CC FLAGS_REG))])]
4830   "TARGET_80387"
4831 {
4832   if (TARGET_FISTTP)
4833    {
4834      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4835      DONE;
4836    }
4837 })
4838
4839 (define_expand "fix_trunc<mode>di2"
4840   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4841                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4842               (clobber (reg:CC FLAGS_REG))])]
4843   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4844 {
4845   if (TARGET_FISTTP
4846       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4847    {
4848      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4849      DONE;
4850    }
4851   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4852    {
4853      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4854      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4855      if (out != operands[0])
4856         emit_move_insn (operands[0], out);
4857      DONE;
4858    }
4859 })
4860
4861 ;; Signed conversion to SImode.
4862
4863 (define_expand "fix_truncxfsi2"
4864   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4865                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4866               (clobber (reg:CC FLAGS_REG))])]
4867   "TARGET_80387"
4868 {
4869   if (TARGET_FISTTP)
4870    {
4871      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4872      DONE;
4873    }
4874 })
4875
4876 (define_expand "fix_trunc<mode>si2"
4877   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4878                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4879               (clobber (reg:CC FLAGS_REG))])]
4880   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4881 {
4882   if (TARGET_FISTTP
4883       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4884    {
4885      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4886      DONE;
4887    }
4888   if (SSE_FLOAT_MODE_P (<MODE>mode))
4889    {
4890      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4891      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4892      if (out != operands[0])
4893         emit_move_insn (operands[0], out);
4894      DONE;
4895    }
4896 })
4897
4898 ;; Signed conversion to HImode.
4899
4900 (define_expand "fix_trunc<mode>hi2"
4901   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4902                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4903               (clobber (reg:CC FLAGS_REG))])]
4904   "TARGET_80387
4905    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4906 {
4907   if (TARGET_FISTTP)
4908    {
4909      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4910      DONE;
4911    }
4912 })
4913
4914 ;; Unsigned conversion to SImode.
4915
4916 (define_expand "fixuns_trunc<mode>si2"
4917   [(parallel
4918     [(set (match_operand:SI 0 "register_operand" "")
4919           (unsigned_fix:SI
4920             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4921      (use (match_dup 2))
4922      (clobber (match_scratch:<ssevecmode> 3 ""))
4923      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4924   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4925 {
4926   enum machine_mode mode = <MODE>mode;
4927   enum machine_mode vecmode = <ssevecmode>mode;
4928   REAL_VALUE_TYPE TWO31r;
4929   rtx two31;
4930
4931   if (optimize_insn_for_size_p ())
4932     FAIL;
4933
4934   real_ldexp (&TWO31r, &dconst1, 31);
4935   two31 = const_double_from_real_value (TWO31r, mode);
4936   two31 = ix86_build_const_vector (mode, true, two31);
4937   operands[2] = force_reg (vecmode, two31);
4938 })
4939
4940 (define_insn_and_split "*fixuns_trunc<mode>_1"
4941   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4942         (unsigned_fix:SI
4943           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4944    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4945    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4946    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4947   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4948    && optimize_function_for_speed_p (cfun)"
4949   "#"
4950   "&& reload_completed"
4951   [(const_int 0)]
4952 {
4953   ix86_split_convert_uns_si_sse (operands);
4954   DONE;
4955 })
4956
4957 ;; Unsigned conversion to HImode.
4958 ;; Without these patterns, we'll try the unsigned SI conversion which
4959 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4960
4961 (define_expand "fixuns_trunc<mode>hi2"
4962   [(set (match_dup 2)
4963         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4964    (set (match_operand:HI 0 "nonimmediate_operand" "")
4965         (subreg:HI (match_dup 2) 0))]
4966   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4967   "operands[2] = gen_reg_rtx (SImode);")
4968
4969 ;; When SSE is available, it is always faster to use it!
4970 (define_insn "fix_trunc<mode>di_sse"
4971   [(set (match_operand:DI 0 "register_operand" "=r,r")
4972         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4973   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4974    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4975   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4976   [(set_attr "type" "sseicvt")
4977    (set_attr "prefix" "maybe_vex")
4978    (set_attr "mode" "<MODE>")
4979    (set_attr "athlon_decode" "double,vector")
4980    (set_attr "amdfam10_decode" "double,double")])
4981
4982 (define_insn "fix_trunc<mode>si_sse"
4983   [(set (match_operand:SI 0 "register_operand" "=r,r")
4984         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4985   "SSE_FLOAT_MODE_P (<MODE>mode)
4986    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4987   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4988   [(set_attr "type" "sseicvt")
4989    (set_attr "prefix" "maybe_vex")
4990    (set_attr "mode" "<MODE>")
4991    (set_attr "athlon_decode" "double,vector")
4992    (set_attr "amdfam10_decode" "double,double")])
4993
4994 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4995 (define_peephole2
4996   [(set (match_operand:MODEF 0 "register_operand" "")
4997         (match_operand:MODEF 1 "memory_operand" ""))
4998    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4999         (fix:SSEMODEI24 (match_dup 0)))]
5000   "TARGET_SHORTEN_X87_SSE
5001    && peep2_reg_dead_p (2, operands[0])"
5002   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5003   "")
5004
5005 ;; Avoid vector decoded forms of the instruction.
5006 (define_peephole2
5007   [(match_scratch:DF 2 "Y2")
5008    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5009         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5010   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5011   [(set (match_dup 2) (match_dup 1))
5012    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5013   "")
5014
5015 (define_peephole2
5016   [(match_scratch:SF 2 "x")
5017    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5018         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5019   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5020   [(set (match_dup 2) (match_dup 1))
5021    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5022   "")
5023
5024 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5025   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5026         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5027   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5028    && TARGET_FISTTP
5029    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5030          && (TARGET_64BIT || <MODE>mode != DImode))
5031         && TARGET_SSE_MATH)
5032    && !(reload_completed || reload_in_progress)"
5033   "#"
5034   "&& 1"
5035   [(const_int 0)]
5036 {
5037   if (memory_operand (operands[0], VOIDmode))
5038     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5039   else
5040     {
5041       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5042       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5043                                                             operands[1],
5044                                                             operands[2]));
5045     }
5046   DONE;
5047 }
5048   [(set_attr "type" "fisttp")
5049    (set_attr "mode" "<MODE>")])
5050
5051 (define_insn "fix_trunc<mode>_i387_fisttp"
5052   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5053         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5054    (clobber (match_scratch:XF 2 "=&1f"))]
5055   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5056    && TARGET_FISTTP
5057    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5058          && (TARGET_64BIT || <MODE>mode != DImode))
5059         && TARGET_SSE_MATH)"
5060   "* return output_fix_trunc (insn, operands, 1);"
5061   [(set_attr "type" "fisttp")
5062    (set_attr "mode" "<MODE>")])
5063
5064 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5065   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5066         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5067    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5068    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5069   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5070    && TARGET_FISTTP
5071    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5072         && (TARGET_64BIT || <MODE>mode != DImode))
5073         && TARGET_SSE_MATH)"
5074   "#"
5075   [(set_attr "type" "fisttp")
5076    (set_attr "mode" "<MODE>")])
5077
5078 (define_split
5079   [(set (match_operand:X87MODEI 0 "register_operand" "")
5080         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5081    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5082    (clobber (match_scratch 3 ""))]
5083   "reload_completed"
5084   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5085               (clobber (match_dup 3))])
5086    (set (match_dup 0) (match_dup 2))]
5087   "")
5088
5089 (define_split
5090   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5091         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5092    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5093    (clobber (match_scratch 3 ""))]
5094   "reload_completed"
5095   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5096               (clobber (match_dup 3))])]
5097   "")
5098
5099 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5100 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5101 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5102 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5103 ;; function in i386.c.
5104 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5105   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5106         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5107    (clobber (reg:CC FLAGS_REG))]
5108   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5109    && !TARGET_FISTTP
5110    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5111          && (TARGET_64BIT || <MODE>mode != DImode))
5112    && !(reload_completed || reload_in_progress)"
5113   "#"
5114   "&& 1"
5115   [(const_int 0)]
5116 {
5117   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5118
5119   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5120   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5121   if (memory_operand (operands[0], VOIDmode))
5122     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5123                                          operands[2], operands[3]));
5124   else
5125     {
5126       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5127       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5128                                                      operands[2], operands[3],
5129                                                      operands[4]));
5130     }
5131   DONE;
5132 }
5133   [(set_attr "type" "fistp")
5134    (set_attr "i387_cw" "trunc")
5135    (set_attr "mode" "<MODE>")])
5136
5137 (define_insn "fix_truncdi_i387"
5138   [(set (match_operand:DI 0 "memory_operand" "=m")
5139         (fix:DI (match_operand 1 "register_operand" "f")))
5140    (use (match_operand:HI 2 "memory_operand" "m"))
5141    (use (match_operand:HI 3 "memory_operand" "m"))
5142    (clobber (match_scratch:XF 4 "=&1f"))]
5143   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5144    && !TARGET_FISTTP
5145    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5146   "* return output_fix_trunc (insn, operands, 0);"
5147   [(set_attr "type" "fistp")
5148    (set_attr "i387_cw" "trunc")
5149    (set_attr "mode" "DI")])
5150
5151 (define_insn "fix_truncdi_i387_with_temp"
5152   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5153         (fix:DI (match_operand 1 "register_operand" "f,f")))
5154    (use (match_operand:HI 2 "memory_operand" "m,m"))
5155    (use (match_operand:HI 3 "memory_operand" "m,m"))
5156    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5157    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5158   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5159    && !TARGET_FISTTP
5160    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5161   "#"
5162   [(set_attr "type" "fistp")
5163    (set_attr "i387_cw" "trunc")
5164    (set_attr "mode" "DI")])
5165
5166 (define_split
5167   [(set (match_operand:DI 0 "register_operand" "")
5168         (fix:DI (match_operand 1 "register_operand" "")))
5169    (use (match_operand:HI 2 "memory_operand" ""))
5170    (use (match_operand:HI 3 "memory_operand" ""))
5171    (clobber (match_operand:DI 4 "memory_operand" ""))
5172    (clobber (match_scratch 5 ""))]
5173   "reload_completed"
5174   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5175               (use (match_dup 2))
5176               (use (match_dup 3))
5177               (clobber (match_dup 5))])
5178    (set (match_dup 0) (match_dup 4))]
5179   "")
5180
5181 (define_split
5182   [(set (match_operand:DI 0 "memory_operand" "")
5183         (fix:DI (match_operand 1 "register_operand" "")))
5184    (use (match_operand:HI 2 "memory_operand" ""))
5185    (use (match_operand:HI 3 "memory_operand" ""))
5186    (clobber (match_operand:DI 4 "memory_operand" ""))
5187    (clobber (match_scratch 5 ""))]
5188   "reload_completed"
5189   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5190               (use (match_dup 2))
5191               (use (match_dup 3))
5192               (clobber (match_dup 5))])]
5193   "")
5194
5195 (define_insn "fix_trunc<mode>_i387"
5196   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5197         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5198    (use (match_operand:HI 2 "memory_operand" "m"))
5199    (use (match_operand:HI 3 "memory_operand" "m"))]
5200   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5201    && !TARGET_FISTTP
5202    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5203   "* return output_fix_trunc (insn, operands, 0);"
5204   [(set_attr "type" "fistp")
5205    (set_attr "i387_cw" "trunc")
5206    (set_attr "mode" "<MODE>")])
5207
5208 (define_insn "fix_trunc<mode>_i387_with_temp"
5209   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5210         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5211    (use (match_operand:HI 2 "memory_operand" "m,m"))
5212    (use (match_operand:HI 3 "memory_operand" "m,m"))
5213    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5214   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5215    && !TARGET_FISTTP
5216    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5217   "#"
5218   [(set_attr "type" "fistp")
5219    (set_attr "i387_cw" "trunc")
5220    (set_attr "mode" "<MODE>")])
5221
5222 (define_split
5223   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5224         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5225    (use (match_operand:HI 2 "memory_operand" ""))
5226    (use (match_operand:HI 3 "memory_operand" ""))
5227    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5228   "reload_completed"
5229   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5230               (use (match_dup 2))
5231               (use (match_dup 3))])
5232    (set (match_dup 0) (match_dup 4))]
5233   "")
5234
5235 (define_split
5236   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5237         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5238    (use (match_operand:HI 2 "memory_operand" ""))
5239    (use (match_operand:HI 3 "memory_operand" ""))
5240    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5241   "reload_completed"
5242   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5243               (use (match_dup 2))
5244               (use (match_dup 3))])]
5245   "")
5246
5247 (define_insn "x86_fnstcw_1"
5248   [(set (match_operand:HI 0 "memory_operand" "=m")
5249         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5250   "TARGET_80387"
5251   "fnstcw\t%0"
5252   [(set_attr "length" "2")
5253    (set_attr "mode" "HI")
5254    (set_attr "unit" "i387")])
5255
5256 (define_insn "x86_fldcw_1"
5257   [(set (reg:HI FPCR_REG)
5258         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5259   "TARGET_80387"
5260   "fldcw\t%0"
5261   [(set_attr "length" "2")
5262    (set_attr "mode" "HI")
5263    (set_attr "unit" "i387")
5264    (set_attr "athlon_decode" "vector")
5265    (set_attr "amdfam10_decode" "vector")])
5266 \f
5267 ;; Conversion between fixed point and floating point.
5268
5269 ;; Even though we only accept memory inputs, the backend _really_
5270 ;; wants to be able to do this between registers.
5271
5272 (define_expand "floathi<mode>2"
5273   [(set (match_operand:X87MODEF 0 "register_operand" "")
5274         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5275   "TARGET_80387
5276    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5277        || TARGET_MIX_SSE_I387)"
5278   "")
5279
5280 ;; Pre-reload splitter to add memory clobber to the pattern.
5281 (define_insn_and_split "*floathi<mode>2_1"
5282   [(set (match_operand:X87MODEF 0 "register_operand" "")
5283         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5284   "TARGET_80387
5285    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5286        || TARGET_MIX_SSE_I387)
5287    && !(reload_completed || reload_in_progress)"
5288   "#"
5289   "&& 1"
5290   [(parallel [(set (match_dup 0)
5291               (float:X87MODEF (match_dup 1)))
5292    (clobber (match_dup 2))])]
5293   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5294
5295 (define_insn "*floathi<mode>2_i387_with_temp"
5296   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5297         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5298   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5299   "TARGET_80387
5300    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5301        || TARGET_MIX_SSE_I387)"
5302   "#"
5303   [(set_attr "type" "fmov,multi")
5304    (set_attr "mode" "<MODE>")
5305    (set_attr "unit" "*,i387")
5306    (set_attr "fp_int_src" "true")])
5307
5308 (define_insn "*floathi<mode>2_i387"
5309   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5310         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5311   "TARGET_80387
5312    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5313        || TARGET_MIX_SSE_I387)"
5314   "fild%Z1\t%1"
5315   [(set_attr "type" "fmov")
5316    (set_attr "mode" "<MODE>")
5317    (set_attr "fp_int_src" "true")])
5318
5319 (define_split
5320   [(set (match_operand:X87MODEF 0 "register_operand" "")
5321         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5322    (clobber (match_operand:HI 2 "memory_operand" ""))]
5323   "TARGET_80387
5324    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5325        || TARGET_MIX_SSE_I387)
5326    && reload_completed"
5327   [(set (match_dup 2) (match_dup 1))
5328    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5329   "")
5330
5331 (define_split
5332   [(set (match_operand:X87MODEF 0 "register_operand" "")
5333         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5334    (clobber (match_operand:HI 2 "memory_operand" ""))]
5335    "TARGET_80387
5336     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5337         || TARGET_MIX_SSE_I387)
5338     && reload_completed"
5339   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5340   "")
5341
5342 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5343   [(set (match_operand:X87MODEF 0 "register_operand" "")
5344         (float:X87MODEF
5345           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5346   "TARGET_80387
5347    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5348        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5349   "
5350 {
5351   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5352         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5353       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5354     {
5355       rtx reg = gen_reg_rtx (XFmode);
5356       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5357 /* Avoid references to nonexistent function in dead code in XFmode case.  */
5358 #define gen_truncxfxf2 gen_truncxfdf2
5359       emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5360 #undef gen_truncxfxf2
5361       DONE;
5362     }
5363 }")
5364
5365 ;; Pre-reload splitter to add memory clobber to the pattern.
5366 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5367   [(set (match_operand:X87MODEF 0 "register_operand" "")
5368         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5369   "((TARGET_80387
5370      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5371      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5372            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5373          || TARGET_MIX_SSE_I387))
5374     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5375         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5376         && ((<SSEMODEI24:MODE>mode == SImode
5377              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5378              && optimize_function_for_speed_p (cfun)
5379              && flag_trapping_math)
5380             || !(TARGET_INTER_UNIT_CONVERSIONS
5381                  || optimize_function_for_size_p (cfun)))))
5382    && !(reload_completed || reload_in_progress)"
5383   "#"
5384   "&& 1"
5385   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5386               (clobber (match_dup 2))])]
5387 {
5388   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5389
5390   /* Avoid store forwarding (partial memory) stall penalty
5391      by passing DImode value through XMM registers.  */
5392   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5393       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5394       && optimize_function_for_speed_p (cfun))
5395     {
5396       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5397                                                             operands[1],
5398                                                             operands[2]));
5399       DONE;
5400     }
5401 })
5402
5403 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5404   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5405         (float:MODEF
5406           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5407    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5408   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5409    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5410   "#"
5411   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5412    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5413    (set_attr "unit" "*,i387,*,*,*")
5414    (set_attr "athlon_decode" "*,*,double,direct,double")
5415    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5416    (set_attr "fp_int_src" "true")])
5417
5418 (define_insn "*floatsi<mode>2_vector_mixed"
5419   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5420         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5421   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5422    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5423   "@
5424    fild%Z1\t%1
5425    #"
5426   [(set_attr "type" "fmov,sseicvt")
5427    (set_attr "mode" "<MODE>,<ssevecmode>")
5428    (set_attr "unit" "i387,*")
5429    (set_attr "athlon_decode" "*,direct")
5430    (set_attr "amdfam10_decode" "*,double")
5431    (set_attr "fp_int_src" "true")])
5432
5433 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5434   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5435         (float:MODEF
5436           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5437   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5438   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5439    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5440   "#"
5441   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5442    (set_attr "mode" "<MODEF:MODE>")
5443    (set_attr "unit" "*,i387,*,*")
5444    (set_attr "athlon_decode" "*,*,double,direct")
5445    (set_attr "amdfam10_decode" "*,*,vector,double")
5446    (set_attr "fp_int_src" "true")])
5447
5448 (define_split
5449   [(set (match_operand:MODEF 0 "register_operand" "")
5450         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5451    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5452   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5453    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5454    && TARGET_INTER_UNIT_CONVERSIONS
5455    && reload_completed
5456    && (SSE_REG_P (operands[0])
5457        || (GET_CODE (operands[0]) == SUBREG
5458            && SSE_REG_P (operands[0])))"
5459   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5460   "")
5461
5462 (define_split
5463   [(set (match_operand:MODEF 0 "register_operand" "")
5464         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5465    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5466   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5467    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5468    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5469    && reload_completed
5470    && (SSE_REG_P (operands[0])
5471        || (GET_CODE (operands[0]) == SUBREG
5472            && SSE_REG_P (operands[0])))"
5473   [(set (match_dup 2) (match_dup 1))
5474    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5475   "")
5476
5477 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5478   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5479         (float:MODEF
5480           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5481   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5482    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5483    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5484   "@
5485    fild%Z1\t%1
5486    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5487    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5488   [(set_attr "type" "fmov,sseicvt,sseicvt")
5489    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5490    (set_attr "mode" "<MODEF:MODE>")
5491    (set_attr "unit" "i387,*,*")
5492    (set_attr "athlon_decode" "*,double,direct")
5493    (set_attr "amdfam10_decode" "*,vector,double")
5494    (set_attr "fp_int_src" "true")])
5495
5496 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5497   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5498         (float:MODEF
5499           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5500   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5501    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5502    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5503   "@
5504    fild%Z1\t%1
5505    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5506   [(set_attr "type" "fmov,sseicvt")
5507    (set_attr "prefix" "orig,maybe_vex")
5508    (set_attr "mode" "<MODEF:MODE>")
5509    (set_attr "athlon_decode" "*,direct")
5510    (set_attr "amdfam10_decode" "*,double")
5511    (set_attr "fp_int_src" "true")])
5512
5513 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5514   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5515         (float:MODEF
5516           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5517    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5518   "TARGET_SSE2 && TARGET_SSE_MATH
5519    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5520   "#"
5521   [(set_attr "type" "sseicvt")
5522    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5523    (set_attr "athlon_decode" "double,direct,double")
5524    (set_attr "amdfam10_decode" "vector,double,double")
5525    (set_attr "fp_int_src" "true")])
5526
5527 (define_insn "*floatsi<mode>2_vector_sse"
5528   [(set (match_operand:MODEF 0 "register_operand" "=x")
5529         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5530   "TARGET_SSE2 && TARGET_SSE_MATH
5531    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5532   "#"
5533   [(set_attr "type" "sseicvt")
5534    (set_attr "mode" "<MODE>")
5535    (set_attr "athlon_decode" "direct")
5536    (set_attr "amdfam10_decode" "double")
5537    (set_attr "fp_int_src" "true")])
5538
5539 (define_split
5540   [(set (match_operand:MODEF 0 "register_operand" "")
5541         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5542    (clobber (match_operand:SI 2 "memory_operand" ""))]
5543   "TARGET_SSE2 && TARGET_SSE_MATH
5544    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5545    && reload_completed
5546    && (SSE_REG_P (operands[0])
5547        || (GET_CODE (operands[0]) == SUBREG
5548            && SSE_REG_P (operands[0])))"
5549   [(const_int 0)]
5550 {
5551   rtx op1 = operands[1];
5552
5553   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5554                                      <MODE>mode, 0);
5555   if (GET_CODE (op1) == SUBREG)
5556     op1 = SUBREG_REG (op1);
5557
5558   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5559     {
5560       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5561       emit_insn (gen_sse2_loadld (operands[4],
5562                                   CONST0_RTX (V4SImode), operands[1]));
5563     }
5564   /* We can ignore possible trapping value in the
5565      high part of SSE register for non-trapping math. */
5566   else if (SSE_REG_P (op1) && !flag_trapping_math)
5567     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5568   else
5569     {
5570       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5571       emit_move_insn (operands[2], operands[1]);
5572       emit_insn (gen_sse2_loadld (operands[4],
5573                                   CONST0_RTX (V4SImode), operands[2]));
5574     }
5575   emit_insn
5576     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5577   DONE;
5578 })
5579
5580 (define_split
5581   [(set (match_operand:MODEF 0 "register_operand" "")
5582         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5583    (clobber (match_operand:SI 2 "memory_operand" ""))]
5584   "TARGET_SSE2 && TARGET_SSE_MATH
5585    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5586    && reload_completed
5587    && (SSE_REG_P (operands[0])
5588        || (GET_CODE (operands[0]) == SUBREG
5589            && SSE_REG_P (operands[0])))"
5590   [(const_int 0)]
5591 {
5592   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5593                                      <MODE>mode, 0);
5594   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5595
5596   emit_insn (gen_sse2_loadld (operands[4],
5597                               CONST0_RTX (V4SImode), operands[1]));
5598   emit_insn
5599     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5600   DONE;
5601 })
5602
5603 (define_split
5604   [(set (match_operand:MODEF 0 "register_operand" "")
5605         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5606   "TARGET_SSE2 && TARGET_SSE_MATH
5607    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5608    && reload_completed
5609    && (SSE_REG_P (operands[0])
5610        || (GET_CODE (operands[0]) == SUBREG
5611            && SSE_REG_P (operands[0])))"
5612   [(const_int 0)]
5613 {
5614   rtx op1 = operands[1];
5615
5616   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5617                                      <MODE>mode, 0);
5618   if (GET_CODE (op1) == SUBREG)
5619     op1 = SUBREG_REG (op1);
5620
5621   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5622     {
5623       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5624       emit_insn (gen_sse2_loadld (operands[4],
5625                                   CONST0_RTX (V4SImode), operands[1]));
5626     }
5627   /* We can ignore possible trapping value in the
5628      high part of SSE register for non-trapping math. */
5629   else if (SSE_REG_P (op1) && !flag_trapping_math)
5630     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5631   else
5632     gcc_unreachable ();
5633   emit_insn
5634     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5635   DONE;
5636 })
5637
5638 (define_split
5639   [(set (match_operand:MODEF 0 "register_operand" "")
5640         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5641   "TARGET_SSE2 && TARGET_SSE_MATH
5642    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5643    && reload_completed
5644    && (SSE_REG_P (operands[0])
5645        || (GET_CODE (operands[0]) == SUBREG
5646            && SSE_REG_P (operands[0])))"
5647   [(const_int 0)]
5648 {
5649   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5650                                      <MODE>mode, 0);
5651   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5652
5653   emit_insn (gen_sse2_loadld (operands[4],
5654                               CONST0_RTX (V4SImode), operands[1]));
5655   emit_insn
5656     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5657   DONE;
5658 })
5659
5660 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5661   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5662         (float:MODEF
5663           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5664   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5665   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5666    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5667   "#"
5668   [(set_attr "type" "sseicvt")
5669    (set_attr "mode" "<MODEF:MODE>")
5670    (set_attr "athlon_decode" "double,direct")
5671    (set_attr "amdfam10_decode" "vector,double")
5672    (set_attr "fp_int_src" "true")])
5673
5674 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5675   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5676         (float:MODEF
5677           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5678   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5679    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5680    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5681   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5682   [(set_attr "type" "sseicvt")
5683    (set_attr "prefix" "maybe_vex")
5684    (set_attr "mode" "<MODEF:MODE>")
5685    (set_attr "athlon_decode" "double,direct")
5686    (set_attr "amdfam10_decode" "vector,double")
5687    (set_attr "fp_int_src" "true")])
5688
5689 (define_split
5690   [(set (match_operand:MODEF 0 "register_operand" "")
5691         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5692    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5693   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5694    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5695    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5696    && reload_completed
5697    && (SSE_REG_P (operands[0])
5698        || (GET_CODE (operands[0]) == SUBREG
5699            && SSE_REG_P (operands[0])))"
5700   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5701   "")
5702
5703 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5704   [(set (match_operand:MODEF 0 "register_operand" "=x")
5705         (float:MODEF
5706           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5707   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5708    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5709    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5710   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5711   [(set_attr "type" "sseicvt")
5712    (set_attr "prefix" "maybe_vex")
5713    (set_attr "mode" "<MODEF:MODE>")
5714    (set_attr "athlon_decode" "direct")
5715    (set_attr "amdfam10_decode" "double")
5716    (set_attr "fp_int_src" "true")])
5717
5718 (define_split
5719   [(set (match_operand:MODEF 0 "register_operand" "")
5720         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5721    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5722   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5723    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5724    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5725    && reload_completed
5726    && (SSE_REG_P (operands[0])
5727        || (GET_CODE (operands[0]) == SUBREG
5728            && SSE_REG_P (operands[0])))"
5729   [(set (match_dup 2) (match_dup 1))
5730    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5731   "")
5732
5733 (define_split
5734   [(set (match_operand:MODEF 0 "register_operand" "")
5735         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5736    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5737   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5738    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5739    && reload_completed
5740    && (SSE_REG_P (operands[0])
5741        || (GET_CODE (operands[0]) == SUBREG
5742            && SSE_REG_P (operands[0])))"
5743   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5744   "")
5745
5746 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5747   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5748         (float:X87MODEF
5749           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5750   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5751   "TARGET_80387
5752    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5753   "@
5754    fild%Z1\t%1
5755    #"
5756   [(set_attr "type" "fmov,multi")
5757    (set_attr "mode" "<X87MODEF:MODE>")
5758    (set_attr "unit" "*,i387")
5759    (set_attr "fp_int_src" "true")])
5760
5761 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5762   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5763         (float:X87MODEF
5764           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5765   "TARGET_80387
5766    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5767   "fild%Z1\t%1"
5768   [(set_attr "type" "fmov")
5769    (set_attr "mode" "<X87MODEF:MODE>")
5770    (set_attr "fp_int_src" "true")])
5771
5772 (define_split
5773   [(set (match_operand:X87MODEF 0 "register_operand" "")
5774         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5775    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5776   "TARGET_80387
5777    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5778    && reload_completed
5779    && FP_REG_P (operands[0])"
5780   [(set (match_dup 2) (match_dup 1))
5781    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5782   "")
5783
5784 (define_split
5785   [(set (match_operand:X87MODEF 0 "register_operand" "")
5786         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5787    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5788   "TARGET_80387
5789    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5790    && reload_completed
5791    && FP_REG_P (operands[0])"
5792   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5793   "")
5794
5795 ;; Avoid store forwarding (partial memory) stall penalty
5796 ;; by passing DImode value through XMM registers.  */
5797
5798 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5799   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5800         (float:X87MODEF
5801           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5802    (clobber (match_scratch:V4SI 3 "=X,x"))
5803    (clobber (match_scratch:V4SI 4 "=X,x"))
5804    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5805   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5806    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5807    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5808   "#"
5809   [(set_attr "type" "multi")
5810    (set_attr "mode" "<X87MODEF:MODE>")
5811    (set_attr "unit" "i387")
5812    (set_attr "fp_int_src" "true")])
5813
5814 (define_split
5815   [(set (match_operand:X87MODEF 0 "register_operand" "")
5816         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5817    (clobber (match_scratch:V4SI 3 ""))
5818    (clobber (match_scratch:V4SI 4 ""))
5819    (clobber (match_operand:DI 2 "memory_operand" ""))]
5820   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5821    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5822    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5823    && reload_completed
5824    && FP_REG_P (operands[0])"
5825   [(set (match_dup 2) (match_dup 3))
5826    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5827 {
5828   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5829      Assemble the 64-bit DImode value in an xmm register.  */
5830   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5831                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5832   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5833                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5834   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5835
5836   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5837 })
5838
5839 (define_split
5840   [(set (match_operand:X87MODEF 0 "register_operand" "")
5841         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5842    (clobber (match_scratch:V4SI 3 ""))
5843    (clobber (match_scratch:V4SI 4 ""))
5844    (clobber (match_operand:DI 2 "memory_operand" ""))]
5845   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5846    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5847    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5848    && reload_completed
5849    && FP_REG_P (operands[0])"
5850   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5851   "")
5852
5853 ;; Avoid store forwarding (partial memory) stall penalty by extending
5854 ;; SImode value to DImode through XMM register instead of pushing two
5855 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5856 ;; targets benefit from this optimization. Also note that fild
5857 ;; loads from memory only.
5858
5859 (define_insn "*floatunssi<mode>2_1"
5860   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5861         (unsigned_float:X87MODEF
5862           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5863    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5864    (clobber (match_scratch:SI 3 "=X,x"))]
5865   "!TARGET_64BIT
5866    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5867    && TARGET_SSE"
5868   "#"
5869   [(set_attr "type" "multi")
5870    (set_attr "mode" "<MODE>")])
5871
5872 (define_split
5873   [(set (match_operand:X87MODEF 0 "register_operand" "")
5874         (unsigned_float:X87MODEF
5875           (match_operand:SI 1 "register_operand" "")))
5876    (clobber (match_operand:DI 2 "memory_operand" ""))
5877    (clobber (match_scratch:SI 3 ""))]
5878   "!TARGET_64BIT
5879    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5880    && TARGET_SSE
5881    && reload_completed"
5882   [(set (match_dup 2) (match_dup 1))
5883    (set (match_dup 0)
5884         (float:X87MODEF (match_dup 2)))]
5885   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5886
5887 (define_split
5888   [(set (match_operand:X87MODEF 0 "register_operand" "")
5889         (unsigned_float:X87MODEF
5890           (match_operand:SI 1 "memory_operand" "")))
5891    (clobber (match_operand:DI 2 "memory_operand" ""))
5892    (clobber (match_scratch:SI 3 ""))]
5893   "!TARGET_64BIT
5894    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5895    && TARGET_SSE
5896    && reload_completed"
5897   [(set (match_dup 2) (match_dup 3))
5898    (set (match_dup 0)
5899         (float:X87MODEF (match_dup 2)))]
5900 {
5901   emit_move_insn (operands[3], operands[1]);
5902   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5903 })
5904
5905 (define_expand "floatunssi<mode>2"
5906   [(parallel
5907      [(set (match_operand:X87MODEF 0 "register_operand" "")
5908            (unsigned_float:X87MODEF
5909              (match_operand:SI 1 "nonimmediate_operand" "")))
5910       (clobber (match_dup 2))
5911       (clobber (match_scratch:SI 3 ""))])]
5912   "!TARGET_64BIT
5913    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5914         && TARGET_SSE)
5915        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5916 {
5917   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5918     {
5919       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5920       DONE;
5921     }
5922   else
5923     {
5924       enum ix86_stack_slot slot = (virtuals_instantiated
5925                                    ? SLOT_TEMP
5926                                    : SLOT_VIRTUAL);
5927       operands[2] = assign_386_stack_local (DImode, slot);
5928     }
5929 })
5930
5931 (define_expand "floatunsdisf2"
5932   [(use (match_operand:SF 0 "register_operand" ""))
5933    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5934   "TARGET_64BIT && TARGET_SSE_MATH"
5935   "x86_emit_floatuns (operands); DONE;")
5936
5937 (define_expand "floatunsdidf2"
5938   [(use (match_operand:DF 0 "register_operand" ""))
5939    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5940   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5941    && TARGET_SSE2 && TARGET_SSE_MATH"
5942 {
5943   if (TARGET_64BIT)
5944     x86_emit_floatuns (operands);
5945   else
5946     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5947   DONE;
5948 })
5949 \f
5950 ;; Add instructions
5951
5952 ;; %%% splits for addditi3
5953
5954 (define_expand "addti3"
5955   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5956         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5957                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5958   "TARGET_64BIT"
5959   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5960
5961 (define_insn "*addti3_1"
5962   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5963         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5964                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5965    (clobber (reg:CC FLAGS_REG))]
5966   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5967   "#")
5968
5969 (define_split
5970   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5971         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5972                  (match_operand:TI 2 "x86_64_general_operand" "")))
5973    (clobber (reg:CC FLAGS_REG))]
5974   "TARGET_64BIT && reload_completed"
5975   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5976                                           UNSPEC_ADD_CARRY))
5977               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5978    (parallel [(set (match_dup 3)
5979                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5980                                      (match_dup 4))
5981                             (match_dup 5)))
5982               (clobber (reg:CC FLAGS_REG))])]
5983   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5984
5985 ;; %%% splits for addsidi3
5986 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5987 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5988 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5989
5990 (define_expand "adddi3"
5991   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5992         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5993                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5994   ""
5995   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5996
5997 (define_insn "*adddi3_1"
5998   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5999         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6000                  (match_operand:DI 2 "general_operand" "roiF,riF")))
6001    (clobber (reg:CC FLAGS_REG))]
6002   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6003   "#")
6004
6005 (define_split
6006   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6007         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6008                  (match_operand:DI 2 "general_operand" "")))
6009    (clobber (reg:CC FLAGS_REG))]
6010   "!TARGET_64BIT && reload_completed"
6011   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6012                                           UNSPEC_ADD_CARRY))
6013               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
6014    (parallel [(set (match_dup 3)
6015                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6016                                      (match_dup 4))
6017                             (match_dup 5)))
6018               (clobber (reg:CC FLAGS_REG))])]
6019   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
6020
6021 (define_insn "adddi3_carry_rex64"
6022   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6023           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6024                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
6025                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6026    (clobber (reg:CC FLAGS_REG))]
6027   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6028   "adc{q}\t{%2, %0|%0, %2}"
6029   [(set_attr "type" "alu")
6030    (set_attr "use_carry" "1")
6031    (set_attr "pent_pair" "pu")
6032    (set_attr "mode" "DI")])
6033
6034 (define_insn "*adddi3_cc_rex64"
6035   [(set (reg:CC FLAGS_REG)
6036         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
6037                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
6038                    UNSPEC_ADD_CARRY))
6039    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6040         (plus:DI (match_dup 1) (match_dup 2)))]
6041   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6042   "add{q}\t{%2, %0|%0, %2}"
6043   [(set_attr "type" "alu")
6044    (set_attr "mode" "DI")])
6045
6046 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6047   [(set (reg:CCC FLAGS_REG)
6048         (compare:CCC
6049             (plusminus:SWI
6050                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6051                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6052             (match_dup 1)))
6053    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6054         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6055   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6056   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6057   [(set_attr "type" "alu")
6058    (set_attr "mode" "<MODE>")])
6059
6060 (define_insn "*add<mode>3_cconly_overflow"
6061   [(set (reg:CCC FLAGS_REG)
6062         (compare:CCC
6063                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
6064                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6065                 (match_dup 1)))
6066    (clobber (match_scratch:SWI 0 "=<r>"))]
6067   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6068   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6069   [(set_attr "type" "alu")
6070    (set_attr "mode" "<MODE>")])
6071
6072 (define_insn "*sub<mode>3_cconly_overflow"
6073   [(set (reg:CCC FLAGS_REG)
6074         (compare:CCC
6075              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6076                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6077              (match_dup 0)))]
6078   ""
6079   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6080   [(set_attr "type" "icmp")
6081    (set_attr "mode" "<MODE>")])
6082
6083 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6084   [(set (reg:CCC FLAGS_REG)
6085         (compare:CCC
6086             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6087                           (match_operand:SI 2 "general_operand" "g"))
6088             (match_dup 1)))
6089    (set (match_operand:DI 0 "register_operand" "=r")
6090         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6091   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6092   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6093   [(set_attr "type" "alu")
6094    (set_attr "mode" "SI")])
6095
6096 (define_insn "addqi3_carry"
6097   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6098           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6099                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
6100                    (match_operand:QI 2 "general_operand" "qn,qm")))
6101    (clobber (reg:CC FLAGS_REG))]
6102   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6103   "adc{b}\t{%2, %0|%0, %2}"
6104   [(set_attr "type" "alu")
6105    (set_attr "use_carry" "1")
6106    (set_attr "pent_pair" "pu")
6107    (set_attr "mode" "QI")])
6108
6109 (define_insn "addhi3_carry"
6110   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6111           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6112                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
6113                    (match_operand:HI 2 "general_operand" "rn,rm")))
6114    (clobber (reg:CC FLAGS_REG))]
6115   "ix86_binary_operator_ok (PLUS, HImode, operands)"
6116   "adc{w}\t{%2, %0|%0, %2}"
6117   [(set_attr "type" "alu")
6118    (set_attr "use_carry" "1")
6119    (set_attr "pent_pair" "pu")
6120    (set_attr "mode" "HI")])
6121
6122 (define_insn "addsi3_carry"
6123   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6124           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6125                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
6126                    (match_operand:SI 2 "general_operand" "ri,rm")))
6127    (clobber (reg:CC FLAGS_REG))]
6128   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6129   "adc{l}\t{%2, %0|%0, %2}"
6130   [(set_attr "type" "alu")
6131    (set_attr "use_carry" "1")
6132    (set_attr "pent_pair" "pu")
6133    (set_attr "mode" "SI")])
6134
6135 (define_insn "*addsi3_carry_zext"
6136   [(set (match_operand:DI 0 "register_operand" "=r")
6137           (zero_extend:DI
6138             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6139                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
6140                      (match_operand:SI 2 "general_operand" "g"))))
6141    (clobber (reg:CC FLAGS_REG))]
6142   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6143   "adc{l}\t{%2, %k0|%k0, %2}"
6144   [(set_attr "type" "alu")
6145    (set_attr "use_carry" "1")
6146    (set_attr "pent_pair" "pu")
6147    (set_attr "mode" "SI")])
6148
6149 (define_insn "*addsi3_cc"
6150   [(set (reg:CC FLAGS_REG)
6151         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
6152                     (match_operand:SI 2 "general_operand" "ri,rm")]
6153                    UNSPEC_ADD_CARRY))
6154    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6155         (plus:SI (match_dup 1) (match_dup 2)))]
6156   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6157   "add{l}\t{%2, %0|%0, %2}"
6158   [(set_attr "type" "alu")
6159    (set_attr "mode" "SI")])
6160
6161 (define_insn "addqi3_cc"
6162   [(set (reg:CC FLAGS_REG)
6163         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6164                     (match_operand:QI 2 "general_operand" "qn,qm")]
6165                    UNSPEC_ADD_CARRY))
6166    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6167         (plus:QI (match_dup 1) (match_dup 2)))]
6168   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6169   "add{b}\t{%2, %0|%0, %2}"
6170   [(set_attr "type" "alu")
6171    (set_attr "mode" "QI")])
6172
6173 (define_expand "addsi3"
6174   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6175         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6176                  (match_operand:SI 2 "general_operand" "")))]
6177   ""
6178   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
6179
6180 (define_insn "*lea_1"
6181   [(set (match_operand:SI 0 "register_operand" "=r")
6182         (match_operand:SI 1 "no_seg_address_operand" "p"))]
6183   "!TARGET_64BIT"
6184   "lea{l}\t{%a1, %0|%0, %a1}"
6185   [(set_attr "type" "lea")
6186    (set_attr "mode" "SI")])
6187
6188 (define_insn "*lea_1_rex64"
6189   [(set (match_operand:SI 0 "register_operand" "=r")
6190         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6191   "TARGET_64BIT"
6192   "lea{l}\t{%a1, %0|%0, %a1}"
6193   [(set_attr "type" "lea")
6194    (set_attr "mode" "SI")])
6195
6196 (define_insn "*lea_1_zext"
6197   [(set (match_operand:DI 0 "register_operand" "=r")
6198         (zero_extend:DI
6199          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6200   "TARGET_64BIT"
6201   "lea{l}\t{%a1, %k0|%k0, %a1}"
6202   [(set_attr "type" "lea")
6203    (set_attr "mode" "SI")])
6204
6205 (define_insn "*lea_2_rex64"
6206   [(set (match_operand:DI 0 "register_operand" "=r")
6207         (match_operand:DI 1 "no_seg_address_operand" "p"))]
6208   "TARGET_64BIT"
6209   "lea{q}\t{%a1, %0|%0, %a1}"
6210   [(set_attr "type" "lea")
6211    (set_attr "mode" "DI")])
6212
6213 ;; The lea patterns for non-Pmodes needs to be matched by several
6214 ;; insns converted to real lea by splitters.
6215
6216 (define_insn_and_split "*lea_general_1"
6217   [(set (match_operand 0 "register_operand" "=r")
6218         (plus (plus (match_operand 1 "index_register_operand" "l")
6219                     (match_operand 2 "register_operand" "r"))
6220               (match_operand 3 "immediate_operand" "i")))]
6221   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6222     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6223    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6224    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6225    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6226    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6227        || GET_MODE (operands[3]) == VOIDmode)"
6228   "#"
6229   "&& reload_completed"
6230   [(const_int 0)]
6231 {
6232   rtx pat;
6233   operands[0] = gen_lowpart (SImode, operands[0]);
6234   operands[1] = gen_lowpart (Pmode, operands[1]);
6235   operands[2] = gen_lowpart (Pmode, operands[2]);
6236   operands[3] = gen_lowpart (Pmode, operands[3]);
6237   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6238                       operands[3]);
6239   if (Pmode != SImode)
6240     pat = gen_rtx_SUBREG (SImode, pat, 0);
6241   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6242   DONE;
6243 }
6244   [(set_attr "type" "lea")
6245    (set_attr "mode" "SI")])
6246
6247 (define_insn_and_split "*lea_general_1_zext"
6248   [(set (match_operand:DI 0 "register_operand" "=r")
6249         (zero_extend:DI
6250           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6251                             (match_operand:SI 2 "register_operand" "r"))
6252                    (match_operand:SI 3 "immediate_operand" "i"))))]
6253   "TARGET_64BIT"
6254   "#"
6255   "&& reload_completed"
6256   [(set (match_dup 0)
6257         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6258                                                      (match_dup 2))
6259                                             (match_dup 3)) 0)))]
6260 {
6261   operands[1] = gen_lowpart (Pmode, operands[1]);
6262   operands[2] = gen_lowpart (Pmode, operands[2]);
6263   operands[3] = gen_lowpart (Pmode, operands[3]);
6264 }
6265   [(set_attr "type" "lea")
6266    (set_attr "mode" "SI")])
6267
6268 (define_insn_and_split "*lea_general_2"
6269   [(set (match_operand 0 "register_operand" "=r")
6270         (plus (mult (match_operand 1 "index_register_operand" "l")
6271                     (match_operand 2 "const248_operand" "i"))
6272               (match_operand 3 "nonmemory_operand" "ri")))]
6273   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6274     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6275    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6276    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6277    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6278        || GET_MODE (operands[3]) == VOIDmode)"
6279   "#"
6280   "&& reload_completed"
6281   [(const_int 0)]
6282 {
6283   rtx pat;
6284   operands[0] = gen_lowpart (SImode, operands[0]);
6285   operands[1] = gen_lowpart (Pmode, operands[1]);
6286   operands[3] = gen_lowpart (Pmode, operands[3]);
6287   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6288                       operands[3]);
6289   if (Pmode != SImode)
6290     pat = gen_rtx_SUBREG (SImode, pat, 0);
6291   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6292   DONE;
6293 }
6294   [(set_attr "type" "lea")
6295    (set_attr "mode" "SI")])
6296
6297 (define_insn_and_split "*lea_general_2_zext"
6298   [(set (match_operand:DI 0 "register_operand" "=r")
6299         (zero_extend:DI
6300           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6301                             (match_operand:SI 2 "const248_operand" "n"))
6302                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6303   "TARGET_64BIT"
6304   "#"
6305   "&& reload_completed"
6306   [(set (match_dup 0)
6307         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6308                                                      (match_dup 2))
6309                                             (match_dup 3)) 0)))]
6310 {
6311   operands[1] = gen_lowpart (Pmode, operands[1]);
6312   operands[3] = gen_lowpart (Pmode, operands[3]);
6313 }
6314   [(set_attr "type" "lea")
6315    (set_attr "mode" "SI")])
6316
6317 (define_insn_and_split "*lea_general_3"
6318   [(set (match_operand 0 "register_operand" "=r")
6319         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6320                           (match_operand 2 "const248_operand" "i"))
6321                     (match_operand 3 "register_operand" "r"))
6322               (match_operand 4 "immediate_operand" "i")))]
6323   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6324     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6325    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6326    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6327    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6328   "#"
6329   "&& reload_completed"
6330   [(const_int 0)]
6331 {
6332   rtx pat;
6333   operands[0] = gen_lowpart (SImode, operands[0]);
6334   operands[1] = gen_lowpart (Pmode, operands[1]);
6335   operands[3] = gen_lowpart (Pmode, operands[3]);
6336   operands[4] = gen_lowpart (Pmode, operands[4]);
6337   pat = gen_rtx_PLUS (Pmode,
6338                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6339                                                          operands[2]),
6340                                     operands[3]),
6341                       operands[4]);
6342   if (Pmode != SImode)
6343     pat = gen_rtx_SUBREG (SImode, pat, 0);
6344   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6345   DONE;
6346 }
6347   [(set_attr "type" "lea")
6348    (set_attr "mode" "SI")])
6349
6350 (define_insn_and_split "*lea_general_3_zext"
6351   [(set (match_operand:DI 0 "register_operand" "=r")
6352         (zero_extend:DI
6353           (plus:SI (plus:SI (mult:SI
6354                               (match_operand:SI 1 "index_register_operand" "l")
6355                               (match_operand:SI 2 "const248_operand" "n"))
6356                             (match_operand:SI 3 "register_operand" "r"))
6357                    (match_operand:SI 4 "immediate_operand" "i"))))]
6358   "TARGET_64BIT"
6359   "#"
6360   "&& reload_completed"
6361   [(set (match_dup 0)
6362         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6363                                                               (match_dup 2))
6364                                                      (match_dup 3))
6365                                             (match_dup 4)) 0)))]
6366 {
6367   operands[1] = gen_lowpart (Pmode, operands[1]);
6368   operands[3] = gen_lowpart (Pmode, operands[3]);
6369   operands[4] = gen_lowpart (Pmode, operands[4]);
6370 }
6371   [(set_attr "type" "lea")
6372    (set_attr "mode" "SI")])
6373
6374 (define_insn "*adddi_1_rex64"
6375   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
6376         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
6377                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
6378    (clobber (reg:CC FLAGS_REG))]
6379   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6380 {
6381   switch (get_attr_type (insn))
6382     {
6383     case TYPE_LEA:
6384       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6385       return "lea{q}\t{%a2, %0|%0, %a2}";
6386
6387     case TYPE_INCDEC:
6388       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6389       if (operands[2] == const1_rtx)
6390         return "inc{q}\t%0";
6391       else
6392         {
6393           gcc_assert (operands[2] == constm1_rtx);
6394           return "dec{q}\t%0";
6395         }
6396
6397     default:
6398       /* Use add as much as possible to replace lea for AGU optimization. */
6399       if (which_alternative == 2 && TARGET_OPT_AGU)
6400         return "add{q}\t{%1, %0|%0, %1}";
6401         
6402       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6403
6404       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6405          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6406       if (CONST_INT_P (operands[2])
6407           /* Avoid overflows.  */
6408           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6409           && (INTVAL (operands[2]) == 128
6410               || (INTVAL (operands[2]) < 0
6411                   && INTVAL (operands[2]) != -128)))
6412         {
6413           operands[2] = GEN_INT (-INTVAL (operands[2]));
6414           return "sub{q}\t{%2, %0|%0, %2}";
6415         }
6416       return "add{q}\t{%2, %0|%0, %2}";
6417     }
6418 }
6419   [(set (attr "type")
6420      (cond [(and (eq_attr "alternative" "2") 
6421                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6422               (const_string "lea")
6423             (eq_attr "alternative" "3")
6424               (const_string "lea")
6425             ; Current assemblers are broken and do not allow @GOTOFF in
6426             ; ought but a memory context.
6427             (match_operand:DI 2 "pic_symbolic_operand" "")
6428               (const_string "lea")
6429             (match_operand:DI 2 "incdec_operand" "")
6430               (const_string "incdec")
6431            ]
6432            (const_string "alu")))
6433    (set_attr "mode" "DI")])
6434
6435 ;; Convert lea to the lea pattern to avoid flags dependency.
6436 (define_split
6437   [(set (match_operand:DI 0 "register_operand" "")
6438         (plus:DI (match_operand:DI 1 "register_operand" "")
6439                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6440    (clobber (reg:CC FLAGS_REG))]
6441   "TARGET_64BIT && reload_completed 
6442    && ix86_lea_for_add_ok (PLUS, insn, operands)"
6443   [(set (match_dup 0)
6444         (plus:DI (match_dup 1)
6445                  (match_dup 2)))]
6446   "")
6447
6448 (define_insn "*adddi_2_rex64"
6449   [(set (reg FLAGS_REG)
6450         (compare
6451           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6452                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6453           (const_int 0)))
6454    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6455         (plus:DI (match_dup 1) (match_dup 2)))]
6456   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6457    && ix86_binary_operator_ok (PLUS, DImode, operands)
6458    /* Current assemblers are broken and do not allow @GOTOFF in
6459       ought but a memory context.  */
6460    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6461 {
6462   switch (get_attr_type (insn))
6463     {
6464     case TYPE_INCDEC:
6465       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6466       if (operands[2] == const1_rtx)
6467         return "inc{q}\t%0";
6468       else
6469         {
6470           gcc_assert (operands[2] == constm1_rtx);
6471           return "dec{q}\t%0";
6472         }
6473
6474     default:
6475       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6476       /* ???? We ought to handle there the 32bit case too
6477          - do we need new constraint?  */
6478       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6479          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6480       if (CONST_INT_P (operands[2])
6481           /* Avoid overflows.  */
6482           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6483           && (INTVAL (operands[2]) == 128
6484               || (INTVAL (operands[2]) < 0
6485                   && INTVAL (operands[2]) != -128)))
6486         {
6487           operands[2] = GEN_INT (-INTVAL (operands[2]));
6488           return "sub{q}\t{%2, %0|%0, %2}";
6489         }
6490       return "add{q}\t{%2, %0|%0, %2}";
6491     }
6492 }
6493   [(set (attr "type")
6494      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6495         (const_string "incdec")
6496         (const_string "alu")))
6497    (set_attr "mode" "DI")])
6498
6499 (define_insn "*adddi_3_rex64"
6500   [(set (reg FLAGS_REG)
6501         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6502                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6503    (clobber (match_scratch:DI 0 "=r"))]
6504   "TARGET_64BIT
6505    && ix86_match_ccmode (insn, CCZmode)
6506    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6507    /* Current assemblers are broken and do not allow @GOTOFF in
6508       ought but a memory context.  */
6509    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6510 {
6511   switch (get_attr_type (insn))
6512     {
6513     case TYPE_INCDEC:
6514       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6515       if (operands[2] == const1_rtx)
6516         return "inc{q}\t%0";
6517       else
6518         {
6519           gcc_assert (operands[2] == constm1_rtx);
6520           return "dec{q}\t%0";
6521         }
6522
6523     default:
6524       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6525       /* ???? We ought to handle there the 32bit case too
6526          - do we need new constraint?  */
6527       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6528          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6529       if (CONST_INT_P (operands[2])
6530           /* Avoid overflows.  */
6531           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6532           && (INTVAL (operands[2]) == 128
6533               || (INTVAL (operands[2]) < 0
6534                   && INTVAL (operands[2]) != -128)))
6535         {
6536           operands[2] = GEN_INT (-INTVAL (operands[2]));
6537           return "sub{q}\t{%2, %0|%0, %2}";
6538         }
6539       return "add{q}\t{%2, %0|%0, %2}";
6540     }
6541 }
6542   [(set (attr "type")
6543      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6544         (const_string "incdec")
6545         (const_string "alu")))
6546    (set_attr "mode" "DI")])
6547
6548 ; For comparisons against 1, -1 and 128, we may generate better code
6549 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6550 ; is matched then.  We can't accept general immediate, because for
6551 ; case of overflows,  the result is messed up.
6552 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6553 ; when negated.
6554 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6555 ; only for comparisons not depending on it.
6556 (define_insn "*adddi_4_rex64"
6557   [(set (reg FLAGS_REG)
6558         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6559                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6560    (clobber (match_scratch:DI 0 "=rm"))]
6561   "TARGET_64BIT
6562    &&  ix86_match_ccmode (insn, CCGCmode)"
6563 {
6564   switch (get_attr_type (insn))
6565     {
6566     case TYPE_INCDEC:
6567       if (operands[2] == constm1_rtx)
6568         return "inc{q}\t%0";
6569       else
6570         {
6571           gcc_assert (operands[2] == const1_rtx);
6572           return "dec{q}\t%0";
6573         }
6574
6575     default:
6576       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6577       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6578          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6579       if ((INTVAL (operands[2]) == -128
6580            || (INTVAL (operands[2]) > 0
6581                && INTVAL (operands[2]) != 128))
6582           /* Avoid overflows.  */
6583           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6584         return "sub{q}\t{%2, %0|%0, %2}";
6585       operands[2] = GEN_INT (-INTVAL (operands[2]));
6586       return "add{q}\t{%2, %0|%0, %2}";
6587     }
6588 }
6589   [(set (attr "type")
6590      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6591         (const_string "incdec")
6592         (const_string "alu")))
6593    (set_attr "mode" "DI")])
6594
6595 (define_insn "*adddi_5_rex64"
6596   [(set (reg FLAGS_REG)
6597         (compare
6598           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6599                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6600           (const_int 0)))
6601    (clobber (match_scratch:DI 0 "=r"))]
6602   "TARGET_64BIT
6603    && ix86_match_ccmode (insn, CCGOCmode)
6604    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6605    /* Current assemblers are broken and do not allow @GOTOFF in
6606       ought but a memory context.  */
6607    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6608 {
6609   switch (get_attr_type (insn))
6610     {
6611     case TYPE_INCDEC:
6612       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6613       if (operands[2] == const1_rtx)
6614         return "inc{q}\t%0";
6615       else
6616         {
6617           gcc_assert (operands[2] == constm1_rtx);
6618           return "dec{q}\t%0";
6619         }
6620
6621     default:
6622       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6623       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6624          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6625       if (CONST_INT_P (operands[2])
6626           /* Avoid overflows.  */
6627           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6628           && (INTVAL (operands[2]) == 128
6629               || (INTVAL (operands[2]) < 0
6630                   && INTVAL (operands[2]) != -128)))
6631         {
6632           operands[2] = GEN_INT (-INTVAL (operands[2]));
6633           return "sub{q}\t{%2, %0|%0, %2}";
6634         }
6635       return "add{q}\t{%2, %0|%0, %2}";
6636     }
6637 }
6638   [(set (attr "type")
6639      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6640         (const_string "incdec")
6641         (const_string "alu")))
6642    (set_attr "mode" "DI")])
6643
6644
6645 (define_insn "*addsi_1"
6646   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
6647         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
6648                  (match_operand:SI 2 "general_operand" "g,ri,0,li")))
6649    (clobber (reg:CC FLAGS_REG))]
6650   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6651 {
6652   switch (get_attr_type (insn))
6653     {
6654     case TYPE_LEA:
6655       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6656       return "lea{l}\t{%a2, %0|%0, %a2}";
6657
6658     case TYPE_INCDEC:
6659       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6660       if (operands[2] == const1_rtx)
6661         return "inc{l}\t%0";
6662       else
6663         {
6664           gcc_assert (operands[2] == constm1_rtx);
6665           return "dec{l}\t%0";
6666         }
6667
6668     default:
6669       /* Use add as much as possible to replace lea for AGU optimization. */
6670       if (which_alternative == 2 && TARGET_OPT_AGU)
6671         return "add{l}\t{%1, %0|%0, %1}";
6672
6673       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6674
6675       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6676          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6677       if (CONST_INT_P (operands[2])
6678           && (INTVAL (operands[2]) == 128
6679               || (INTVAL (operands[2]) < 0
6680                   && INTVAL (operands[2]) != -128)))
6681         {
6682           operands[2] = GEN_INT (-INTVAL (operands[2]));
6683           return "sub{l}\t{%2, %0|%0, %2}";
6684         }
6685       return "add{l}\t{%2, %0|%0, %2}";
6686     }
6687 }
6688   [(set (attr "type")
6689      (cond [(and (eq_attr "alternative" "2") 
6690                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6691                (const_string "lea")
6692             (eq_attr "alternative" "3")
6693               (const_string "lea")
6694             ; Current assemblers are broken and do not allow @GOTOFF in
6695             ; ought but a memory context.
6696             (match_operand:SI 2 "pic_symbolic_operand" "")
6697               (const_string "lea")
6698             (match_operand:SI 2 "incdec_operand" "")
6699               (const_string "incdec")
6700            ]
6701            (const_string "alu")))
6702    (set_attr "mode" "SI")])
6703
6704 ;; Convert lea to the lea pattern to avoid flags dependency.
6705 (define_split
6706   [(set (match_operand 0 "register_operand" "")
6707         (plus (match_operand 1 "register_operand" "")
6708               (match_operand 2 "nonmemory_operand" "")))
6709    (clobber (reg:CC FLAGS_REG))]
6710   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
6711   [(const_int 0)]
6712 {
6713   rtx pat;
6714   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6715      may confuse gen_lowpart.  */
6716   if (GET_MODE (operands[0]) != Pmode)
6717     {
6718       operands[1] = gen_lowpart (Pmode, operands[1]);
6719       operands[2] = gen_lowpart (Pmode, operands[2]);
6720     }
6721   operands[0] = gen_lowpart (SImode, operands[0]);
6722   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6723   if (Pmode != SImode)
6724     pat = gen_rtx_SUBREG (SImode, pat, 0);
6725   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6726   DONE;
6727 })
6728
6729 ;; It may seem that nonimmediate operand is proper one for operand 1.
6730 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6731 ;; we take care in ix86_binary_operator_ok to not allow two memory
6732 ;; operands so proper swapping will be done in reload.  This allow
6733 ;; patterns constructed from addsi_1 to match.
6734 (define_insn "addsi_1_zext"
6735   [(set (match_operand:DI 0 "register_operand" "=r,r")
6736         (zero_extend:DI
6737           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6738                    (match_operand:SI 2 "general_operand" "g,li"))))
6739    (clobber (reg:CC FLAGS_REG))]
6740   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6741 {
6742   switch (get_attr_type (insn))
6743     {
6744     case TYPE_LEA:
6745       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6746       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6747
6748     case TYPE_INCDEC:
6749       if (operands[2] == const1_rtx)
6750         return "inc{l}\t%k0";
6751       else
6752         {
6753           gcc_assert (operands[2] == constm1_rtx);
6754           return "dec{l}\t%k0";
6755         }
6756
6757     default:
6758       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6759          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6760       if (CONST_INT_P (operands[2])
6761           && (INTVAL (operands[2]) == 128
6762               || (INTVAL (operands[2]) < 0
6763                   && INTVAL (operands[2]) != -128)))
6764         {
6765           operands[2] = GEN_INT (-INTVAL (operands[2]));
6766           return "sub{l}\t{%2, %k0|%k0, %2}";
6767         }
6768       return "add{l}\t{%2, %k0|%k0, %2}";
6769     }
6770 }
6771   [(set (attr "type")
6772      (cond [(eq_attr "alternative" "1")
6773               (const_string "lea")
6774             ; Current assemblers are broken and do not allow @GOTOFF in
6775             ; ought but a memory context.
6776             (match_operand:SI 2 "pic_symbolic_operand" "")
6777               (const_string "lea")
6778             (match_operand:SI 2 "incdec_operand" "")
6779               (const_string "incdec")
6780            ]
6781            (const_string "alu")))
6782    (set_attr "mode" "SI")])
6783
6784 ;; Convert lea to the lea pattern to avoid flags dependency.
6785 (define_split
6786   [(set (match_operand:DI 0 "register_operand" "")
6787         (zero_extend:DI
6788           (plus:SI (match_operand:SI 1 "register_operand" "")
6789                    (match_operand:SI 2 "nonmemory_operand" ""))))
6790    (clobber (reg:CC FLAGS_REG))]
6791   "TARGET_64BIT && reload_completed
6792    && true_regnum (operands[0]) != true_regnum (operands[1])"
6793   [(set (match_dup 0)
6794         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6795 {
6796   operands[1] = gen_lowpart (Pmode, operands[1]);
6797   operands[2] = gen_lowpart (Pmode, operands[2]);
6798 })
6799
6800 (define_insn "*addsi_2"
6801   [(set (reg FLAGS_REG)
6802         (compare
6803           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6804                    (match_operand:SI 2 "general_operand" "g,ri"))
6805           (const_int 0)))
6806    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6807         (plus:SI (match_dup 1) (match_dup 2)))]
6808   "ix86_match_ccmode (insn, CCGOCmode)
6809    && ix86_binary_operator_ok (PLUS, SImode, operands)
6810    /* Current assemblers are broken and do not allow @GOTOFF in
6811       ought but a memory context.  */
6812    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6813 {
6814   switch (get_attr_type (insn))
6815     {
6816     case TYPE_INCDEC:
6817       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6818       if (operands[2] == const1_rtx)
6819         return "inc{l}\t%0";
6820       else
6821         {
6822           gcc_assert (operands[2] == constm1_rtx);
6823           return "dec{l}\t%0";
6824         }
6825
6826     default:
6827       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6828       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6829          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6830       if (CONST_INT_P (operands[2])
6831           && (INTVAL (operands[2]) == 128
6832               || (INTVAL (operands[2]) < 0
6833                   && INTVAL (operands[2]) != -128)))
6834         {
6835           operands[2] = GEN_INT (-INTVAL (operands[2]));
6836           return "sub{l}\t{%2, %0|%0, %2}";
6837         }
6838       return "add{l}\t{%2, %0|%0, %2}";
6839     }
6840 }
6841   [(set (attr "type")
6842      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6843         (const_string "incdec")
6844         (const_string "alu")))
6845    (set_attr "mode" "SI")])
6846
6847 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6848 (define_insn "*addsi_2_zext"
6849   [(set (reg FLAGS_REG)
6850         (compare
6851           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6852                    (match_operand:SI 2 "general_operand" "g"))
6853           (const_int 0)))
6854    (set (match_operand:DI 0 "register_operand" "=r")
6855         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6856   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6857    && ix86_binary_operator_ok (PLUS, SImode, operands)
6858    /* Current assemblers are broken and do not allow @GOTOFF in
6859       ought but a memory context.  */
6860    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6861 {
6862   switch (get_attr_type (insn))
6863     {
6864     case TYPE_INCDEC:
6865       if (operands[2] == const1_rtx)
6866         return "inc{l}\t%k0";
6867       else
6868         {
6869           gcc_assert (operands[2] == constm1_rtx);
6870           return "dec{l}\t%k0";
6871         }
6872
6873     default:
6874       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6875          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6876       if (CONST_INT_P (operands[2])
6877           && (INTVAL (operands[2]) == 128
6878               || (INTVAL (operands[2]) < 0
6879                   && INTVAL (operands[2]) != -128)))
6880         {
6881           operands[2] = GEN_INT (-INTVAL (operands[2]));
6882           return "sub{l}\t{%2, %k0|%k0, %2}";
6883         }
6884       return "add{l}\t{%2, %k0|%k0, %2}";
6885     }
6886 }
6887   [(set (attr "type")
6888      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6889         (const_string "incdec")
6890         (const_string "alu")))
6891    (set_attr "mode" "SI")])
6892
6893 (define_insn "*addsi_3"
6894   [(set (reg FLAGS_REG)
6895         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6896                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6897    (clobber (match_scratch:SI 0 "=r"))]
6898   "ix86_match_ccmode (insn, CCZmode)
6899    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6900    /* Current assemblers are broken and do not allow @GOTOFF in
6901       ought but a memory context.  */
6902    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6903 {
6904   switch (get_attr_type (insn))
6905     {
6906     case TYPE_INCDEC:
6907       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6908       if (operands[2] == const1_rtx)
6909         return "inc{l}\t%0";
6910       else
6911         {
6912           gcc_assert (operands[2] == constm1_rtx);
6913           return "dec{l}\t%0";
6914         }
6915
6916     default:
6917       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6918       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6919          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6920       if (CONST_INT_P (operands[2])
6921           && (INTVAL (operands[2]) == 128
6922               || (INTVAL (operands[2]) < 0
6923                   && INTVAL (operands[2]) != -128)))
6924         {
6925           operands[2] = GEN_INT (-INTVAL (operands[2]));
6926           return "sub{l}\t{%2, %0|%0, %2}";
6927         }
6928       return "add{l}\t{%2, %0|%0, %2}";
6929     }
6930 }
6931   [(set (attr "type")
6932      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6933         (const_string "incdec")
6934         (const_string "alu")))
6935    (set_attr "mode" "SI")])
6936
6937 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6938 (define_insn "*addsi_3_zext"
6939   [(set (reg FLAGS_REG)
6940         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6941                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6942    (set (match_operand:DI 0 "register_operand" "=r")
6943         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6944   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6945    && ix86_binary_operator_ok (PLUS, SImode, operands)
6946    /* Current assemblers are broken and do not allow @GOTOFF in
6947       ought but a memory context.  */
6948    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6949 {
6950   switch (get_attr_type (insn))
6951     {
6952     case TYPE_INCDEC:
6953       if (operands[2] == const1_rtx)
6954         return "inc{l}\t%k0";
6955       else
6956         {
6957           gcc_assert (operands[2] == constm1_rtx);
6958           return "dec{l}\t%k0";
6959         }
6960
6961     default:
6962       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6963          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6964       if (CONST_INT_P (operands[2])
6965           && (INTVAL (operands[2]) == 128
6966               || (INTVAL (operands[2]) < 0
6967                   && INTVAL (operands[2]) != -128)))
6968         {
6969           operands[2] = GEN_INT (-INTVAL (operands[2]));
6970           return "sub{l}\t{%2, %k0|%k0, %2}";
6971         }
6972       return "add{l}\t{%2, %k0|%k0, %2}";
6973     }
6974 }
6975   [(set (attr "type")
6976      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6977         (const_string "incdec")
6978         (const_string "alu")))
6979    (set_attr "mode" "SI")])
6980
6981 ; For comparisons against 1, -1 and 128, we may generate better code
6982 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6983 ; is matched then.  We can't accept general immediate, because for
6984 ; case of overflows,  the result is messed up.
6985 ; This pattern also don't hold of 0x80000000, since the value overflows
6986 ; when negated.
6987 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6988 ; only for comparisons not depending on it.
6989 (define_insn "*addsi_4"
6990   [(set (reg FLAGS_REG)
6991         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6992                  (match_operand:SI 2 "const_int_operand" "n")))
6993    (clobber (match_scratch:SI 0 "=rm"))]
6994   "ix86_match_ccmode (insn, CCGCmode)
6995    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6996 {
6997   switch (get_attr_type (insn))
6998     {
6999     case TYPE_INCDEC:
7000       if (operands[2] == constm1_rtx)
7001         return "inc{l}\t%0";
7002       else
7003         {
7004           gcc_assert (operands[2] == const1_rtx);
7005           return "dec{l}\t%0";
7006         }
7007
7008     default:
7009       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7010       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7011          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7012       if ((INTVAL (operands[2]) == -128
7013            || (INTVAL (operands[2]) > 0
7014                && INTVAL (operands[2]) != 128)))
7015         return "sub{l}\t{%2, %0|%0, %2}";
7016       operands[2] = GEN_INT (-INTVAL (operands[2]));
7017       return "add{l}\t{%2, %0|%0, %2}";
7018     }
7019 }
7020   [(set (attr "type")
7021      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7022         (const_string "incdec")
7023         (const_string "alu")))
7024    (set_attr "mode" "SI")])
7025
7026 (define_insn "*addsi_5"
7027   [(set (reg FLAGS_REG)
7028         (compare
7029           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7030                    (match_operand:SI 2 "general_operand" "g"))
7031           (const_int 0)))
7032    (clobber (match_scratch:SI 0 "=r"))]
7033   "ix86_match_ccmode (insn, CCGOCmode)
7034    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7035    /* Current assemblers are broken and do not allow @GOTOFF in
7036       ought but a memory context.  */
7037    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7038 {
7039   switch (get_attr_type (insn))
7040     {
7041     case TYPE_INCDEC:
7042       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7043       if (operands[2] == const1_rtx)
7044         return "inc{l}\t%0";
7045       else
7046         {
7047           gcc_assert (operands[2] == constm1_rtx);
7048           return "dec{l}\t%0";
7049         }
7050
7051     default:
7052       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7053       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7054          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7055       if (CONST_INT_P (operands[2])
7056           && (INTVAL (operands[2]) == 128
7057               || (INTVAL (operands[2]) < 0
7058                   && INTVAL (operands[2]) != -128)))
7059         {
7060           operands[2] = GEN_INT (-INTVAL (operands[2]));
7061           return "sub{l}\t{%2, %0|%0, %2}";
7062         }
7063       return "add{l}\t{%2, %0|%0, %2}";
7064     }
7065 }
7066   [(set (attr "type")
7067      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7068         (const_string "incdec")
7069         (const_string "alu")))
7070    (set_attr "mode" "SI")])
7071
7072 (define_expand "addhi3"
7073   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7074         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7075                  (match_operand:HI 2 "general_operand" "")))]
7076   "TARGET_HIMODE_MATH"
7077   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
7078
7079 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
7080 ;; type optimizations enabled by define-splits.  This is not important
7081 ;; for PII, and in fact harmful because of partial register stalls.
7082
7083 (define_insn "*addhi_1_lea"
7084   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7085         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
7086                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
7087    (clobber (reg:CC FLAGS_REG))]
7088   "!TARGET_PARTIAL_REG_STALL
7089    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7090 {
7091   switch (get_attr_type (insn))
7092     {
7093     case TYPE_LEA:
7094       return "#";
7095     case TYPE_INCDEC:
7096       if (operands[2] == const1_rtx)
7097         return "inc{w}\t%0";
7098       else
7099         {
7100           gcc_assert (operands[2] == constm1_rtx);
7101           return "dec{w}\t%0";
7102         }
7103
7104     default:
7105       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7106          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7107       if (CONST_INT_P (operands[2])
7108           && (INTVAL (operands[2]) == 128
7109               || (INTVAL (operands[2]) < 0
7110                   && INTVAL (operands[2]) != -128)))
7111         {
7112           operands[2] = GEN_INT (-INTVAL (operands[2]));
7113           return "sub{w}\t{%2, %0|%0, %2}";
7114         }
7115       return "add{w}\t{%2, %0|%0, %2}";
7116     }
7117 }
7118   [(set (attr "type")
7119      (if_then_else (eq_attr "alternative" "2")
7120         (const_string "lea")
7121         (if_then_else (match_operand:HI 2 "incdec_operand" "")
7122            (const_string "incdec")
7123            (const_string "alu"))))
7124    (set_attr "mode" "HI,HI,SI")])
7125
7126 (define_insn "*addhi_1"
7127   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7128         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7129                  (match_operand:HI 2 "general_operand" "rn,rm")))
7130    (clobber (reg:CC FLAGS_REG))]
7131   "TARGET_PARTIAL_REG_STALL
7132    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7133 {
7134   switch (get_attr_type (insn))
7135     {
7136     case TYPE_INCDEC:
7137       if (operands[2] == const1_rtx)
7138         return "inc{w}\t%0";
7139       else
7140         {
7141           gcc_assert (operands[2] == constm1_rtx);
7142           return "dec{w}\t%0";
7143         }
7144
7145     default:
7146       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7147          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7148       if (CONST_INT_P (operands[2])
7149           && (INTVAL (operands[2]) == 128
7150               || (INTVAL (operands[2]) < 0
7151                   && INTVAL (operands[2]) != -128)))
7152         {
7153           operands[2] = GEN_INT (-INTVAL (operands[2]));
7154           return "sub{w}\t{%2, %0|%0, %2}";
7155         }
7156       return "add{w}\t{%2, %0|%0, %2}";
7157     }
7158 }
7159   [(set (attr "type")
7160      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7161         (const_string "incdec")
7162         (const_string "alu")))
7163    (set_attr "mode" "HI")])
7164
7165 (define_insn "*addhi_2"
7166   [(set (reg FLAGS_REG)
7167         (compare
7168           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7169                    (match_operand:HI 2 "general_operand" "rmn,rn"))
7170           (const_int 0)))
7171    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7172         (plus:HI (match_dup 1) (match_dup 2)))]
7173   "ix86_match_ccmode (insn, CCGOCmode)
7174    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7175 {
7176   switch (get_attr_type (insn))
7177     {
7178     case TYPE_INCDEC:
7179       if (operands[2] == const1_rtx)
7180         return "inc{w}\t%0";
7181       else
7182         {
7183           gcc_assert (operands[2] == constm1_rtx);
7184           return "dec{w}\t%0";
7185         }
7186
7187     default:
7188       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7189          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7190       if (CONST_INT_P (operands[2])
7191           && (INTVAL (operands[2]) == 128
7192               || (INTVAL (operands[2]) < 0
7193                   && INTVAL (operands[2]) != -128)))
7194         {
7195           operands[2] = GEN_INT (-INTVAL (operands[2]));
7196           return "sub{w}\t{%2, %0|%0, %2}";
7197         }
7198       return "add{w}\t{%2, %0|%0, %2}";
7199     }
7200 }
7201   [(set (attr "type")
7202      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7203         (const_string "incdec")
7204         (const_string "alu")))
7205    (set_attr "mode" "HI")])
7206
7207 (define_insn "*addhi_3"
7208   [(set (reg FLAGS_REG)
7209         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
7210                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
7211    (clobber (match_scratch:HI 0 "=r"))]
7212   "ix86_match_ccmode (insn, CCZmode)
7213    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7214 {
7215   switch (get_attr_type (insn))
7216     {
7217     case TYPE_INCDEC:
7218       if (operands[2] == const1_rtx)
7219         return "inc{w}\t%0";
7220       else
7221         {
7222           gcc_assert (operands[2] == constm1_rtx);
7223           return "dec{w}\t%0";
7224         }
7225
7226     default:
7227       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7228          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7229       if (CONST_INT_P (operands[2])
7230           && (INTVAL (operands[2]) == 128
7231               || (INTVAL (operands[2]) < 0
7232                   && INTVAL (operands[2]) != -128)))
7233         {
7234           operands[2] = GEN_INT (-INTVAL (operands[2]));
7235           return "sub{w}\t{%2, %0|%0, %2}";
7236         }
7237       return "add{w}\t{%2, %0|%0, %2}";
7238     }
7239 }
7240   [(set (attr "type")
7241      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7242         (const_string "incdec")
7243         (const_string "alu")))
7244    (set_attr "mode" "HI")])
7245
7246 ; See comments above addsi_4 for details.
7247 (define_insn "*addhi_4"
7248   [(set (reg FLAGS_REG)
7249         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7250                  (match_operand:HI 2 "const_int_operand" "n")))
7251    (clobber (match_scratch:HI 0 "=rm"))]
7252   "ix86_match_ccmode (insn, CCGCmode)
7253    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7254 {
7255   switch (get_attr_type (insn))
7256     {
7257     case TYPE_INCDEC:
7258       if (operands[2] == constm1_rtx)
7259         return "inc{w}\t%0";
7260       else
7261         {
7262           gcc_assert (operands[2] == const1_rtx);
7263           return "dec{w}\t%0";
7264         }
7265
7266     default:
7267       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7268       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7269          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7270       if ((INTVAL (operands[2]) == -128
7271            || (INTVAL (operands[2]) > 0
7272                && INTVAL (operands[2]) != 128)))
7273         return "sub{w}\t{%2, %0|%0, %2}";
7274       operands[2] = GEN_INT (-INTVAL (operands[2]));
7275       return "add{w}\t{%2, %0|%0, %2}";
7276     }
7277 }
7278   [(set (attr "type")
7279      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7280         (const_string "incdec")
7281         (const_string "alu")))
7282    (set_attr "mode" "SI")])
7283
7284
7285 (define_insn "*addhi_5"
7286   [(set (reg FLAGS_REG)
7287         (compare
7288           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7289                    (match_operand:HI 2 "general_operand" "rmn"))
7290           (const_int 0)))
7291    (clobber (match_scratch:HI 0 "=r"))]
7292   "ix86_match_ccmode (insn, CCGOCmode)
7293    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7294 {
7295   switch (get_attr_type (insn))
7296     {
7297     case TYPE_INCDEC:
7298       if (operands[2] == const1_rtx)
7299         return "inc{w}\t%0";
7300       else
7301         {
7302           gcc_assert (operands[2] == constm1_rtx);
7303           return "dec{w}\t%0";
7304         }
7305
7306     default:
7307       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7308          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7309       if (CONST_INT_P (operands[2])
7310           && (INTVAL (operands[2]) == 128
7311               || (INTVAL (operands[2]) < 0
7312                   && INTVAL (operands[2]) != -128)))
7313         {
7314           operands[2] = GEN_INT (-INTVAL (operands[2]));
7315           return "sub{w}\t{%2, %0|%0, %2}";
7316         }
7317       return "add{w}\t{%2, %0|%0, %2}";
7318     }
7319 }
7320   [(set (attr "type")
7321      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7322         (const_string "incdec")
7323         (const_string "alu")))
7324    (set_attr "mode" "HI")])
7325
7326 (define_expand "addqi3"
7327   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7328         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7329                  (match_operand:QI 2 "general_operand" "")))]
7330   "TARGET_QIMODE_MATH"
7331   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7332
7333 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7334 (define_insn "*addqi_1_lea"
7335   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7336         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7337                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7338    (clobber (reg:CC FLAGS_REG))]
7339   "!TARGET_PARTIAL_REG_STALL
7340    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7341 {
7342   int widen = (which_alternative == 2);
7343   switch (get_attr_type (insn))
7344     {
7345     case TYPE_LEA:
7346       return "#";
7347     case TYPE_INCDEC:
7348       if (operands[2] == const1_rtx)
7349         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7350       else
7351         {
7352           gcc_assert (operands[2] == constm1_rtx);
7353           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7354         }
7355
7356     default:
7357       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7358          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7359       if (CONST_INT_P (operands[2])
7360           && (INTVAL (operands[2]) == 128
7361               || (INTVAL (operands[2]) < 0
7362                   && INTVAL (operands[2]) != -128)))
7363         {
7364           operands[2] = GEN_INT (-INTVAL (operands[2]));
7365           if (widen)
7366             return "sub{l}\t{%2, %k0|%k0, %2}";
7367           else
7368             return "sub{b}\t{%2, %0|%0, %2}";
7369         }
7370       if (widen)
7371         return "add{l}\t{%k2, %k0|%k0, %k2}";
7372       else
7373         return "add{b}\t{%2, %0|%0, %2}";
7374     }
7375 }
7376   [(set (attr "type")
7377      (if_then_else (eq_attr "alternative" "3")
7378         (const_string "lea")
7379         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7380            (const_string "incdec")
7381            (const_string "alu"))))
7382    (set_attr "mode" "QI,QI,SI,SI")])
7383
7384 (define_insn "*addqi_1"
7385   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7386         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7387                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "TARGET_PARTIAL_REG_STALL
7390    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7391 {
7392   int widen = (which_alternative == 2);
7393   switch (get_attr_type (insn))
7394     {
7395     case TYPE_INCDEC:
7396       if (operands[2] == const1_rtx)
7397         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7398       else
7399         {
7400           gcc_assert (operands[2] == constm1_rtx);
7401           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7402         }
7403
7404     default:
7405       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7406          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7407       if (CONST_INT_P (operands[2])
7408           && (INTVAL (operands[2]) == 128
7409               || (INTVAL (operands[2]) < 0
7410                   && INTVAL (operands[2]) != -128)))
7411         {
7412           operands[2] = GEN_INT (-INTVAL (operands[2]));
7413           if (widen)
7414             return "sub{l}\t{%2, %k0|%k0, %2}";
7415           else
7416             return "sub{b}\t{%2, %0|%0, %2}";
7417         }
7418       if (widen)
7419         return "add{l}\t{%k2, %k0|%k0, %k2}";
7420       else
7421         return "add{b}\t{%2, %0|%0, %2}";
7422     }
7423 }
7424   [(set (attr "type")
7425      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7426         (const_string "incdec")
7427         (const_string "alu")))
7428    (set_attr "mode" "QI,QI,SI")])
7429
7430 (define_insn "*addqi_1_slp"
7431   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7432         (plus:QI (match_dup 0)
7433                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7434    (clobber (reg:CC FLAGS_REG))]
7435   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7436    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7437 {
7438   switch (get_attr_type (insn))
7439     {
7440     case TYPE_INCDEC:
7441       if (operands[1] == const1_rtx)
7442         return "inc{b}\t%0";
7443       else
7444         {
7445           gcc_assert (operands[1] == constm1_rtx);
7446           return "dec{b}\t%0";
7447         }
7448
7449     default:
7450       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7451       if (CONST_INT_P (operands[1])
7452           && INTVAL (operands[1]) < 0)
7453         {
7454           operands[1] = GEN_INT (-INTVAL (operands[1]));
7455           return "sub{b}\t{%1, %0|%0, %1}";
7456         }
7457       return "add{b}\t{%1, %0|%0, %1}";
7458     }
7459 }
7460   [(set (attr "type")
7461      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7462         (const_string "incdec")
7463         (const_string "alu1")))
7464    (set (attr "memory")
7465      (if_then_else (match_operand 1 "memory_operand" "")
7466         (const_string "load")
7467         (const_string "none")))
7468    (set_attr "mode" "QI")])
7469
7470 (define_insn "*addqi_2"
7471   [(set (reg FLAGS_REG)
7472         (compare
7473           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7474                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7475           (const_int 0)))
7476    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7477         (plus:QI (match_dup 1) (match_dup 2)))]
7478   "ix86_match_ccmode (insn, CCGOCmode)
7479    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7480 {
7481   switch (get_attr_type (insn))
7482     {
7483     case TYPE_INCDEC:
7484       if (operands[2] == const1_rtx)
7485         return "inc{b}\t%0";
7486       else
7487         {
7488           gcc_assert (operands[2] == constm1_rtx
7489                       || (CONST_INT_P (operands[2])
7490                           && INTVAL (operands[2]) == 255));
7491           return "dec{b}\t%0";
7492         }
7493
7494     default:
7495       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7496       if (CONST_INT_P (operands[2])
7497           && INTVAL (operands[2]) < 0)
7498         {
7499           operands[2] = GEN_INT (-INTVAL (operands[2]));
7500           return "sub{b}\t{%2, %0|%0, %2}";
7501         }
7502       return "add{b}\t{%2, %0|%0, %2}";
7503     }
7504 }
7505   [(set (attr "type")
7506      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7507         (const_string "incdec")
7508         (const_string "alu")))
7509    (set_attr "mode" "QI")])
7510
7511 (define_insn "*addqi_3"
7512   [(set (reg FLAGS_REG)
7513         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7514                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7515    (clobber (match_scratch:QI 0 "=q"))]
7516   "ix86_match_ccmode (insn, CCZmode)
7517    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7518 {
7519   switch (get_attr_type (insn))
7520     {
7521     case TYPE_INCDEC:
7522       if (operands[2] == const1_rtx)
7523         return "inc{b}\t%0";
7524       else
7525         {
7526           gcc_assert (operands[2] == constm1_rtx
7527                       || (CONST_INT_P (operands[2])
7528                           && INTVAL (operands[2]) == 255));
7529           return "dec{b}\t%0";
7530         }
7531
7532     default:
7533       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7534       if (CONST_INT_P (operands[2])
7535           && INTVAL (operands[2]) < 0)
7536         {
7537           operands[2] = GEN_INT (-INTVAL (operands[2]));
7538           return "sub{b}\t{%2, %0|%0, %2}";
7539         }
7540       return "add{b}\t{%2, %0|%0, %2}";
7541     }
7542 }
7543   [(set (attr "type")
7544      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7545         (const_string "incdec")
7546         (const_string "alu")))
7547    (set_attr "mode" "QI")])
7548
7549 ; See comments above addsi_4 for details.
7550 (define_insn "*addqi_4"
7551   [(set (reg FLAGS_REG)
7552         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7553                  (match_operand:QI 2 "const_int_operand" "n")))
7554    (clobber (match_scratch:QI 0 "=qm"))]
7555   "ix86_match_ccmode (insn, CCGCmode)
7556    && (INTVAL (operands[2]) & 0xff) != 0x80"
7557 {
7558   switch (get_attr_type (insn))
7559     {
7560     case TYPE_INCDEC:
7561       if (operands[2] == constm1_rtx
7562           || (CONST_INT_P (operands[2])
7563               && INTVAL (operands[2]) == 255))
7564         return "inc{b}\t%0";
7565       else
7566         {
7567           gcc_assert (operands[2] == const1_rtx);
7568           return "dec{b}\t%0";
7569         }
7570
7571     default:
7572       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7573       if (INTVAL (operands[2]) < 0)
7574         {
7575           operands[2] = GEN_INT (-INTVAL (operands[2]));
7576           return "add{b}\t{%2, %0|%0, %2}";
7577         }
7578       return "sub{b}\t{%2, %0|%0, %2}";
7579     }
7580 }
7581   [(set (attr "type")
7582      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7583         (const_string "incdec")
7584         (const_string "alu")))
7585    (set_attr "mode" "QI")])
7586
7587
7588 (define_insn "*addqi_5"
7589   [(set (reg FLAGS_REG)
7590         (compare
7591           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7592                    (match_operand:QI 2 "general_operand" "qmn"))
7593           (const_int 0)))
7594    (clobber (match_scratch:QI 0 "=q"))]
7595   "ix86_match_ccmode (insn, CCGOCmode)
7596    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7597 {
7598   switch (get_attr_type (insn))
7599     {
7600     case TYPE_INCDEC:
7601       if (operands[2] == const1_rtx)
7602         return "inc{b}\t%0";
7603       else
7604         {
7605           gcc_assert (operands[2] == constm1_rtx
7606                       || (CONST_INT_P (operands[2])
7607                           && INTVAL (operands[2]) == 255));
7608           return "dec{b}\t%0";
7609         }
7610
7611     default:
7612       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7613       if (CONST_INT_P (operands[2])
7614           && INTVAL (operands[2]) < 0)
7615         {
7616           operands[2] = GEN_INT (-INTVAL (operands[2]));
7617           return "sub{b}\t{%2, %0|%0, %2}";
7618         }
7619       return "add{b}\t{%2, %0|%0, %2}";
7620     }
7621 }
7622   [(set (attr "type")
7623      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7624         (const_string "incdec")
7625         (const_string "alu")))
7626    (set_attr "mode" "QI")])
7627
7628
7629 (define_insn "addqi_ext_1"
7630   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7631                          (const_int 8)
7632                          (const_int 8))
7633         (plus:SI
7634           (zero_extract:SI
7635             (match_operand 1 "ext_register_operand" "0")
7636             (const_int 8)
7637             (const_int 8))
7638           (match_operand:QI 2 "general_operand" "Qmn")))
7639    (clobber (reg:CC FLAGS_REG))]
7640   "!TARGET_64BIT"
7641 {
7642   switch (get_attr_type (insn))
7643     {
7644     case TYPE_INCDEC:
7645       if (operands[2] == const1_rtx)
7646         return "inc{b}\t%h0";
7647       else
7648         {
7649           gcc_assert (operands[2] == constm1_rtx
7650                       || (CONST_INT_P (operands[2])
7651                           && INTVAL (operands[2]) == 255));
7652           return "dec{b}\t%h0";
7653         }
7654
7655     default:
7656       return "add{b}\t{%2, %h0|%h0, %2}";
7657     }
7658 }
7659   [(set (attr "type")
7660      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7661         (const_string "incdec")
7662         (const_string "alu")))
7663    (set_attr "mode" "QI")])
7664
7665 (define_insn "*addqi_ext_1_rex64"
7666   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7667                          (const_int 8)
7668                          (const_int 8))
7669         (plus:SI
7670           (zero_extract:SI
7671             (match_operand 1 "ext_register_operand" "0")
7672             (const_int 8)
7673             (const_int 8))
7674           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7675    (clobber (reg:CC FLAGS_REG))]
7676   "TARGET_64BIT"
7677 {
7678   switch (get_attr_type (insn))
7679     {
7680     case TYPE_INCDEC:
7681       if (operands[2] == const1_rtx)
7682         return "inc{b}\t%h0";
7683       else
7684         {
7685           gcc_assert (operands[2] == constm1_rtx
7686                       || (CONST_INT_P (operands[2])
7687                           && INTVAL (operands[2]) == 255));
7688           return "dec{b}\t%h0";
7689         }
7690
7691     default:
7692       return "add{b}\t{%2, %h0|%h0, %2}";
7693     }
7694 }
7695   [(set (attr "type")
7696      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7697         (const_string "incdec")
7698         (const_string "alu")))
7699    (set_attr "mode" "QI")])
7700
7701 (define_insn "*addqi_ext_2"
7702   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7703                          (const_int 8)
7704                          (const_int 8))
7705         (plus:SI
7706           (zero_extract:SI
7707             (match_operand 1 "ext_register_operand" "%0")
7708             (const_int 8)
7709             (const_int 8))
7710           (zero_extract:SI
7711             (match_operand 2 "ext_register_operand" "Q")
7712             (const_int 8)
7713             (const_int 8))))
7714    (clobber (reg:CC FLAGS_REG))]
7715   ""
7716   "add{b}\t{%h2, %h0|%h0, %h2}"
7717   [(set_attr "type" "alu")
7718    (set_attr "mode" "QI")])
7719
7720 ;; The patterns that match these are at the end of this file.
7721
7722 (define_expand "addxf3"
7723   [(set (match_operand:XF 0 "register_operand" "")
7724         (plus:XF (match_operand:XF 1 "register_operand" "")
7725                  (match_operand:XF 2 "register_operand" "")))]
7726   "TARGET_80387"
7727   "")
7728
7729 (define_expand "add<mode>3"
7730   [(set (match_operand:MODEF 0 "register_operand" "")
7731         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7732                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7733   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7734     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7735   "")
7736 \f
7737 ;; Subtract instructions
7738
7739 ;; %%% splits for subditi3
7740
7741 (define_expand "subti3"
7742   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7743         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7744                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7745   "TARGET_64BIT"
7746   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7747
7748 (define_insn "*subti3_1"
7749   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7750         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7751                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7752    (clobber (reg:CC FLAGS_REG))]
7753   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7754   "#")
7755
7756 (define_split
7757   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7758         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7759                   (match_operand:TI 2 "x86_64_general_operand" "")))
7760    (clobber (reg:CC FLAGS_REG))]
7761   "TARGET_64BIT && reload_completed"
7762   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7763               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7764    (parallel [(set (match_dup 3)
7765                    (minus:DI (match_dup 4)
7766                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7767                                       (match_dup 5))))
7768               (clobber (reg:CC FLAGS_REG))])]
7769   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7770
7771 ;; %%% splits for subsidi3
7772
7773 (define_expand "subdi3"
7774   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7775         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7776                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7777   ""
7778   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7779
7780 (define_insn "*subdi3_1"
7781   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7782         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7783                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7784    (clobber (reg:CC FLAGS_REG))]
7785   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7786   "#")
7787
7788 (define_split
7789   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7790         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7791                   (match_operand:DI 2 "general_operand" "")))
7792    (clobber (reg:CC FLAGS_REG))]
7793   "!TARGET_64BIT && reload_completed"
7794   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7795               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7796    (parallel [(set (match_dup 3)
7797                    (minus:SI (match_dup 4)
7798                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7799                                       (match_dup 5))))
7800               (clobber (reg:CC FLAGS_REG))])]
7801   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7802
7803 (define_insn "subdi3_carry_rex64"
7804   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7805           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7806             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7807                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7808    (clobber (reg:CC FLAGS_REG))]
7809   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7810   "sbb{q}\t{%2, %0|%0, %2}"
7811   [(set_attr "type" "alu")
7812    (set_attr "use_carry" "1")
7813    (set_attr "pent_pair" "pu")
7814    (set_attr "mode" "DI")])
7815
7816 (define_insn "*subdi_1_rex64"
7817   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7818         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7819                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7820    (clobber (reg:CC FLAGS_REG))]
7821   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7822   "sub{q}\t{%2, %0|%0, %2}"
7823   [(set_attr "type" "alu")
7824    (set_attr "mode" "DI")])
7825
7826 (define_insn "*subdi_2_rex64"
7827   [(set (reg FLAGS_REG)
7828         (compare
7829           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7830                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7831           (const_int 0)))
7832    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7833         (minus:DI (match_dup 1) (match_dup 2)))]
7834   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7835    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7836   "sub{q}\t{%2, %0|%0, %2}"
7837   [(set_attr "type" "alu")
7838    (set_attr "mode" "DI")])
7839
7840 (define_insn "*subdi_3_rex63"
7841   [(set (reg FLAGS_REG)
7842         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7843                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7844    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7845         (minus:DI (match_dup 1) (match_dup 2)))]
7846   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7847    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7848   "sub{q}\t{%2, %0|%0, %2}"
7849   [(set_attr "type" "alu")
7850    (set_attr "mode" "DI")])
7851
7852 (define_insn "subqi3_carry"
7853   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7854           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7855             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7856                (match_operand:QI 2 "general_operand" "qn,qm"))))
7857    (clobber (reg:CC FLAGS_REG))]
7858   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7859   "sbb{b}\t{%2, %0|%0, %2}"
7860   [(set_attr "type" "alu")
7861    (set_attr "use_carry" "1")
7862    (set_attr "pent_pair" "pu")
7863    (set_attr "mode" "QI")])
7864
7865 (define_insn "subhi3_carry"
7866   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7867           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7868             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7869                (match_operand:HI 2 "general_operand" "rn,rm"))))
7870    (clobber (reg:CC FLAGS_REG))]
7871   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7872   "sbb{w}\t{%2, %0|%0, %2}"
7873   [(set_attr "type" "alu")
7874    (set_attr "use_carry" "1")
7875    (set_attr "pent_pair" "pu")
7876    (set_attr "mode" "HI")])
7877
7878 (define_insn "subsi3_carry"
7879   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7880           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7881             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7882                (match_operand:SI 2 "general_operand" "ri,rm"))))
7883    (clobber (reg:CC FLAGS_REG))]
7884   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7885   "sbb{l}\t{%2, %0|%0, %2}"
7886   [(set_attr "type" "alu")
7887    (set_attr "use_carry" "1")
7888    (set_attr "pent_pair" "pu")
7889    (set_attr "mode" "SI")])
7890
7891 (define_insn "subsi3_carry_zext"
7892   [(set (match_operand:DI 0 "register_operand" "=r")
7893           (zero_extend:DI
7894             (minus:SI (match_operand:SI 1 "register_operand" "0")
7895               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7896                  (match_operand:SI 2 "general_operand" "g")))))
7897    (clobber (reg:CC FLAGS_REG))]
7898   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7899   "sbb{l}\t{%2, %k0|%k0, %2}"
7900   [(set_attr "type" "alu")
7901    (set_attr "pent_pair" "pu")
7902    (set_attr "mode" "SI")])
7903
7904 (define_expand "subsi3"
7905   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7906         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7907                   (match_operand:SI 2 "general_operand" "")))]
7908   ""
7909   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7910
7911 (define_insn "*subsi_1"
7912   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7913         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7914                   (match_operand:SI 2 "general_operand" "ri,rm")))
7915    (clobber (reg:CC FLAGS_REG))]
7916   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7917   "sub{l}\t{%2, %0|%0, %2}"
7918   [(set_attr "type" "alu")
7919    (set_attr "mode" "SI")])
7920
7921 (define_insn "*subsi_1_zext"
7922   [(set (match_operand:DI 0 "register_operand" "=r")
7923         (zero_extend:DI
7924           (minus:SI (match_operand:SI 1 "register_operand" "0")
7925                     (match_operand:SI 2 "general_operand" "g"))))
7926    (clobber (reg:CC FLAGS_REG))]
7927   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7928   "sub{l}\t{%2, %k0|%k0, %2}"
7929   [(set_attr "type" "alu")
7930    (set_attr "mode" "SI")])
7931
7932 (define_insn "*subsi_2"
7933   [(set (reg FLAGS_REG)
7934         (compare
7935           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7936                     (match_operand:SI 2 "general_operand" "ri,rm"))
7937           (const_int 0)))
7938    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7939         (minus:SI (match_dup 1) (match_dup 2)))]
7940   "ix86_match_ccmode (insn, CCGOCmode)
7941    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7942   "sub{l}\t{%2, %0|%0, %2}"
7943   [(set_attr "type" "alu")
7944    (set_attr "mode" "SI")])
7945
7946 (define_insn "*subsi_2_zext"
7947   [(set (reg FLAGS_REG)
7948         (compare
7949           (minus:SI (match_operand:SI 1 "register_operand" "0")
7950                     (match_operand:SI 2 "general_operand" "g"))
7951           (const_int 0)))
7952    (set (match_operand:DI 0 "register_operand" "=r")
7953         (zero_extend:DI
7954           (minus:SI (match_dup 1)
7955                     (match_dup 2))))]
7956   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7957    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7958   "sub{l}\t{%2, %k0|%k0, %2}"
7959   [(set_attr "type" "alu")
7960    (set_attr "mode" "SI")])
7961
7962 (define_insn "*subsi_3"
7963   [(set (reg FLAGS_REG)
7964         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7965                  (match_operand:SI 2 "general_operand" "ri,rm")))
7966    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7967         (minus:SI (match_dup 1) (match_dup 2)))]
7968   "ix86_match_ccmode (insn, CCmode)
7969    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7970   "sub{l}\t{%2, %0|%0, %2}"
7971   [(set_attr "type" "alu")
7972    (set_attr "mode" "SI")])
7973
7974 (define_insn "*subsi_3_zext"
7975   [(set (reg FLAGS_REG)
7976         (compare (match_operand:SI 1 "register_operand" "0")
7977                  (match_operand:SI 2 "general_operand" "g")))
7978    (set (match_operand:DI 0 "register_operand" "=r")
7979         (zero_extend:DI
7980           (minus:SI (match_dup 1)
7981                     (match_dup 2))))]
7982   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7983    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7984   "sub{l}\t{%2, %1|%1, %2}"
7985   [(set_attr "type" "alu")
7986    (set_attr "mode" "DI")])
7987
7988 (define_expand "subhi3"
7989   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7990         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7991                   (match_operand:HI 2 "general_operand" "")))]
7992   "TARGET_HIMODE_MATH"
7993   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7994
7995 (define_insn "*subhi_1"
7996   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7997         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7998                   (match_operand:HI 2 "general_operand" "rn,rm")))
7999    (clobber (reg:CC FLAGS_REG))]
8000   "ix86_binary_operator_ok (MINUS, HImode, operands)"
8001   "sub{w}\t{%2, %0|%0, %2}"
8002   [(set_attr "type" "alu")
8003    (set_attr "mode" "HI")])
8004
8005 (define_insn "*subhi_2"
8006   [(set (reg FLAGS_REG)
8007         (compare
8008           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8009                     (match_operand:HI 2 "general_operand" "rn,rm"))
8010           (const_int 0)))
8011    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8012         (minus:HI (match_dup 1) (match_dup 2)))]
8013   "ix86_match_ccmode (insn, CCGOCmode)
8014    && ix86_binary_operator_ok (MINUS, HImode, operands)"
8015   "sub{w}\t{%2, %0|%0, %2}"
8016   [(set_attr "type" "alu")
8017    (set_attr "mode" "HI")])
8018
8019 (define_insn "*subhi_3"
8020   [(set (reg FLAGS_REG)
8021         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
8022                  (match_operand:HI 2 "general_operand" "rn,rm")))
8023    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8024         (minus:HI (match_dup 1) (match_dup 2)))]
8025   "ix86_match_ccmode (insn, CCmode)
8026    && ix86_binary_operator_ok (MINUS, HImode, operands)"
8027   "sub{w}\t{%2, %0|%0, %2}"
8028   [(set_attr "type" "alu")
8029    (set_attr "mode" "HI")])
8030
8031 (define_expand "subqi3"
8032   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8033         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
8034                   (match_operand:QI 2 "general_operand" "")))]
8035   "TARGET_QIMODE_MATH"
8036   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
8037
8038 (define_insn "*subqi_1"
8039   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8040         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8041                   (match_operand:QI 2 "general_operand" "qn,qm")))
8042    (clobber (reg:CC FLAGS_REG))]
8043   "ix86_binary_operator_ok (MINUS, QImode, operands)"
8044   "sub{b}\t{%2, %0|%0, %2}"
8045   [(set_attr "type" "alu")
8046    (set_attr "mode" "QI")])
8047
8048 (define_insn "*subqi_1_slp"
8049   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8050         (minus:QI (match_dup 0)
8051                   (match_operand:QI 1 "general_operand" "qn,qm")))
8052    (clobber (reg:CC FLAGS_REG))]
8053   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8054    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8055   "sub{b}\t{%1, %0|%0, %1}"
8056   [(set_attr "type" "alu1")
8057    (set_attr "mode" "QI")])
8058
8059 (define_insn "*subqi_2"
8060   [(set (reg FLAGS_REG)
8061         (compare
8062           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8063                     (match_operand:QI 2 "general_operand" "qn,qm"))
8064           (const_int 0)))
8065    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8066         (minus:QI (match_dup 1) (match_dup 2)))]
8067   "ix86_match_ccmode (insn, CCGOCmode)
8068    && ix86_binary_operator_ok (MINUS, QImode, operands)"
8069   "sub{b}\t{%2, %0|%0, %2}"
8070   [(set_attr "type" "alu")
8071    (set_attr "mode" "QI")])
8072
8073 (define_insn "*subqi_3"
8074   [(set (reg FLAGS_REG)
8075         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
8076                  (match_operand:QI 2 "general_operand" "qn,qm")))
8077    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8078         (minus:QI (match_dup 1) (match_dup 2)))]
8079   "ix86_match_ccmode (insn, CCmode)
8080    && ix86_binary_operator_ok (MINUS, QImode, operands)"
8081   "sub{b}\t{%2, %0|%0, %2}"
8082   [(set_attr "type" "alu")
8083    (set_attr "mode" "QI")])
8084
8085 ;; The patterns that match these are at the end of this file.
8086
8087 (define_expand "subxf3"
8088   [(set (match_operand:XF 0 "register_operand" "")
8089         (minus:XF (match_operand:XF 1 "register_operand" "")
8090                   (match_operand:XF 2 "register_operand" "")))]
8091   "TARGET_80387"
8092   "")
8093
8094 (define_expand "sub<mode>3"
8095   [(set (match_operand:MODEF 0 "register_operand" "")
8096         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
8097                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8098   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8099     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8100   "")
8101 \f
8102 ;; Multiply instructions
8103
8104 (define_expand "muldi3"
8105   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8106                    (mult:DI (match_operand:DI 1 "register_operand" "")
8107                             (match_operand:DI 2 "x86_64_general_operand" "")))
8108               (clobber (reg:CC FLAGS_REG))])]
8109   "TARGET_64BIT"
8110   "")
8111
8112 ;; On AMDFAM10
8113 ;; IMUL reg64, reg64, imm8      Direct
8114 ;; IMUL reg64, mem64, imm8      VectorPath
8115 ;; IMUL reg64, reg64, imm32     Direct
8116 ;; IMUL reg64, mem64, imm32     VectorPath
8117 ;; IMUL reg64, reg64            Direct
8118 ;; IMUL reg64, mem64            Direct
8119
8120 (define_insn "*muldi3_1_rex64"
8121   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8122         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
8123                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
8124    (clobber (reg:CC FLAGS_REG))]
8125   "TARGET_64BIT
8126    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8127   "@
8128    imul{q}\t{%2, %1, %0|%0, %1, %2}
8129    imul{q}\t{%2, %1, %0|%0, %1, %2}
8130    imul{q}\t{%2, %0|%0, %2}"
8131   [(set_attr "type" "imul")
8132    (set_attr "prefix_0f" "0,0,1")
8133    (set (attr "athlon_decode")
8134         (cond [(eq_attr "cpu" "athlon")
8135                   (const_string "vector")
8136                (eq_attr "alternative" "1")
8137                   (const_string "vector")
8138                (and (eq_attr "alternative" "2")
8139                     (match_operand 1 "memory_operand" ""))
8140                   (const_string "vector")]
8141               (const_string "direct")))
8142    (set (attr "amdfam10_decode")
8143         (cond [(and (eq_attr "alternative" "0,1")
8144                     (match_operand 1 "memory_operand" ""))
8145                   (const_string "vector")]
8146               (const_string "direct")))
8147    (set_attr "mode" "DI")])
8148
8149 (define_expand "mulsi3"
8150   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8151                    (mult:SI (match_operand:SI 1 "register_operand" "")
8152                             (match_operand:SI 2 "general_operand" "")))
8153               (clobber (reg:CC FLAGS_REG))])]
8154   ""
8155   "")
8156
8157 ;; On AMDFAM10
8158 ;; IMUL reg32, reg32, imm8      Direct
8159 ;; IMUL reg32, mem32, imm8      VectorPath
8160 ;; IMUL reg32, reg32, imm32     Direct
8161 ;; IMUL reg32, mem32, imm32     VectorPath
8162 ;; IMUL reg32, reg32            Direct
8163 ;; IMUL reg32, mem32            Direct
8164
8165 (define_insn "*mulsi3_1"
8166   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
8167         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8168                  (match_operand:SI 2 "general_operand" "K,i,mr")))
8169    (clobber (reg:CC FLAGS_REG))]
8170   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8171   "@
8172    imul{l}\t{%2, %1, %0|%0, %1, %2}
8173    imul{l}\t{%2, %1, %0|%0, %1, %2}
8174    imul{l}\t{%2, %0|%0, %2}"
8175   [(set_attr "type" "imul")
8176    (set_attr "prefix_0f" "0,0,1")
8177    (set (attr "athlon_decode")
8178         (cond [(eq_attr "cpu" "athlon")
8179                   (const_string "vector")
8180                (eq_attr "alternative" "1")
8181                   (const_string "vector")
8182                (and (eq_attr "alternative" "2")
8183                     (match_operand 1 "memory_operand" ""))
8184                   (const_string "vector")]
8185               (const_string "direct")))
8186    (set (attr "amdfam10_decode")
8187         (cond [(and (eq_attr "alternative" "0,1")
8188                     (match_operand 1 "memory_operand" ""))
8189                   (const_string "vector")]
8190               (const_string "direct")))
8191    (set_attr "mode" "SI")])
8192
8193 (define_insn "*mulsi3_1_zext"
8194   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8195         (zero_extend:DI
8196           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8197                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
8198    (clobber (reg:CC FLAGS_REG))]
8199   "TARGET_64BIT
8200    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8201   "@
8202    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8203    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8204    imul{l}\t{%2, %k0|%k0, %2}"
8205   [(set_attr "type" "imul")
8206    (set_attr "prefix_0f" "0,0,1")
8207    (set (attr "athlon_decode")
8208         (cond [(eq_attr "cpu" "athlon")
8209                   (const_string "vector")
8210                (eq_attr "alternative" "1")
8211                   (const_string "vector")
8212                (and (eq_attr "alternative" "2")
8213                     (match_operand 1 "memory_operand" ""))
8214                   (const_string "vector")]
8215               (const_string "direct")))
8216    (set (attr "amdfam10_decode")
8217         (cond [(and (eq_attr "alternative" "0,1")
8218                     (match_operand 1 "memory_operand" ""))
8219                   (const_string "vector")]
8220               (const_string "direct")))
8221    (set_attr "mode" "SI")])
8222
8223 (define_expand "mulhi3"
8224   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8225                    (mult:HI (match_operand:HI 1 "register_operand" "")
8226                             (match_operand:HI 2 "general_operand" "")))
8227               (clobber (reg:CC FLAGS_REG))])]
8228   "TARGET_HIMODE_MATH"
8229   "")
8230
8231 ;; On AMDFAM10
8232 ;; IMUL reg16, reg16, imm8      VectorPath
8233 ;; IMUL reg16, mem16, imm8      VectorPath
8234 ;; IMUL reg16, reg16, imm16     VectorPath
8235 ;; IMUL reg16, mem16, imm16     VectorPath
8236 ;; IMUL reg16, reg16            Direct
8237 ;; IMUL reg16, mem16            Direct
8238 (define_insn "*mulhi3_1"
8239   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8240         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8241                  (match_operand:HI 2 "general_operand" "K,n,mr")))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8244   "@
8245    imul{w}\t{%2, %1, %0|%0, %1, %2}
8246    imul{w}\t{%2, %1, %0|%0, %1, %2}
8247    imul{w}\t{%2, %0|%0, %2}"
8248   [(set_attr "type" "imul")
8249    (set_attr "prefix_0f" "0,0,1")
8250    (set (attr "athlon_decode")
8251         (cond [(eq_attr "cpu" "athlon")
8252                   (const_string "vector")
8253                (eq_attr "alternative" "1,2")
8254                   (const_string "vector")]
8255               (const_string "direct")))
8256    (set (attr "amdfam10_decode")
8257         (cond [(eq_attr "alternative" "0,1")
8258                   (const_string "vector")]
8259               (const_string "direct")))
8260    (set_attr "mode" "HI")])
8261
8262 (define_expand "mulqi3"
8263   [(parallel [(set (match_operand:QI 0 "register_operand" "")
8264                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8265                             (match_operand:QI 2 "register_operand" "")))
8266               (clobber (reg:CC FLAGS_REG))])]
8267   "TARGET_QIMODE_MATH"
8268   "")
8269
8270 ;;On AMDFAM10
8271 ;; MUL reg8     Direct
8272 ;; MUL mem8     Direct
8273
8274 (define_insn "*mulqi3_1"
8275   [(set (match_operand:QI 0 "register_operand" "=a")
8276         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8277                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8278    (clobber (reg:CC FLAGS_REG))]
8279   "TARGET_QIMODE_MATH
8280    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8281   "mul{b}\t%2"
8282   [(set_attr "type" "imul")
8283    (set_attr "length_immediate" "0")
8284    (set (attr "athlon_decode")
8285      (if_then_else (eq_attr "cpu" "athlon")
8286         (const_string "vector")
8287         (const_string "direct")))
8288    (set_attr "amdfam10_decode" "direct")
8289    (set_attr "mode" "QI")])
8290
8291 (define_expand "umulqihi3"
8292   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8293                    (mult:HI (zero_extend:HI
8294                               (match_operand:QI 1 "nonimmediate_operand" ""))
8295                             (zero_extend:HI
8296                               (match_operand:QI 2 "register_operand" ""))))
8297               (clobber (reg:CC FLAGS_REG))])]
8298   "TARGET_QIMODE_MATH"
8299   "")
8300
8301 (define_insn "*umulqihi3_1"
8302   [(set (match_operand:HI 0 "register_operand" "=a")
8303         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8304                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8305    (clobber (reg:CC FLAGS_REG))]
8306   "TARGET_QIMODE_MATH
8307    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8308   "mul{b}\t%2"
8309   [(set_attr "type" "imul")
8310    (set_attr "length_immediate" "0")
8311    (set (attr "athlon_decode")
8312      (if_then_else (eq_attr "cpu" "athlon")
8313         (const_string "vector")
8314         (const_string "direct")))
8315    (set_attr "amdfam10_decode" "direct")
8316    (set_attr "mode" "QI")])
8317
8318 (define_expand "mulqihi3"
8319   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8320                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8321                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8322               (clobber (reg:CC FLAGS_REG))])]
8323   "TARGET_QIMODE_MATH"
8324   "")
8325
8326 (define_insn "*mulqihi3_insn"
8327   [(set (match_operand:HI 0 "register_operand" "=a")
8328         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8329                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8330    (clobber (reg:CC FLAGS_REG))]
8331   "TARGET_QIMODE_MATH
8332    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8333   "imul{b}\t%2"
8334   [(set_attr "type" "imul")
8335    (set_attr "length_immediate" "0")
8336    (set (attr "athlon_decode")
8337      (if_then_else (eq_attr "cpu" "athlon")
8338         (const_string "vector")
8339         (const_string "direct")))
8340    (set_attr "amdfam10_decode" "direct")
8341    (set_attr "mode" "QI")])
8342
8343 (define_expand "umulditi3"
8344   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8345                    (mult:TI (zero_extend:TI
8346                               (match_operand:DI 1 "nonimmediate_operand" ""))
8347                             (zero_extend:TI
8348                               (match_operand:DI 2 "register_operand" ""))))
8349               (clobber (reg:CC FLAGS_REG))])]
8350   "TARGET_64BIT"
8351   "")
8352
8353 (define_insn "*umulditi3_insn"
8354   [(set (match_operand:TI 0 "register_operand" "=A")
8355         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8356                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8357    (clobber (reg:CC FLAGS_REG))]
8358   "TARGET_64BIT
8359    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8360   "mul{q}\t%2"
8361   [(set_attr "type" "imul")
8362    (set_attr "length_immediate" "0")
8363    (set (attr "athlon_decode")
8364      (if_then_else (eq_attr "cpu" "athlon")
8365         (const_string "vector")
8366         (const_string "double")))
8367    (set_attr "amdfam10_decode" "double")
8368    (set_attr "mode" "DI")])
8369
8370 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8371 (define_expand "umulsidi3"
8372   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8373                    (mult:DI (zero_extend:DI
8374                               (match_operand:SI 1 "nonimmediate_operand" ""))
8375                             (zero_extend:DI
8376                               (match_operand:SI 2 "register_operand" ""))))
8377               (clobber (reg:CC FLAGS_REG))])]
8378   "!TARGET_64BIT"
8379   "")
8380
8381 (define_insn "*umulsidi3_insn"
8382   [(set (match_operand:DI 0 "register_operand" "=A")
8383         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8384                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8385    (clobber (reg:CC FLAGS_REG))]
8386   "!TARGET_64BIT
8387    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8388   "mul{l}\t%2"
8389   [(set_attr "type" "imul")
8390    (set_attr "length_immediate" "0")
8391    (set (attr "athlon_decode")
8392      (if_then_else (eq_attr "cpu" "athlon")
8393         (const_string "vector")
8394         (const_string "double")))
8395    (set_attr "amdfam10_decode" "double")
8396    (set_attr "mode" "SI")])
8397
8398 (define_expand "mulditi3"
8399   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8400                    (mult:TI (sign_extend:TI
8401                               (match_operand:DI 1 "nonimmediate_operand" ""))
8402                             (sign_extend:TI
8403                               (match_operand:DI 2 "register_operand" ""))))
8404               (clobber (reg:CC FLAGS_REG))])]
8405   "TARGET_64BIT"
8406   "")
8407
8408 (define_insn "*mulditi3_insn"
8409   [(set (match_operand:TI 0 "register_operand" "=A")
8410         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8411                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8412    (clobber (reg:CC FLAGS_REG))]
8413   "TARGET_64BIT
8414    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8415   "imul{q}\t%2"
8416   [(set_attr "type" "imul")
8417    (set_attr "length_immediate" "0")
8418    (set (attr "athlon_decode")
8419      (if_then_else (eq_attr "cpu" "athlon")
8420         (const_string "vector")
8421         (const_string "double")))
8422    (set_attr "amdfam10_decode" "double")
8423    (set_attr "mode" "DI")])
8424
8425 (define_expand "mulsidi3"
8426   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8427                    (mult:DI (sign_extend:DI
8428                               (match_operand:SI 1 "nonimmediate_operand" ""))
8429                             (sign_extend:DI
8430                               (match_operand:SI 2 "register_operand" ""))))
8431               (clobber (reg:CC FLAGS_REG))])]
8432   "!TARGET_64BIT"
8433   "")
8434
8435 (define_insn "*mulsidi3_insn"
8436   [(set (match_operand:DI 0 "register_operand" "=A")
8437         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8438                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8439    (clobber (reg:CC FLAGS_REG))]
8440   "!TARGET_64BIT
8441    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8442   "imul{l}\t%2"
8443   [(set_attr "type" "imul")
8444    (set_attr "length_immediate" "0")
8445    (set (attr "athlon_decode")
8446      (if_then_else (eq_attr "cpu" "athlon")
8447         (const_string "vector")
8448         (const_string "double")))
8449    (set_attr "amdfam10_decode" "double")
8450    (set_attr "mode" "SI")])
8451
8452 (define_expand "umuldi3_highpart"
8453   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8454                    (truncate:DI
8455                      (lshiftrt:TI
8456                        (mult:TI (zero_extend:TI
8457                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8458                                 (zero_extend:TI
8459                                   (match_operand:DI 2 "register_operand" "")))
8460                        (const_int 64))))
8461               (clobber (match_scratch:DI 3 ""))
8462               (clobber (reg:CC FLAGS_REG))])]
8463   "TARGET_64BIT"
8464   "")
8465
8466 (define_insn "*umuldi3_highpart_rex64"
8467   [(set (match_operand:DI 0 "register_operand" "=d")
8468         (truncate:DI
8469           (lshiftrt:TI
8470             (mult:TI (zero_extend:TI
8471                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8472                      (zero_extend:TI
8473                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8474             (const_int 64))))
8475    (clobber (match_scratch:DI 3 "=1"))
8476    (clobber (reg:CC FLAGS_REG))]
8477   "TARGET_64BIT
8478    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8479   "mul{q}\t%2"
8480   [(set_attr "type" "imul")
8481    (set_attr "length_immediate" "0")
8482    (set (attr "athlon_decode")
8483      (if_then_else (eq_attr "cpu" "athlon")
8484         (const_string "vector")
8485         (const_string "double")))
8486    (set_attr "amdfam10_decode" "double")
8487    (set_attr "mode" "DI")])
8488
8489 (define_expand "umulsi3_highpart"
8490   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8491                    (truncate:SI
8492                      (lshiftrt:DI
8493                        (mult:DI (zero_extend:DI
8494                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8495                                 (zero_extend:DI
8496                                   (match_operand:SI 2 "register_operand" "")))
8497                        (const_int 32))))
8498               (clobber (match_scratch:SI 3 ""))
8499               (clobber (reg:CC FLAGS_REG))])]
8500   ""
8501   "")
8502
8503 (define_insn "*umulsi3_highpart_insn"
8504   [(set (match_operand:SI 0 "register_operand" "=d")
8505         (truncate:SI
8506           (lshiftrt:DI
8507             (mult:DI (zero_extend:DI
8508                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8509                      (zero_extend:DI
8510                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8511             (const_int 32))))
8512    (clobber (match_scratch:SI 3 "=1"))
8513    (clobber (reg:CC FLAGS_REG))]
8514   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8515   "mul{l}\t%2"
8516   [(set_attr "type" "imul")
8517    (set_attr "length_immediate" "0")
8518    (set (attr "athlon_decode")
8519      (if_then_else (eq_attr "cpu" "athlon")
8520         (const_string "vector")
8521         (const_string "double")))
8522    (set_attr "amdfam10_decode" "double")
8523    (set_attr "mode" "SI")])
8524
8525 (define_insn "*umulsi3_highpart_zext"
8526   [(set (match_operand:DI 0 "register_operand" "=d")
8527         (zero_extend:DI (truncate:SI
8528           (lshiftrt:DI
8529             (mult:DI (zero_extend:DI
8530                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8531                      (zero_extend:DI
8532                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8533             (const_int 32)))))
8534    (clobber (match_scratch:SI 3 "=1"))
8535    (clobber (reg:CC FLAGS_REG))]
8536   "TARGET_64BIT
8537    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8538   "mul{l}\t%2"
8539   [(set_attr "type" "imul")
8540    (set_attr "length_immediate" "0")
8541    (set (attr "athlon_decode")
8542      (if_then_else (eq_attr "cpu" "athlon")
8543         (const_string "vector")
8544         (const_string "double")))
8545    (set_attr "amdfam10_decode" "double")
8546    (set_attr "mode" "SI")])
8547
8548 (define_expand "smuldi3_highpart"
8549   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8550                    (truncate:DI
8551                      (lshiftrt:TI
8552                        (mult:TI (sign_extend:TI
8553                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8554                                 (sign_extend:TI
8555                                   (match_operand:DI 2 "register_operand" "")))
8556                        (const_int 64))))
8557               (clobber (match_scratch:DI 3 ""))
8558               (clobber (reg:CC FLAGS_REG))])]
8559   "TARGET_64BIT"
8560   "")
8561
8562 (define_insn "*smuldi3_highpart_rex64"
8563   [(set (match_operand:DI 0 "register_operand" "=d")
8564         (truncate:DI
8565           (lshiftrt:TI
8566             (mult:TI (sign_extend:TI
8567                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8568                      (sign_extend:TI
8569                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8570             (const_int 64))))
8571    (clobber (match_scratch:DI 3 "=1"))
8572    (clobber (reg:CC FLAGS_REG))]
8573   "TARGET_64BIT
8574    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8575   "imul{q}\t%2"
8576   [(set_attr "type" "imul")
8577    (set (attr "athlon_decode")
8578      (if_then_else (eq_attr "cpu" "athlon")
8579         (const_string "vector")
8580         (const_string "double")))
8581    (set_attr "amdfam10_decode" "double")
8582    (set_attr "mode" "DI")])
8583
8584 (define_expand "smulsi3_highpart"
8585   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8586                    (truncate:SI
8587                      (lshiftrt:DI
8588                        (mult:DI (sign_extend:DI
8589                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8590                                 (sign_extend:DI
8591                                   (match_operand:SI 2 "register_operand" "")))
8592                        (const_int 32))))
8593               (clobber (match_scratch:SI 3 ""))
8594               (clobber (reg:CC FLAGS_REG))])]
8595   ""
8596   "")
8597
8598 (define_insn "*smulsi3_highpart_insn"
8599   [(set (match_operand:SI 0 "register_operand" "=d")
8600         (truncate:SI
8601           (lshiftrt:DI
8602             (mult:DI (sign_extend:DI
8603                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8604                      (sign_extend:DI
8605                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8606             (const_int 32))))
8607    (clobber (match_scratch:SI 3 "=1"))
8608    (clobber (reg:CC FLAGS_REG))]
8609   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8610   "imul{l}\t%2"
8611   [(set_attr "type" "imul")
8612    (set (attr "athlon_decode")
8613      (if_then_else (eq_attr "cpu" "athlon")
8614         (const_string "vector")
8615         (const_string "double")))
8616    (set_attr "amdfam10_decode" "double")
8617    (set_attr "mode" "SI")])
8618
8619 (define_insn "*smulsi3_highpart_zext"
8620   [(set (match_operand:DI 0 "register_operand" "=d")
8621         (zero_extend:DI (truncate:SI
8622           (lshiftrt:DI
8623             (mult:DI (sign_extend:DI
8624                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8625                      (sign_extend:DI
8626                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8627             (const_int 32)))))
8628    (clobber (match_scratch:SI 3 "=1"))
8629    (clobber (reg:CC FLAGS_REG))]
8630   "TARGET_64BIT
8631    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8632   "imul{l}\t%2"
8633   [(set_attr "type" "imul")
8634    (set (attr "athlon_decode")
8635      (if_then_else (eq_attr "cpu" "athlon")
8636         (const_string "vector")
8637         (const_string "double")))
8638    (set_attr "amdfam10_decode" "double")
8639    (set_attr "mode" "SI")])
8640
8641 ;; The patterns that match these are at the end of this file.
8642
8643 (define_expand "mulxf3"
8644   [(set (match_operand:XF 0 "register_operand" "")
8645         (mult:XF (match_operand:XF 1 "register_operand" "")
8646                  (match_operand:XF 2 "register_operand" "")))]
8647   "TARGET_80387"
8648   "")
8649
8650 (define_expand "mul<mode>3"
8651   [(set (match_operand:MODEF 0 "register_operand" "")
8652         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8653                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8654   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8655     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8656   "")
8657
8658 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8659
8660 \f
8661 ;; Divide instructions
8662
8663 (define_insn "divqi3"
8664   [(set (match_operand:QI 0 "register_operand" "=a")
8665         (div:QI (match_operand:HI 1 "register_operand" "0")
8666                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8667    (clobber (reg:CC FLAGS_REG))]
8668   "TARGET_QIMODE_MATH"
8669   "idiv{b}\t%2"
8670   [(set_attr "type" "idiv")
8671    (set_attr "mode" "QI")])
8672
8673 (define_insn "udivqi3"
8674   [(set (match_operand:QI 0 "register_operand" "=a")
8675         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8676                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8677    (clobber (reg:CC FLAGS_REG))]
8678   "TARGET_QIMODE_MATH"
8679   "div{b}\t%2"
8680   [(set_attr "type" "idiv")
8681    (set_attr "mode" "QI")])
8682
8683 ;; The patterns that match these are at the end of this file.
8684
8685 (define_expand "divxf3"
8686   [(set (match_operand:XF 0 "register_operand" "")
8687         (div:XF (match_operand:XF 1 "register_operand" "")
8688                 (match_operand:XF 2 "register_operand" "")))]
8689   "TARGET_80387"
8690   "")
8691
8692 (define_expand "divdf3"
8693   [(set (match_operand:DF 0 "register_operand" "")
8694         (div:DF (match_operand:DF 1 "register_operand" "")
8695                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8696    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8697     || (TARGET_SSE2 && TARGET_SSE_MATH)"
8698    "")
8699
8700 (define_expand "divsf3"
8701   [(set (match_operand:SF 0 "register_operand" "")
8702         (div:SF (match_operand:SF 1 "register_operand" "")
8703                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8704   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8705     || TARGET_SSE_MATH"
8706 {
8707   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8708       && flag_finite_math_only && !flag_trapping_math
8709       && flag_unsafe_math_optimizations)
8710     {
8711       ix86_emit_swdivsf (operands[0], operands[1],
8712                          operands[2], SFmode);
8713       DONE;
8714     }
8715 })
8716 \f
8717 ;; Remainder instructions.
8718
8719 (define_expand "divmoddi4"
8720   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8721                    (div:DI (match_operand:DI 1 "register_operand" "")
8722                            (match_operand:DI 2 "nonimmediate_operand" "")))
8723               (set (match_operand:DI 3 "register_operand" "")
8724                    (mod:DI (match_dup 1) (match_dup 2)))
8725               (clobber (reg:CC FLAGS_REG))])]
8726   "TARGET_64BIT"
8727   "")
8728
8729 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8730 ;; Penalize eax case slightly because it results in worse scheduling
8731 ;; of code.
8732 (define_insn "*divmoddi4_nocltd_rex64"
8733   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8734         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8735                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8736    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8737         (mod:DI (match_dup 2) (match_dup 3)))
8738    (clobber (reg:CC FLAGS_REG))]
8739   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8740   "#"
8741   [(set_attr "type" "multi")])
8742
8743 (define_insn "*divmoddi4_cltd_rex64"
8744   [(set (match_operand:DI 0 "register_operand" "=a")
8745         (div:DI (match_operand:DI 2 "register_operand" "a")
8746                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8747    (set (match_operand:DI 1 "register_operand" "=&d")
8748         (mod:DI (match_dup 2) (match_dup 3)))
8749    (clobber (reg:CC FLAGS_REG))]
8750   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8751   "#"
8752   [(set_attr "type" "multi")])
8753
8754 (define_insn "*divmoddi_noext_rex64"
8755   [(set (match_operand:DI 0 "register_operand" "=a")
8756         (div:DI (match_operand:DI 1 "register_operand" "0")
8757                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8758    (set (match_operand:DI 3 "register_operand" "=d")
8759         (mod:DI (match_dup 1) (match_dup 2)))
8760    (use (match_operand:DI 4 "register_operand" "3"))
8761    (clobber (reg:CC FLAGS_REG))]
8762   "TARGET_64BIT"
8763   "idiv{q}\t%2"
8764   [(set_attr "type" "idiv")
8765    (set_attr "mode" "DI")])
8766
8767 (define_split
8768   [(set (match_operand:DI 0 "register_operand" "")
8769         (div:DI (match_operand:DI 1 "register_operand" "")
8770                 (match_operand:DI 2 "nonimmediate_operand" "")))
8771    (set (match_operand:DI 3 "register_operand" "")
8772         (mod:DI (match_dup 1) (match_dup 2)))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "TARGET_64BIT && reload_completed"
8775   [(parallel [(set (match_dup 3)
8776                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8777               (clobber (reg:CC FLAGS_REG))])
8778    (parallel [(set (match_dup 0)
8779                    (div:DI (reg:DI 0) (match_dup 2)))
8780               (set (match_dup 3)
8781                    (mod:DI (reg:DI 0) (match_dup 2)))
8782               (use (match_dup 3))
8783               (clobber (reg:CC FLAGS_REG))])]
8784 {
8785   /* Avoid use of cltd in favor of a mov+shift.  */
8786   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8787     {
8788       if (true_regnum (operands[1]))
8789         emit_move_insn (operands[0], operands[1]);
8790       else
8791         emit_move_insn (operands[3], operands[1]);
8792       operands[4] = operands[3];
8793     }
8794   else
8795     {
8796       gcc_assert (!true_regnum (operands[1]));
8797       operands[4] = operands[1];
8798     }
8799 })
8800
8801
8802 (define_expand "divmodsi4"
8803   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8804                    (div:SI (match_operand:SI 1 "register_operand" "")
8805                            (match_operand:SI 2 "nonimmediate_operand" "")))
8806               (set (match_operand:SI 3 "register_operand" "")
8807                    (mod:SI (match_dup 1) (match_dup 2)))
8808               (clobber (reg:CC FLAGS_REG))])]
8809   ""
8810   "")
8811
8812 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8813 ;; Penalize eax case slightly because it results in worse scheduling
8814 ;; of code.
8815 (define_insn "*divmodsi4_nocltd"
8816   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8817         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8818                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8819    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8820         (mod:SI (match_dup 2) (match_dup 3)))
8821    (clobber (reg:CC FLAGS_REG))]
8822   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8823   "#"
8824   [(set_attr "type" "multi")])
8825
8826 (define_insn "*divmodsi4_cltd"
8827   [(set (match_operand:SI 0 "register_operand" "=a")
8828         (div:SI (match_operand:SI 2 "register_operand" "a")
8829                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8830    (set (match_operand:SI 1 "register_operand" "=&d")
8831         (mod:SI (match_dup 2) (match_dup 3)))
8832    (clobber (reg:CC FLAGS_REG))]
8833   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8834   "#"
8835   [(set_attr "type" "multi")])
8836
8837 (define_insn "*divmodsi_noext"
8838   [(set (match_operand:SI 0 "register_operand" "=a")
8839         (div:SI (match_operand:SI 1 "register_operand" "0")
8840                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8841    (set (match_operand:SI 3 "register_operand" "=d")
8842         (mod:SI (match_dup 1) (match_dup 2)))
8843    (use (match_operand:SI 4 "register_operand" "3"))
8844    (clobber (reg:CC FLAGS_REG))]
8845   ""
8846   "idiv{l}\t%2"
8847   [(set_attr "type" "idiv")
8848    (set_attr "mode" "SI")])
8849
8850 (define_split
8851   [(set (match_operand:SI 0 "register_operand" "")
8852         (div:SI (match_operand:SI 1 "register_operand" "")
8853                 (match_operand:SI 2 "nonimmediate_operand" "")))
8854    (set (match_operand:SI 3 "register_operand" "")
8855         (mod:SI (match_dup 1) (match_dup 2)))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "reload_completed"
8858   [(parallel [(set (match_dup 3)
8859                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8860               (clobber (reg:CC FLAGS_REG))])
8861    (parallel [(set (match_dup 0)
8862                    (div:SI (reg:SI 0) (match_dup 2)))
8863               (set (match_dup 3)
8864                    (mod:SI (reg:SI 0) (match_dup 2)))
8865               (use (match_dup 3))
8866               (clobber (reg:CC FLAGS_REG))])]
8867 {
8868   /* Avoid use of cltd in favor of a mov+shift.  */
8869   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8870     {
8871       if (true_regnum (operands[1]))
8872         emit_move_insn (operands[0], operands[1]);
8873       else
8874         emit_move_insn (operands[3], operands[1]);
8875       operands[4] = operands[3];
8876     }
8877   else
8878     {
8879       gcc_assert (!true_regnum (operands[1]));
8880       operands[4] = operands[1];
8881     }
8882 })
8883 ;; %%% Split me.
8884 (define_insn "divmodhi4"
8885   [(set (match_operand:HI 0 "register_operand" "=a")
8886         (div:HI (match_operand:HI 1 "register_operand" "0")
8887                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8888    (set (match_operand:HI 3 "register_operand" "=&d")
8889         (mod:HI (match_dup 1) (match_dup 2)))
8890    (clobber (reg:CC FLAGS_REG))]
8891   "TARGET_HIMODE_MATH"
8892   "cwtd\;idiv{w}\t%2"
8893   [(set_attr "type" "multi")
8894    (set_attr "length_immediate" "0")
8895    (set_attr "mode" "SI")])
8896
8897 (define_insn "udivmoddi4"
8898   [(set (match_operand:DI 0 "register_operand" "=a")
8899         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8900                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8901    (set (match_operand:DI 3 "register_operand" "=&d")
8902         (umod:DI (match_dup 1) (match_dup 2)))
8903    (clobber (reg:CC FLAGS_REG))]
8904   "TARGET_64BIT"
8905   "xor{q}\t%3, %3\;div{q}\t%2"
8906   [(set_attr "type" "multi")
8907    (set_attr "length_immediate" "0")
8908    (set_attr "mode" "DI")])
8909
8910 (define_insn "*udivmoddi4_noext"
8911   [(set (match_operand:DI 0 "register_operand" "=a")
8912         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8913                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8914    (set (match_operand:DI 3 "register_operand" "=d")
8915         (umod:DI (match_dup 1) (match_dup 2)))
8916    (use (match_dup 3))
8917    (clobber (reg:CC FLAGS_REG))]
8918   "TARGET_64BIT"
8919   "div{q}\t%2"
8920   [(set_attr "type" "idiv")
8921    (set_attr "mode" "DI")])
8922
8923 (define_split
8924   [(set (match_operand:DI 0 "register_operand" "")
8925         (udiv:DI (match_operand:DI 1 "register_operand" "")
8926                  (match_operand:DI 2 "nonimmediate_operand" "")))
8927    (set (match_operand:DI 3 "register_operand" "")
8928         (umod:DI (match_dup 1) (match_dup 2)))
8929    (clobber (reg:CC FLAGS_REG))]
8930   "TARGET_64BIT && reload_completed"
8931   [(set (match_dup 3) (const_int 0))
8932    (parallel [(set (match_dup 0)
8933                    (udiv:DI (match_dup 1) (match_dup 2)))
8934               (set (match_dup 3)
8935                    (umod:DI (match_dup 1) (match_dup 2)))
8936               (use (match_dup 3))
8937               (clobber (reg:CC FLAGS_REG))])]
8938   "")
8939
8940 (define_insn "udivmodsi4"
8941   [(set (match_operand:SI 0 "register_operand" "=a")
8942         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8943                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8944    (set (match_operand:SI 3 "register_operand" "=&d")
8945         (umod:SI (match_dup 1) (match_dup 2)))
8946    (clobber (reg:CC FLAGS_REG))]
8947   ""
8948   "xor{l}\t%3, %3\;div{l}\t%2"
8949   [(set_attr "type" "multi")
8950    (set_attr "length_immediate" "0")
8951    (set_attr "mode" "SI")])
8952
8953 (define_insn "*udivmodsi4_noext"
8954   [(set (match_operand:SI 0 "register_operand" "=a")
8955         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8956                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8957    (set (match_operand:SI 3 "register_operand" "=d")
8958         (umod:SI (match_dup 1) (match_dup 2)))
8959    (use (match_dup 3))
8960    (clobber (reg:CC FLAGS_REG))]
8961   ""
8962   "div{l}\t%2"
8963   [(set_attr "type" "idiv")
8964    (set_attr "mode" "SI")])
8965
8966 (define_split
8967   [(set (match_operand:SI 0 "register_operand" "")
8968         (udiv:SI (match_operand:SI 1 "register_operand" "")
8969                  (match_operand:SI 2 "nonimmediate_operand" "")))
8970    (set (match_operand:SI 3 "register_operand" "")
8971         (umod:SI (match_dup 1) (match_dup 2)))
8972    (clobber (reg:CC FLAGS_REG))]
8973   "reload_completed"
8974   [(set (match_dup 3) (const_int 0))
8975    (parallel [(set (match_dup 0)
8976                    (udiv:SI (match_dup 1) (match_dup 2)))
8977               (set (match_dup 3)
8978                    (umod:SI (match_dup 1) (match_dup 2)))
8979               (use (match_dup 3))
8980               (clobber (reg:CC FLAGS_REG))])]
8981   "")
8982
8983 (define_expand "udivmodhi4"
8984   [(set (match_dup 4) (const_int 0))
8985    (parallel [(set (match_operand:HI 0 "register_operand" "")
8986                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8987                             (match_operand:HI 2 "nonimmediate_operand" "")))
8988               (set (match_operand:HI 3 "register_operand" "")
8989                    (umod:HI (match_dup 1) (match_dup 2)))
8990               (use (match_dup 4))
8991               (clobber (reg:CC FLAGS_REG))])]
8992   "TARGET_HIMODE_MATH"
8993   "operands[4] = gen_reg_rtx (HImode);")
8994
8995 (define_insn "*udivmodhi_noext"
8996   [(set (match_operand:HI 0 "register_operand" "=a")
8997         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8998                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8999    (set (match_operand:HI 3 "register_operand" "=d")
9000         (umod:HI (match_dup 1) (match_dup 2)))
9001    (use (match_operand:HI 4 "register_operand" "3"))
9002    (clobber (reg:CC FLAGS_REG))]
9003   ""
9004   "div{w}\t%2"
9005   [(set_attr "type" "idiv")
9006    (set_attr "mode" "HI")])
9007
9008 ;; We cannot use div/idiv for double division, because it causes
9009 ;; "division by zero" on the overflow and that's not what we expect
9010 ;; from truncate.  Because true (non truncating) double division is
9011 ;; never generated, we can't create this insn anyway.
9012 ;
9013 ;(define_insn ""
9014 ;  [(set (match_operand:SI 0 "register_operand" "=a")
9015 ;       (truncate:SI
9016 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
9017 ;                  (zero_extend:DI
9018 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
9019 ;   (set (match_operand:SI 3 "register_operand" "=d")
9020 ;       (truncate:SI
9021 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
9022 ;   (clobber (reg:CC FLAGS_REG))]
9023 ;  ""
9024 ;  "div{l}\t{%2, %0|%0, %2}"
9025 ;  [(set_attr "type" "idiv")])
9026 \f
9027 ;;- Logical AND instructions
9028
9029 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
9030 ;; Note that this excludes ah.
9031
9032 (define_insn "*testdi_1_rex64"
9033   [(set (reg FLAGS_REG)
9034         (compare
9035           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
9036                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
9037           (const_int 0)))]
9038   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9039    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9040   "@
9041    test{l}\t{%k1, %k0|%k0, %k1}
9042    test{l}\t{%k1, %k0|%k0, %k1}
9043    test{q}\t{%1, %0|%0, %1}
9044    test{q}\t{%1, %0|%0, %1}
9045    test{q}\t{%1, %0|%0, %1}"
9046   [(set_attr "type" "test")
9047    (set_attr "modrm" "0,1,0,1,1")
9048    (set_attr "mode" "SI,SI,DI,DI,DI")
9049    (set_attr "pent_pair" "uv,np,uv,np,uv")])
9050
9051 (define_insn "testsi_1"
9052   [(set (reg FLAGS_REG)
9053         (compare
9054           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
9055                   (match_operand:SI 1 "general_operand" "i,i,ri"))
9056           (const_int 0)))]
9057   "ix86_match_ccmode (insn, CCNOmode)
9058    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9059   "test{l}\t{%1, %0|%0, %1}"
9060   [(set_attr "type" "test")
9061    (set_attr "modrm" "0,1,1")
9062    (set_attr "mode" "SI")
9063    (set_attr "pent_pair" "uv,np,uv")])
9064
9065 (define_expand "testsi_ccno_1"
9066   [(set (reg:CCNO FLAGS_REG)
9067         (compare:CCNO
9068           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
9069                   (match_operand:SI 1 "nonmemory_operand" ""))
9070           (const_int 0)))]
9071   ""
9072   "")
9073
9074 (define_insn "*testhi_1"
9075   [(set (reg FLAGS_REG)
9076         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
9077                          (match_operand:HI 1 "general_operand" "n,n,rn"))
9078                  (const_int 0)))]
9079   "ix86_match_ccmode (insn, CCNOmode)
9080    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9081   "test{w}\t{%1, %0|%0, %1}"
9082   [(set_attr "type" "test")
9083    (set_attr "modrm" "0,1,1")
9084    (set_attr "mode" "HI")
9085    (set_attr "pent_pair" "uv,np,uv")])
9086
9087 (define_expand "testqi_ccz_1"
9088   [(set (reg:CCZ FLAGS_REG)
9089         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
9090                              (match_operand:QI 1 "nonmemory_operand" ""))
9091                  (const_int 0)))]
9092   ""
9093   "")
9094
9095 (define_insn "*testqi_1_maybe_si"
9096   [(set (reg FLAGS_REG)
9097         (compare
9098           (and:QI
9099             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
9100             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
9101           (const_int 0)))]
9102    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9103     && ix86_match_ccmode (insn,
9104                          CONST_INT_P (operands[1])
9105                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
9106 {
9107   if (which_alternative == 3)
9108     {
9109       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
9110         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
9111       return "test{l}\t{%1, %k0|%k0, %1}";
9112     }
9113   return "test{b}\t{%1, %0|%0, %1}";
9114 }
9115   [(set_attr "type" "test")
9116    (set_attr "modrm" "0,1,1,1")
9117    (set_attr "mode" "QI,QI,QI,SI")
9118    (set_attr "pent_pair" "uv,np,uv,np")])
9119
9120 (define_insn "*testqi_1"
9121   [(set (reg FLAGS_REG)
9122         (compare
9123           (and:QI
9124             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
9125             (match_operand:QI 1 "general_operand" "n,n,qn"))
9126           (const_int 0)))]
9127   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9128    && ix86_match_ccmode (insn, CCNOmode)"
9129   "test{b}\t{%1, %0|%0, %1}"
9130   [(set_attr "type" "test")
9131    (set_attr "modrm" "0,1,1")
9132    (set_attr "mode" "QI")
9133    (set_attr "pent_pair" "uv,np,uv")])
9134
9135 (define_expand "testqi_ext_ccno_0"
9136   [(set (reg:CCNO FLAGS_REG)
9137         (compare:CCNO
9138           (and:SI
9139             (zero_extract:SI
9140               (match_operand 0 "ext_register_operand" "")
9141               (const_int 8)
9142               (const_int 8))
9143             (match_operand 1 "const_int_operand" ""))
9144           (const_int 0)))]
9145   ""
9146   "")
9147
9148 (define_insn "*testqi_ext_0"
9149   [(set (reg FLAGS_REG)
9150         (compare
9151           (and:SI
9152             (zero_extract:SI
9153               (match_operand 0 "ext_register_operand" "Q")
9154               (const_int 8)
9155               (const_int 8))
9156             (match_operand 1 "const_int_operand" "n"))
9157           (const_int 0)))]
9158   "ix86_match_ccmode (insn, CCNOmode)"
9159   "test{b}\t{%1, %h0|%h0, %1}"
9160   [(set_attr "type" "test")
9161    (set_attr "mode" "QI")
9162    (set_attr "length_immediate" "1")
9163    (set_attr "pent_pair" "np")])
9164
9165 (define_insn "*testqi_ext_1"
9166   [(set (reg FLAGS_REG)
9167         (compare
9168           (and:SI
9169             (zero_extract:SI
9170               (match_operand 0 "ext_register_operand" "Q")
9171               (const_int 8)
9172               (const_int 8))
9173             (zero_extend:SI
9174               (match_operand:QI 1 "general_operand" "Qm")))
9175           (const_int 0)))]
9176   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9177    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9178   "test{b}\t{%1, %h0|%h0, %1}"
9179   [(set_attr "type" "test")
9180    (set_attr "mode" "QI")])
9181
9182 (define_insn "*testqi_ext_1_rex64"
9183   [(set (reg FLAGS_REG)
9184         (compare
9185           (and:SI
9186             (zero_extract:SI
9187               (match_operand 0 "ext_register_operand" "Q")
9188               (const_int 8)
9189               (const_int 8))
9190             (zero_extend:SI
9191               (match_operand:QI 1 "register_operand" "Q")))
9192           (const_int 0)))]
9193   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9194   "test{b}\t{%1, %h0|%h0, %1}"
9195   [(set_attr "type" "test")
9196    (set_attr "mode" "QI")])
9197
9198 (define_insn "*testqi_ext_2"
9199   [(set (reg FLAGS_REG)
9200         (compare
9201           (and:SI
9202             (zero_extract:SI
9203               (match_operand 0 "ext_register_operand" "Q")
9204               (const_int 8)
9205               (const_int 8))
9206             (zero_extract:SI
9207               (match_operand 1 "ext_register_operand" "Q")
9208               (const_int 8)
9209               (const_int 8)))
9210           (const_int 0)))]
9211   "ix86_match_ccmode (insn, CCNOmode)"
9212   "test{b}\t{%h1, %h0|%h0, %h1}"
9213   [(set_attr "type" "test")
9214    (set_attr "mode" "QI")])
9215
9216 ;; Combine likes to form bit extractions for some tests.  Humor it.
9217 (define_insn "*testqi_ext_3"
9218   [(set (reg FLAGS_REG)
9219         (compare (zero_extract:SI
9220                    (match_operand 0 "nonimmediate_operand" "rm")
9221                    (match_operand:SI 1 "const_int_operand" "")
9222                    (match_operand:SI 2 "const_int_operand" ""))
9223                  (const_int 0)))]
9224   "ix86_match_ccmode (insn, CCNOmode)
9225    && INTVAL (operands[1]) > 0
9226    && INTVAL (operands[2]) >= 0
9227    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9228    && (GET_MODE (operands[0]) == SImode
9229        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
9230        || GET_MODE (operands[0]) == HImode
9231        || GET_MODE (operands[0]) == QImode)"
9232   "#")
9233
9234 (define_insn "*testqi_ext_3_rex64"
9235   [(set (reg FLAGS_REG)
9236         (compare (zero_extract:DI
9237                    (match_operand 0 "nonimmediate_operand" "rm")
9238                    (match_operand:DI 1 "const_int_operand" "")
9239                    (match_operand:DI 2 "const_int_operand" ""))
9240                  (const_int 0)))]
9241   "TARGET_64BIT
9242    && ix86_match_ccmode (insn, CCNOmode)
9243    && INTVAL (operands[1]) > 0
9244    && INTVAL (operands[2]) >= 0
9245    /* Ensure that resulting mask is zero or sign extended operand.  */
9246    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9247        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9248            && INTVAL (operands[1]) > 32))
9249    && (GET_MODE (operands[0]) == SImode
9250        || GET_MODE (operands[0]) == DImode
9251        || GET_MODE (operands[0]) == HImode
9252        || GET_MODE (operands[0]) == QImode)"
9253   "#")
9254
9255 (define_split
9256   [(set (match_operand 0 "flags_reg_operand" "")
9257         (match_operator 1 "compare_operator"
9258           [(zero_extract
9259              (match_operand 2 "nonimmediate_operand" "")
9260              (match_operand 3 "const_int_operand" "")
9261              (match_operand 4 "const_int_operand" ""))
9262            (const_int 0)]))]
9263   "ix86_match_ccmode (insn, CCNOmode)"
9264   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9265 {
9266   rtx val = operands[2];
9267   HOST_WIDE_INT len = INTVAL (operands[3]);
9268   HOST_WIDE_INT pos = INTVAL (operands[4]);
9269   HOST_WIDE_INT mask;
9270   enum machine_mode mode, submode;
9271
9272   mode = GET_MODE (val);
9273   if (MEM_P (val))
9274     {
9275       /* ??? Combine likes to put non-volatile mem extractions in QImode
9276          no matter the size of the test.  So find a mode that works.  */
9277       if (! MEM_VOLATILE_P (val))
9278         {
9279           mode = smallest_mode_for_size (pos + len, MODE_INT);
9280           val = adjust_address (val, mode, 0);
9281         }
9282     }
9283   else if (GET_CODE (val) == SUBREG
9284            && (submode = GET_MODE (SUBREG_REG (val)),
9285                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9286            && pos + len <= GET_MODE_BITSIZE (submode))
9287     {
9288       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9289       mode = submode;
9290       val = SUBREG_REG (val);
9291     }
9292   else if (mode == HImode && pos + len <= 8)
9293     {
9294       /* Small HImode tests can be converted to QImode.  */
9295       mode = QImode;
9296       val = gen_lowpart (QImode, val);
9297     }
9298
9299   if (len == HOST_BITS_PER_WIDE_INT)
9300     mask = -1;
9301   else
9302     mask = ((HOST_WIDE_INT)1 << len) - 1;
9303   mask <<= pos;
9304
9305   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9306 })
9307
9308 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9309 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9310 ;; this is relatively important trick.
9311 ;; Do the conversion only post-reload to avoid limiting of the register class
9312 ;; to QI regs.
9313 (define_split
9314   [(set (match_operand 0 "flags_reg_operand" "")
9315         (match_operator 1 "compare_operator"
9316           [(and (match_operand 2 "register_operand" "")
9317                 (match_operand 3 "const_int_operand" ""))
9318            (const_int 0)]))]
9319    "reload_completed
9320     && QI_REG_P (operands[2])
9321     && GET_MODE (operands[2]) != QImode
9322     && ((ix86_match_ccmode (insn, CCZmode)
9323          && !(INTVAL (operands[3]) & ~(255 << 8)))
9324         || (ix86_match_ccmode (insn, CCNOmode)
9325             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9326   [(set (match_dup 0)
9327         (match_op_dup 1
9328           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9329                    (match_dup 3))
9330            (const_int 0)]))]
9331   "operands[2] = gen_lowpart (SImode, operands[2]);
9332    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9333
9334 (define_split
9335   [(set (match_operand 0 "flags_reg_operand" "")
9336         (match_operator 1 "compare_operator"
9337           [(and (match_operand 2 "nonimmediate_operand" "")
9338                 (match_operand 3 "const_int_operand" ""))
9339            (const_int 0)]))]
9340    "reload_completed
9341     && GET_MODE (operands[2]) != QImode
9342     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9343     && ((ix86_match_ccmode (insn, CCZmode)
9344          && !(INTVAL (operands[3]) & ~255))
9345         || (ix86_match_ccmode (insn, CCNOmode)
9346             && !(INTVAL (operands[3]) & ~127)))"
9347   [(set (match_dup 0)
9348         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9349                          (const_int 0)]))]
9350   "operands[2] = gen_lowpart (QImode, operands[2]);
9351    operands[3] = gen_lowpart (QImode, operands[3]);")
9352
9353
9354 ;; %%% This used to optimize known byte-wide and operations to memory,
9355 ;; and sometimes to QImode registers.  If this is considered useful,
9356 ;; it should be done with splitters.
9357
9358 (define_expand "anddi3"
9359   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9360         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9361                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9362   "TARGET_64BIT"
9363   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9364
9365 (define_insn "*anddi_1_rex64"
9366   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9367         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9368                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9369    (clobber (reg:CC FLAGS_REG))]
9370   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9371 {
9372   switch (get_attr_type (insn))
9373     {
9374     case TYPE_IMOVX:
9375       {
9376         enum machine_mode mode;
9377
9378         gcc_assert (CONST_INT_P (operands[2]));
9379         if (INTVAL (operands[2]) == 0xff)
9380           mode = QImode;
9381         else
9382           {
9383             gcc_assert (INTVAL (operands[2]) == 0xffff);
9384             mode = HImode;
9385           }
9386
9387         operands[1] = gen_lowpart (mode, operands[1]);
9388         if (mode == QImode)
9389           return "movz{bq|x}\t{%1,%0|%0, %1}";
9390         else
9391           return "movz{wq|x}\t{%1,%0|%0, %1}";
9392       }
9393
9394     default:
9395       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9396       if (get_attr_mode (insn) == MODE_SI)
9397         return "and{l}\t{%k2, %k0|%k0, %k2}";
9398       else
9399         return "and{q}\t{%2, %0|%0, %2}";
9400     }
9401 }
9402   [(set_attr "type" "alu,alu,alu,imovx")
9403    (set_attr "length_immediate" "*,*,*,0")
9404    (set_attr "mode" "SI,DI,DI,DI")])
9405
9406 (define_insn "*anddi_2"
9407   [(set (reg FLAGS_REG)
9408         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9409                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9410                  (const_int 0)))
9411    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9412         (and:DI (match_dup 1) (match_dup 2)))]
9413   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9414    && ix86_binary_operator_ok (AND, DImode, operands)"
9415   "@
9416    and{l}\t{%k2, %k0|%k0, %k2}
9417    and{q}\t{%2, %0|%0, %2}
9418    and{q}\t{%2, %0|%0, %2}"
9419   [(set_attr "type" "alu")
9420    (set_attr "mode" "SI,DI,DI")])
9421
9422 (define_expand "andsi3"
9423   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9424         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9425                 (match_operand:SI 2 "general_operand" "")))]
9426   ""
9427   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9428
9429 (define_insn "*andsi_1"
9430   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9431         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9432                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9433    (clobber (reg:CC FLAGS_REG))]
9434   "ix86_binary_operator_ok (AND, SImode, operands)"
9435 {
9436   switch (get_attr_type (insn))
9437     {
9438     case TYPE_IMOVX:
9439       {
9440         enum machine_mode mode;
9441
9442         gcc_assert (CONST_INT_P (operands[2]));
9443         if (INTVAL (operands[2]) == 0xff)
9444           mode = QImode;
9445         else
9446           {
9447             gcc_assert (INTVAL (operands[2]) == 0xffff);
9448             mode = HImode;
9449           }
9450
9451         operands[1] = gen_lowpart (mode, operands[1]);
9452         if (mode == QImode)
9453           return "movz{bl|x}\t{%1,%0|%0, %1}";
9454         else
9455           return "movz{wl|x}\t{%1,%0|%0, %1}";
9456       }
9457
9458     default:
9459       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9460       return "and{l}\t{%2, %0|%0, %2}";
9461     }
9462 }
9463   [(set_attr "type" "alu,alu,imovx")
9464    (set_attr "length_immediate" "*,*,0")
9465    (set_attr "mode" "SI")])
9466
9467 (define_split
9468   [(set (match_operand 0 "register_operand" "")
9469         (and (match_dup 0)
9470              (const_int -65536)))
9471    (clobber (reg:CC FLAGS_REG))]
9472   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9473   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9474   "operands[1] = gen_lowpart (HImode, operands[0]);")
9475
9476 (define_split
9477   [(set (match_operand 0 "ext_register_operand" "")
9478         (and (match_dup 0)
9479              (const_int -256)))
9480    (clobber (reg:CC FLAGS_REG))]
9481   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9482   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9483   "operands[1] = gen_lowpart (QImode, operands[0]);")
9484
9485 (define_split
9486   [(set (match_operand 0 "ext_register_operand" "")
9487         (and (match_dup 0)
9488              (const_int -65281)))
9489    (clobber (reg:CC FLAGS_REG))]
9490   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9491   [(parallel [(set (zero_extract:SI (match_dup 0)
9492                                     (const_int 8)
9493                                     (const_int 8))
9494                    (xor:SI
9495                      (zero_extract:SI (match_dup 0)
9496                                       (const_int 8)
9497                                       (const_int 8))
9498                      (zero_extract:SI (match_dup 0)
9499                                       (const_int 8)
9500                                       (const_int 8))))
9501               (clobber (reg:CC FLAGS_REG))])]
9502   "operands[0] = gen_lowpart (SImode, operands[0]);")
9503
9504 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9505 (define_insn "*andsi_1_zext"
9506   [(set (match_operand:DI 0 "register_operand" "=r")
9507         (zero_extend:DI
9508           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9509                   (match_operand:SI 2 "general_operand" "g"))))
9510    (clobber (reg:CC FLAGS_REG))]
9511   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9512   "and{l}\t{%2, %k0|%k0, %2}"
9513   [(set_attr "type" "alu")
9514    (set_attr "mode" "SI")])
9515
9516 (define_insn "*andsi_2"
9517   [(set (reg FLAGS_REG)
9518         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9519                          (match_operand:SI 2 "general_operand" "g,ri"))
9520                  (const_int 0)))
9521    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9522         (and:SI (match_dup 1) (match_dup 2)))]
9523   "ix86_match_ccmode (insn, CCNOmode)
9524    && ix86_binary_operator_ok (AND, SImode, operands)"
9525   "and{l}\t{%2, %0|%0, %2}"
9526   [(set_attr "type" "alu")
9527    (set_attr "mode" "SI")])
9528
9529 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9530 (define_insn "*andsi_2_zext"
9531   [(set (reg FLAGS_REG)
9532         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9533                          (match_operand:SI 2 "general_operand" "g"))
9534                  (const_int 0)))
9535    (set (match_operand:DI 0 "register_operand" "=r")
9536         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9537   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9538    && ix86_binary_operator_ok (AND, SImode, operands)"
9539   "and{l}\t{%2, %k0|%k0, %2}"
9540   [(set_attr "type" "alu")
9541    (set_attr "mode" "SI")])
9542
9543 (define_expand "andhi3"
9544   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9545         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9546                 (match_operand:HI 2 "general_operand" "")))]
9547   "TARGET_HIMODE_MATH"
9548   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9549
9550 (define_insn "*andhi_1"
9551   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9552         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9553                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9554    (clobber (reg:CC FLAGS_REG))]
9555   "ix86_binary_operator_ok (AND, HImode, operands)"
9556 {
9557   switch (get_attr_type (insn))
9558     {
9559     case TYPE_IMOVX:
9560       gcc_assert (CONST_INT_P (operands[2]));
9561       gcc_assert (INTVAL (operands[2]) == 0xff);
9562       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9563
9564     default:
9565       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9566
9567       return "and{w}\t{%2, %0|%0, %2}";
9568     }
9569 }
9570   [(set_attr "type" "alu,alu,imovx")
9571    (set_attr "length_immediate" "*,*,0")
9572    (set_attr "mode" "HI,HI,SI")])
9573
9574 (define_insn "*andhi_2"
9575   [(set (reg FLAGS_REG)
9576         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9577                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9578                  (const_int 0)))
9579    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9580         (and:HI (match_dup 1) (match_dup 2)))]
9581   "ix86_match_ccmode (insn, CCNOmode)
9582    && ix86_binary_operator_ok (AND, HImode, operands)"
9583   "and{w}\t{%2, %0|%0, %2}"
9584   [(set_attr "type" "alu")
9585    (set_attr "mode" "HI")])
9586
9587 (define_expand "andqi3"
9588   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9589         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9590                 (match_operand:QI 2 "general_operand" "")))]
9591   "TARGET_QIMODE_MATH"
9592   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9593
9594 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9595 (define_insn "*andqi_1"
9596   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9597         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9598                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9599    (clobber (reg:CC FLAGS_REG))]
9600   "ix86_binary_operator_ok (AND, QImode, operands)"
9601   "@
9602    and{b}\t{%2, %0|%0, %2}
9603    and{b}\t{%2, %0|%0, %2}
9604    and{l}\t{%k2, %k0|%k0, %k2}"
9605   [(set_attr "type" "alu")
9606    (set_attr "mode" "QI,QI,SI")])
9607
9608 (define_insn "*andqi_1_slp"
9609   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9610         (and:QI (match_dup 0)
9611                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9612    (clobber (reg:CC FLAGS_REG))]
9613   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9614    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9615   "and{b}\t{%1, %0|%0, %1}"
9616   [(set_attr "type" "alu1")
9617    (set_attr "mode" "QI")])
9618
9619 (define_insn "*andqi_2_maybe_si"
9620   [(set (reg FLAGS_REG)
9621         (compare (and:QI
9622                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9623                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9624                  (const_int 0)))
9625    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9626         (and:QI (match_dup 1) (match_dup 2)))]
9627   "ix86_binary_operator_ok (AND, QImode, operands)
9628    && ix86_match_ccmode (insn,
9629                          CONST_INT_P (operands[2])
9630                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9631 {
9632   if (which_alternative == 2)
9633     {
9634       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9635         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9636       return "and{l}\t{%2, %k0|%k0, %2}";
9637     }
9638   return "and{b}\t{%2, %0|%0, %2}";
9639 }
9640   [(set_attr "type" "alu")
9641    (set_attr "mode" "QI,QI,SI")])
9642
9643 (define_insn "*andqi_2"
9644   [(set (reg FLAGS_REG)
9645         (compare (and:QI
9646                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9647                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9648                  (const_int 0)))
9649    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9650         (and:QI (match_dup 1) (match_dup 2)))]
9651   "ix86_match_ccmode (insn, CCNOmode)
9652    && ix86_binary_operator_ok (AND, QImode, operands)"
9653   "and{b}\t{%2, %0|%0, %2}"
9654   [(set_attr "type" "alu")
9655    (set_attr "mode" "QI")])
9656
9657 (define_insn "*andqi_2_slp"
9658   [(set (reg FLAGS_REG)
9659         (compare (and:QI
9660                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9661                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9662                  (const_int 0)))
9663    (set (strict_low_part (match_dup 0))
9664         (and:QI (match_dup 0) (match_dup 1)))]
9665   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9666    && ix86_match_ccmode (insn, CCNOmode)
9667    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9668   "and{b}\t{%1, %0|%0, %1}"
9669   [(set_attr "type" "alu1")
9670    (set_attr "mode" "QI")])
9671
9672 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9673 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9674 ;; for a QImode operand, which of course failed.
9675
9676 (define_insn "andqi_ext_0"
9677   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9678                          (const_int 8)
9679                          (const_int 8))
9680         (and:SI
9681           (zero_extract:SI
9682             (match_operand 1 "ext_register_operand" "0")
9683             (const_int 8)
9684             (const_int 8))
9685           (match_operand 2 "const_int_operand" "n")))
9686    (clobber (reg:CC FLAGS_REG))]
9687   ""
9688   "and{b}\t{%2, %h0|%h0, %2}"
9689   [(set_attr "type" "alu")
9690    (set_attr "length_immediate" "1")
9691    (set_attr "mode" "QI")])
9692
9693 ;; Generated by peephole translating test to and.  This shows up
9694 ;; often in fp comparisons.
9695
9696 (define_insn "*andqi_ext_0_cc"
9697   [(set (reg FLAGS_REG)
9698         (compare
9699           (and:SI
9700             (zero_extract:SI
9701               (match_operand 1 "ext_register_operand" "0")
9702               (const_int 8)
9703               (const_int 8))
9704             (match_operand 2 "const_int_operand" "n"))
9705           (const_int 0)))
9706    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9707                          (const_int 8)
9708                          (const_int 8))
9709         (and:SI
9710           (zero_extract:SI
9711             (match_dup 1)
9712             (const_int 8)
9713             (const_int 8))
9714           (match_dup 2)))]
9715   "ix86_match_ccmode (insn, CCNOmode)"
9716   "and{b}\t{%2, %h0|%h0, %2}"
9717   [(set_attr "type" "alu")
9718    (set_attr "length_immediate" "1")
9719    (set_attr "mode" "QI")])
9720
9721 (define_insn "*andqi_ext_1"
9722   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9723                          (const_int 8)
9724                          (const_int 8))
9725         (and:SI
9726           (zero_extract:SI
9727             (match_operand 1 "ext_register_operand" "0")
9728             (const_int 8)
9729             (const_int 8))
9730           (zero_extend:SI
9731             (match_operand:QI 2 "general_operand" "Qm"))))
9732    (clobber (reg:CC FLAGS_REG))]
9733   "!TARGET_64BIT"
9734   "and{b}\t{%2, %h0|%h0, %2}"
9735   [(set_attr "type" "alu")
9736    (set_attr "length_immediate" "0")
9737    (set_attr "mode" "QI")])
9738
9739 (define_insn "*andqi_ext_1_rex64"
9740   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9741                          (const_int 8)
9742                          (const_int 8))
9743         (and:SI
9744           (zero_extract:SI
9745             (match_operand 1 "ext_register_operand" "0")
9746             (const_int 8)
9747             (const_int 8))
9748           (zero_extend:SI
9749             (match_operand 2 "ext_register_operand" "Q"))))
9750    (clobber (reg:CC FLAGS_REG))]
9751   "TARGET_64BIT"
9752   "and{b}\t{%2, %h0|%h0, %2}"
9753   [(set_attr "type" "alu")
9754    (set_attr "length_immediate" "0")
9755    (set_attr "mode" "QI")])
9756
9757 (define_insn "*andqi_ext_2"
9758   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9759                          (const_int 8)
9760                          (const_int 8))
9761         (and:SI
9762           (zero_extract:SI
9763             (match_operand 1 "ext_register_operand" "%0")
9764             (const_int 8)
9765             (const_int 8))
9766           (zero_extract:SI
9767             (match_operand 2 "ext_register_operand" "Q")
9768             (const_int 8)
9769             (const_int 8))))
9770    (clobber (reg:CC FLAGS_REG))]
9771   ""
9772   "and{b}\t{%h2, %h0|%h0, %h2}"
9773   [(set_attr "type" "alu")
9774    (set_attr "length_immediate" "0")
9775    (set_attr "mode" "QI")])
9776
9777 ;; Convert wide AND instructions with immediate operand to shorter QImode
9778 ;; equivalents when possible.
9779 ;; Don't do the splitting with memory operands, since it introduces risk
9780 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9781 ;; for size, but that can (should?) be handled by generic code instead.
9782 (define_split
9783   [(set (match_operand 0 "register_operand" "")
9784         (and (match_operand 1 "register_operand" "")
9785              (match_operand 2 "const_int_operand" "")))
9786    (clobber (reg:CC FLAGS_REG))]
9787    "reload_completed
9788     && QI_REG_P (operands[0])
9789     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9790     && !(~INTVAL (operands[2]) & ~(255 << 8))
9791     && GET_MODE (operands[0]) != QImode"
9792   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9793                    (and:SI (zero_extract:SI (match_dup 1)
9794                                             (const_int 8) (const_int 8))
9795                            (match_dup 2)))
9796               (clobber (reg:CC FLAGS_REG))])]
9797   "operands[0] = gen_lowpart (SImode, operands[0]);
9798    operands[1] = gen_lowpart (SImode, operands[1]);
9799    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9800
9801 ;; Since AND can be encoded with sign extended immediate, this is only
9802 ;; profitable when 7th bit is not set.
9803 (define_split
9804   [(set (match_operand 0 "register_operand" "")
9805         (and (match_operand 1 "general_operand" "")
9806              (match_operand 2 "const_int_operand" "")))
9807    (clobber (reg:CC FLAGS_REG))]
9808    "reload_completed
9809     && ANY_QI_REG_P (operands[0])
9810     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9811     && !(~INTVAL (operands[2]) & ~255)
9812     && !(INTVAL (operands[2]) & 128)
9813     && GET_MODE (operands[0]) != QImode"
9814   [(parallel [(set (strict_low_part (match_dup 0))
9815                    (and:QI (match_dup 1)
9816                            (match_dup 2)))
9817               (clobber (reg:CC FLAGS_REG))])]
9818   "operands[0] = gen_lowpart (QImode, operands[0]);
9819    operands[1] = gen_lowpart (QImode, operands[1]);
9820    operands[2] = gen_lowpart (QImode, operands[2]);")
9821 \f
9822 ;; Logical inclusive OR instructions
9823
9824 ;; %%% This used to optimize known byte-wide and operations to memory.
9825 ;; If this is considered useful, it should be done with splitters.
9826
9827 (define_expand "iordi3"
9828   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9829         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9830                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9831   "TARGET_64BIT"
9832   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9833
9834 (define_insn "*iordi_1_rex64"
9835   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9836         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9837                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9838    (clobber (reg:CC FLAGS_REG))]
9839   "TARGET_64BIT
9840    && ix86_binary_operator_ok (IOR, DImode, operands)"
9841   "or{q}\t{%2, %0|%0, %2}"
9842   [(set_attr "type" "alu")
9843    (set_attr "mode" "DI")])
9844
9845 (define_insn "*iordi_2_rex64"
9846   [(set (reg FLAGS_REG)
9847         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9848                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9849                  (const_int 0)))
9850    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9851         (ior:DI (match_dup 1) (match_dup 2)))]
9852   "TARGET_64BIT
9853    && ix86_match_ccmode (insn, CCNOmode)
9854    && ix86_binary_operator_ok (IOR, DImode, operands)"
9855   "or{q}\t{%2, %0|%0, %2}"
9856   [(set_attr "type" "alu")
9857    (set_attr "mode" "DI")])
9858
9859 (define_insn "*iordi_3_rex64"
9860   [(set (reg FLAGS_REG)
9861         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9862                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9863                  (const_int 0)))
9864    (clobber (match_scratch:DI 0 "=r"))]
9865   "TARGET_64BIT
9866    && ix86_match_ccmode (insn, CCNOmode)
9867    && ix86_binary_operator_ok (IOR, DImode, operands)"
9868   "or{q}\t{%2, %0|%0, %2}"
9869   [(set_attr "type" "alu")
9870    (set_attr "mode" "DI")])
9871
9872
9873 (define_expand "iorsi3"
9874   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9875         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9876                 (match_operand:SI 2 "general_operand" "")))]
9877   ""
9878   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9879
9880 (define_insn "*iorsi_1"
9881   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9882         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9883                 (match_operand:SI 2 "general_operand" "ri,g")))
9884    (clobber (reg:CC FLAGS_REG))]
9885   "ix86_binary_operator_ok (IOR, SImode, operands)"
9886   "or{l}\t{%2, %0|%0, %2}"
9887   [(set_attr "type" "alu")
9888    (set_attr "mode" "SI")])
9889
9890 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9891 (define_insn "*iorsi_1_zext"
9892   [(set (match_operand:DI 0 "register_operand" "=r")
9893         (zero_extend:DI
9894           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9895                   (match_operand:SI 2 "general_operand" "g"))))
9896    (clobber (reg:CC FLAGS_REG))]
9897   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9898   "or{l}\t{%2, %k0|%k0, %2}"
9899   [(set_attr "type" "alu")
9900    (set_attr "mode" "SI")])
9901
9902 (define_insn "*iorsi_1_zext_imm"
9903   [(set (match_operand:DI 0 "register_operand" "=r")
9904         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9905                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9906    (clobber (reg:CC FLAGS_REG))]
9907   "TARGET_64BIT"
9908   "or{l}\t{%2, %k0|%k0, %2}"
9909   [(set_attr "type" "alu")
9910    (set_attr "mode" "SI")])
9911
9912 (define_insn "*iorsi_2"
9913   [(set (reg FLAGS_REG)
9914         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9915                          (match_operand:SI 2 "general_operand" "g,ri"))
9916                  (const_int 0)))
9917    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9918         (ior:SI (match_dup 1) (match_dup 2)))]
9919   "ix86_match_ccmode (insn, CCNOmode)
9920    && ix86_binary_operator_ok (IOR, SImode, operands)"
9921   "or{l}\t{%2, %0|%0, %2}"
9922   [(set_attr "type" "alu")
9923    (set_attr "mode" "SI")])
9924
9925 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9926 ;; ??? Special case for immediate operand is missing - it is tricky.
9927 (define_insn "*iorsi_2_zext"
9928   [(set (reg FLAGS_REG)
9929         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9930                          (match_operand:SI 2 "general_operand" "g"))
9931                  (const_int 0)))
9932    (set (match_operand:DI 0 "register_operand" "=r")
9933         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9934   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9935    && ix86_binary_operator_ok (IOR, SImode, operands)"
9936   "or{l}\t{%2, %k0|%k0, %2}"
9937   [(set_attr "type" "alu")
9938    (set_attr "mode" "SI")])
9939
9940 (define_insn "*iorsi_2_zext_imm"
9941   [(set (reg FLAGS_REG)
9942         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9943                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9944                  (const_int 0)))
9945    (set (match_operand:DI 0 "register_operand" "=r")
9946         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9947   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9948    && ix86_binary_operator_ok (IOR, SImode, operands)"
9949   "or{l}\t{%2, %k0|%k0, %2}"
9950   [(set_attr "type" "alu")
9951    (set_attr "mode" "SI")])
9952
9953 (define_insn "*iorsi_3"
9954   [(set (reg FLAGS_REG)
9955         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9956                          (match_operand:SI 2 "general_operand" "g"))
9957                  (const_int 0)))
9958    (clobber (match_scratch:SI 0 "=r"))]
9959   "ix86_match_ccmode (insn, CCNOmode)
9960    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9961   "or{l}\t{%2, %0|%0, %2}"
9962   [(set_attr "type" "alu")
9963    (set_attr "mode" "SI")])
9964
9965 (define_expand "iorhi3"
9966   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9967         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9968                 (match_operand:HI 2 "general_operand" "")))]
9969   "TARGET_HIMODE_MATH"
9970   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9971
9972 (define_insn "*iorhi_1"
9973   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9974         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9975                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9976    (clobber (reg:CC FLAGS_REG))]
9977   "ix86_binary_operator_ok (IOR, HImode, operands)"
9978   "or{w}\t{%2, %0|%0, %2}"
9979   [(set_attr "type" "alu")
9980    (set_attr "mode" "HI")])
9981
9982 (define_insn "*iorhi_2"
9983   [(set (reg FLAGS_REG)
9984         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9985                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9986                  (const_int 0)))
9987    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9988         (ior:HI (match_dup 1) (match_dup 2)))]
9989   "ix86_match_ccmode (insn, CCNOmode)
9990    && ix86_binary_operator_ok (IOR, HImode, operands)"
9991   "or{w}\t{%2, %0|%0, %2}"
9992   [(set_attr "type" "alu")
9993    (set_attr "mode" "HI")])
9994
9995 (define_insn "*iorhi_3"
9996   [(set (reg FLAGS_REG)
9997         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9998                          (match_operand:HI 2 "general_operand" "rmn"))
9999                  (const_int 0)))
10000    (clobber (match_scratch:HI 0 "=r"))]
10001   "ix86_match_ccmode (insn, CCNOmode)
10002    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10003   "or{w}\t{%2, %0|%0, %2}"
10004   [(set_attr "type" "alu")
10005    (set_attr "mode" "HI")])
10006
10007 (define_expand "iorqi3"
10008   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10009         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
10010                 (match_operand:QI 2 "general_operand" "")))]
10011   "TARGET_QIMODE_MATH"
10012   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
10013
10014 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10015 (define_insn "*iorqi_1"
10016   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10017         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10018                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10019    (clobber (reg:CC FLAGS_REG))]
10020   "ix86_binary_operator_ok (IOR, QImode, operands)"
10021   "@
10022    or{b}\t{%2, %0|%0, %2}
10023    or{b}\t{%2, %0|%0, %2}
10024    or{l}\t{%k2, %k0|%k0, %k2}"
10025   [(set_attr "type" "alu")
10026    (set_attr "mode" "QI,QI,SI")])
10027
10028 (define_insn "*iorqi_1_slp"
10029   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
10030         (ior:QI (match_dup 0)
10031                 (match_operand:QI 1 "general_operand" "qmn,qn")))
10032    (clobber (reg:CC FLAGS_REG))]
10033   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10034    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10035   "or{b}\t{%1, %0|%0, %1}"
10036   [(set_attr "type" "alu1")
10037    (set_attr "mode" "QI")])
10038
10039 (define_insn "*iorqi_2"
10040   [(set (reg FLAGS_REG)
10041         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10042                          (match_operand:QI 2 "general_operand" "qmn,qn"))
10043                  (const_int 0)))
10044    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10045         (ior:QI (match_dup 1) (match_dup 2)))]
10046   "ix86_match_ccmode (insn, CCNOmode)
10047    && ix86_binary_operator_ok (IOR, QImode, operands)"
10048   "or{b}\t{%2, %0|%0, %2}"
10049   [(set_attr "type" "alu")
10050    (set_attr "mode" "QI")])
10051
10052 (define_insn "*iorqi_2_slp"
10053   [(set (reg FLAGS_REG)
10054         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10055                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10056                  (const_int 0)))
10057    (set (strict_low_part (match_dup 0))
10058         (ior:QI (match_dup 0) (match_dup 1)))]
10059   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10060    && ix86_match_ccmode (insn, CCNOmode)
10061    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10062   "or{b}\t{%1, %0|%0, %1}"
10063   [(set_attr "type" "alu1")
10064    (set_attr "mode" "QI")])
10065
10066 (define_insn "*iorqi_3"
10067   [(set (reg FLAGS_REG)
10068         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10069                          (match_operand:QI 2 "general_operand" "qmn"))
10070                  (const_int 0)))
10071    (clobber (match_scratch:QI 0 "=q"))]
10072   "ix86_match_ccmode (insn, CCNOmode)
10073    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10074   "or{b}\t{%2, %0|%0, %2}"
10075   [(set_attr "type" "alu")
10076    (set_attr "mode" "QI")])
10077
10078 (define_insn "*iorqi_ext_0"
10079   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10080                          (const_int 8)
10081                          (const_int 8))
10082         (ior:SI
10083           (zero_extract:SI
10084             (match_operand 1 "ext_register_operand" "0")
10085             (const_int 8)
10086             (const_int 8))
10087           (match_operand 2 "const_int_operand" "n")))
10088    (clobber (reg:CC FLAGS_REG))]
10089   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10090   "or{b}\t{%2, %h0|%h0, %2}"
10091   [(set_attr "type" "alu")
10092    (set_attr "length_immediate" "1")
10093    (set_attr "mode" "QI")])
10094
10095 (define_insn "*iorqi_ext_1"
10096   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10097                          (const_int 8)
10098                          (const_int 8))
10099         (ior:SI
10100           (zero_extract:SI
10101             (match_operand 1 "ext_register_operand" "0")
10102             (const_int 8)
10103             (const_int 8))
10104           (zero_extend:SI
10105             (match_operand:QI 2 "general_operand" "Qm"))))
10106    (clobber (reg:CC FLAGS_REG))]
10107   "!TARGET_64BIT
10108    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10109   "or{b}\t{%2, %h0|%h0, %2}"
10110   [(set_attr "type" "alu")
10111    (set_attr "length_immediate" "0")
10112    (set_attr "mode" "QI")])
10113
10114 (define_insn "*iorqi_ext_1_rex64"
10115   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10116                          (const_int 8)
10117                          (const_int 8))
10118         (ior:SI
10119           (zero_extract:SI
10120             (match_operand 1 "ext_register_operand" "0")
10121             (const_int 8)
10122             (const_int 8))
10123           (zero_extend:SI
10124             (match_operand 2 "ext_register_operand" "Q"))))
10125    (clobber (reg:CC FLAGS_REG))]
10126   "TARGET_64BIT
10127    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10128   "or{b}\t{%2, %h0|%h0, %2}"
10129   [(set_attr "type" "alu")
10130    (set_attr "length_immediate" "0")
10131    (set_attr "mode" "QI")])
10132
10133 (define_insn "*iorqi_ext_2"
10134   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10135                          (const_int 8)
10136                          (const_int 8))
10137         (ior:SI
10138           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10139                            (const_int 8)
10140                            (const_int 8))
10141           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10142                            (const_int 8)
10143                            (const_int 8))))
10144    (clobber (reg:CC FLAGS_REG))]
10145   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10146   "ior{b}\t{%h2, %h0|%h0, %h2}"
10147   [(set_attr "type" "alu")
10148    (set_attr "length_immediate" "0")
10149    (set_attr "mode" "QI")])
10150
10151 (define_split
10152   [(set (match_operand 0 "register_operand" "")
10153         (ior (match_operand 1 "register_operand" "")
10154              (match_operand 2 "const_int_operand" "")))
10155    (clobber (reg:CC FLAGS_REG))]
10156    "reload_completed
10157     && QI_REG_P (operands[0])
10158     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10159     && !(INTVAL (operands[2]) & ~(255 << 8))
10160     && GET_MODE (operands[0]) != QImode"
10161   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10162                    (ior:SI (zero_extract:SI (match_dup 1)
10163                                             (const_int 8) (const_int 8))
10164                            (match_dup 2)))
10165               (clobber (reg:CC FLAGS_REG))])]
10166   "operands[0] = gen_lowpart (SImode, operands[0]);
10167    operands[1] = gen_lowpart (SImode, operands[1]);
10168    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10169
10170 ;; Since OR can be encoded with sign extended immediate, this is only
10171 ;; profitable when 7th bit is set.
10172 (define_split
10173   [(set (match_operand 0 "register_operand" "")
10174         (ior (match_operand 1 "general_operand" "")
10175              (match_operand 2 "const_int_operand" "")))
10176    (clobber (reg:CC FLAGS_REG))]
10177    "reload_completed
10178     && ANY_QI_REG_P (operands[0])
10179     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10180     && !(INTVAL (operands[2]) & ~255)
10181     && (INTVAL (operands[2]) & 128)
10182     && GET_MODE (operands[0]) != QImode"
10183   [(parallel [(set (strict_low_part (match_dup 0))
10184                    (ior:QI (match_dup 1)
10185                            (match_dup 2)))
10186               (clobber (reg:CC FLAGS_REG))])]
10187   "operands[0] = gen_lowpart (QImode, operands[0]);
10188    operands[1] = gen_lowpart (QImode, operands[1]);
10189    operands[2] = gen_lowpart (QImode, operands[2]);")
10190 \f
10191 ;; Logical XOR instructions
10192
10193 ;; %%% This used to optimize known byte-wide and operations to memory.
10194 ;; If this is considered useful, it should be done with splitters.
10195
10196 (define_expand "xordi3"
10197   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10198         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
10199                 (match_operand:DI 2 "x86_64_general_operand" "")))]
10200   "TARGET_64BIT"
10201   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
10202
10203 (define_insn "*xordi_1_rex64"
10204   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10205         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10206                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
10207    (clobber (reg:CC FLAGS_REG))]
10208   "TARGET_64BIT
10209    && ix86_binary_operator_ok (XOR, DImode, operands)"
10210   "xor{q}\t{%2, %0|%0, %2}"
10211   [(set_attr "type" "alu")
10212    (set_attr "mode" "DI")])
10213
10214 (define_insn "*xordi_2_rex64"
10215   [(set (reg FLAGS_REG)
10216         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10217                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10218                  (const_int 0)))
10219    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10220         (xor:DI (match_dup 1) (match_dup 2)))]
10221   "TARGET_64BIT
10222    && ix86_match_ccmode (insn, CCNOmode)
10223    && ix86_binary_operator_ok (XOR, DImode, operands)"
10224   "xor{q}\t{%2, %0|%0, %2}"
10225   [(set_attr "type" "alu")
10226    (set_attr "mode" "DI")])
10227
10228 (define_insn "*xordi_3_rex64"
10229   [(set (reg FLAGS_REG)
10230         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10231                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
10232                  (const_int 0)))
10233    (clobber (match_scratch:DI 0 "=r"))]
10234   "TARGET_64BIT
10235    && ix86_match_ccmode (insn, CCNOmode)
10236    && ix86_binary_operator_ok (XOR, DImode, operands)"
10237   "xor{q}\t{%2, %0|%0, %2}"
10238   [(set_attr "type" "alu")
10239    (set_attr "mode" "DI")])
10240
10241 (define_expand "xorsi3"
10242   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10243         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10244                 (match_operand:SI 2 "general_operand" "")))]
10245   ""
10246   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10247
10248 (define_insn "*xorsi_1"
10249   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10250         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10251                 (match_operand:SI 2 "general_operand" "ri,rm")))
10252    (clobber (reg:CC FLAGS_REG))]
10253   "ix86_binary_operator_ok (XOR, SImode, operands)"
10254   "xor{l}\t{%2, %0|%0, %2}"
10255   [(set_attr "type" "alu")
10256    (set_attr "mode" "SI")])
10257
10258 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10259 ;; Add speccase for immediates
10260 (define_insn "*xorsi_1_zext"
10261   [(set (match_operand:DI 0 "register_operand" "=r")
10262         (zero_extend:DI
10263           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10264                   (match_operand:SI 2 "general_operand" "g"))))
10265    (clobber (reg:CC FLAGS_REG))]
10266   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10267   "xor{l}\t{%2, %k0|%k0, %2}"
10268   [(set_attr "type" "alu")
10269    (set_attr "mode" "SI")])
10270
10271 (define_insn "*xorsi_1_zext_imm"
10272   [(set (match_operand:DI 0 "register_operand" "=r")
10273         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10274                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10275    (clobber (reg:CC FLAGS_REG))]
10276   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10277   "xor{l}\t{%2, %k0|%k0, %2}"
10278   [(set_attr "type" "alu")
10279    (set_attr "mode" "SI")])
10280
10281 (define_insn "*xorsi_2"
10282   [(set (reg FLAGS_REG)
10283         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10284                          (match_operand:SI 2 "general_operand" "g,ri"))
10285                  (const_int 0)))
10286    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10287         (xor:SI (match_dup 1) (match_dup 2)))]
10288   "ix86_match_ccmode (insn, CCNOmode)
10289    && ix86_binary_operator_ok (XOR, SImode, operands)"
10290   "xor{l}\t{%2, %0|%0, %2}"
10291   [(set_attr "type" "alu")
10292    (set_attr "mode" "SI")])
10293
10294 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10295 ;; ??? Special case for immediate operand is missing - it is tricky.
10296 (define_insn "*xorsi_2_zext"
10297   [(set (reg FLAGS_REG)
10298         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10299                          (match_operand:SI 2 "general_operand" "g"))
10300                  (const_int 0)))
10301    (set (match_operand:DI 0 "register_operand" "=r")
10302         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10303   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10304    && ix86_binary_operator_ok (XOR, SImode, operands)"
10305   "xor{l}\t{%2, %k0|%k0, %2}"
10306   [(set_attr "type" "alu")
10307    (set_attr "mode" "SI")])
10308
10309 (define_insn "*xorsi_2_zext_imm"
10310   [(set (reg FLAGS_REG)
10311         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10312                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10313                  (const_int 0)))
10314    (set (match_operand:DI 0 "register_operand" "=r")
10315         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10316   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10317    && ix86_binary_operator_ok (XOR, SImode, operands)"
10318   "xor{l}\t{%2, %k0|%k0, %2}"
10319   [(set_attr "type" "alu")
10320    (set_attr "mode" "SI")])
10321
10322 (define_insn "*xorsi_3"
10323   [(set (reg FLAGS_REG)
10324         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10325                          (match_operand:SI 2 "general_operand" "g"))
10326                  (const_int 0)))
10327    (clobber (match_scratch:SI 0 "=r"))]
10328   "ix86_match_ccmode (insn, CCNOmode)
10329    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10330   "xor{l}\t{%2, %0|%0, %2}"
10331   [(set_attr "type" "alu")
10332    (set_attr "mode" "SI")])
10333
10334 (define_expand "xorhi3"
10335   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10336         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10337                 (match_operand:HI 2 "general_operand" "")))]
10338   "TARGET_HIMODE_MATH"
10339   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10340
10341 (define_insn "*xorhi_1"
10342   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10343         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10344                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10345    (clobber (reg:CC FLAGS_REG))]
10346   "ix86_binary_operator_ok (XOR, HImode, operands)"
10347   "xor{w}\t{%2, %0|%0, %2}"
10348   [(set_attr "type" "alu")
10349    (set_attr "mode" "HI")])
10350
10351 (define_insn "*xorhi_2"
10352   [(set (reg FLAGS_REG)
10353         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10354                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10355                  (const_int 0)))
10356    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10357         (xor:HI (match_dup 1) (match_dup 2)))]
10358   "ix86_match_ccmode (insn, CCNOmode)
10359    && ix86_binary_operator_ok (XOR, HImode, operands)"
10360   "xor{w}\t{%2, %0|%0, %2}"
10361   [(set_attr "type" "alu")
10362    (set_attr "mode" "HI")])
10363
10364 (define_insn "*xorhi_3"
10365   [(set (reg FLAGS_REG)
10366         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10367                          (match_operand:HI 2 "general_operand" "rmn"))
10368                  (const_int 0)))
10369    (clobber (match_scratch:HI 0 "=r"))]
10370   "ix86_match_ccmode (insn, CCNOmode)
10371    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10372   "xor{w}\t{%2, %0|%0, %2}"
10373   [(set_attr "type" "alu")
10374    (set_attr "mode" "HI")])
10375
10376 (define_expand "xorqi3"
10377   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10378         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10379                 (match_operand:QI 2 "general_operand" "")))]
10380   "TARGET_QIMODE_MATH"
10381   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10382
10383 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10384 (define_insn "*xorqi_1"
10385   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10386         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10387                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10388    (clobber (reg:CC FLAGS_REG))]
10389   "ix86_binary_operator_ok (XOR, QImode, operands)"
10390   "@
10391    xor{b}\t{%2, %0|%0, %2}
10392    xor{b}\t{%2, %0|%0, %2}
10393    xor{l}\t{%k2, %k0|%k0, %k2}"
10394   [(set_attr "type" "alu")
10395    (set_attr "mode" "QI,QI,SI")])
10396
10397 (define_insn "*xorqi_1_slp"
10398   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10399         (xor:QI (match_dup 0)
10400                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10401    (clobber (reg:CC FLAGS_REG))]
10402   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10403    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10404   "xor{b}\t{%1, %0|%0, %1}"
10405   [(set_attr "type" "alu1")
10406    (set_attr "mode" "QI")])
10407
10408 (define_insn "*xorqi_ext_0"
10409   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10410                          (const_int 8)
10411                          (const_int 8))
10412         (xor:SI
10413           (zero_extract:SI
10414             (match_operand 1 "ext_register_operand" "0")
10415             (const_int 8)
10416             (const_int 8))
10417           (match_operand 2 "const_int_operand" "n")))
10418    (clobber (reg:CC FLAGS_REG))]
10419   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10420   "xor{b}\t{%2, %h0|%h0, %2}"
10421   [(set_attr "type" "alu")
10422    (set_attr "length_immediate" "1")
10423    (set_attr "mode" "QI")])
10424
10425 (define_insn "*xorqi_ext_1"
10426   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10427                          (const_int 8)
10428                          (const_int 8))
10429         (xor:SI
10430           (zero_extract:SI
10431             (match_operand 1 "ext_register_operand" "0")
10432             (const_int 8)
10433             (const_int 8))
10434           (zero_extend:SI
10435             (match_operand:QI 2 "general_operand" "Qm"))))
10436    (clobber (reg:CC FLAGS_REG))]
10437   "!TARGET_64BIT
10438    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10439   "xor{b}\t{%2, %h0|%h0, %2}"
10440   [(set_attr "type" "alu")
10441    (set_attr "length_immediate" "0")
10442    (set_attr "mode" "QI")])
10443
10444 (define_insn "*xorqi_ext_1_rex64"
10445   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10446                          (const_int 8)
10447                          (const_int 8))
10448         (xor:SI
10449           (zero_extract:SI
10450             (match_operand 1 "ext_register_operand" "0")
10451             (const_int 8)
10452             (const_int 8))
10453           (zero_extend:SI
10454             (match_operand 2 "ext_register_operand" "Q"))))
10455    (clobber (reg:CC FLAGS_REG))]
10456   "TARGET_64BIT
10457    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10458   "xor{b}\t{%2, %h0|%h0, %2}"
10459   [(set_attr "type" "alu")
10460    (set_attr "length_immediate" "0")
10461    (set_attr "mode" "QI")])
10462
10463 (define_insn "*xorqi_ext_2"
10464   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10465                          (const_int 8)
10466                          (const_int 8))
10467         (xor:SI
10468           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10469                            (const_int 8)
10470                            (const_int 8))
10471           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10472                            (const_int 8)
10473                            (const_int 8))))
10474    (clobber (reg:CC FLAGS_REG))]
10475   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10476   "xor{b}\t{%h2, %h0|%h0, %h2}"
10477   [(set_attr "type" "alu")
10478    (set_attr "length_immediate" "0")
10479    (set_attr "mode" "QI")])
10480
10481 (define_insn "*xorqi_cc_1"
10482   [(set (reg FLAGS_REG)
10483         (compare
10484           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10485                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10486           (const_int 0)))
10487    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10488         (xor:QI (match_dup 1) (match_dup 2)))]
10489   "ix86_match_ccmode (insn, CCNOmode)
10490    && ix86_binary_operator_ok (XOR, QImode, operands)"
10491   "xor{b}\t{%2, %0|%0, %2}"
10492   [(set_attr "type" "alu")
10493    (set_attr "mode" "QI")])
10494
10495 (define_insn "*xorqi_2_slp"
10496   [(set (reg FLAGS_REG)
10497         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10498                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10499                  (const_int 0)))
10500    (set (strict_low_part (match_dup 0))
10501         (xor:QI (match_dup 0) (match_dup 1)))]
10502   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10503    && ix86_match_ccmode (insn, CCNOmode)
10504    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10505   "xor{b}\t{%1, %0|%0, %1}"
10506   [(set_attr "type" "alu1")
10507    (set_attr "mode" "QI")])
10508
10509 (define_insn "*xorqi_cc_2"
10510   [(set (reg FLAGS_REG)
10511         (compare
10512           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10513                   (match_operand:QI 2 "general_operand" "qmn"))
10514           (const_int 0)))
10515    (clobber (match_scratch:QI 0 "=q"))]
10516   "ix86_match_ccmode (insn, CCNOmode)
10517    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10518   "xor{b}\t{%2, %0|%0, %2}"
10519   [(set_attr "type" "alu")
10520    (set_attr "mode" "QI")])
10521
10522 (define_insn "*xorqi_cc_ext_1"
10523   [(set (reg FLAGS_REG)
10524         (compare
10525           (xor:SI
10526             (zero_extract:SI
10527               (match_operand 1 "ext_register_operand" "0")
10528               (const_int 8)
10529               (const_int 8))
10530             (match_operand:QI 2 "general_operand" "qmn"))
10531           (const_int 0)))
10532    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10533                          (const_int 8)
10534                          (const_int 8))
10535         (xor:SI
10536           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10537           (match_dup 2)))]
10538   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10539   "xor{b}\t{%2, %h0|%h0, %2}"
10540   [(set_attr "type" "alu")
10541    (set_attr "mode" "QI")])
10542
10543 (define_insn "*xorqi_cc_ext_1_rex64"
10544   [(set (reg FLAGS_REG)
10545         (compare
10546           (xor:SI
10547             (zero_extract:SI
10548               (match_operand 1 "ext_register_operand" "0")
10549               (const_int 8)
10550               (const_int 8))
10551             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10552           (const_int 0)))
10553    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10554                          (const_int 8)
10555                          (const_int 8))
10556         (xor:SI
10557           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10558           (match_dup 2)))]
10559   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10560   "xor{b}\t{%2, %h0|%h0, %2}"
10561   [(set_attr "type" "alu")
10562    (set_attr "mode" "QI")])
10563
10564 (define_expand "xorqi_cc_ext_1"
10565   [(parallel [
10566      (set (reg:CCNO FLAGS_REG)
10567           (compare:CCNO
10568             (xor:SI
10569               (zero_extract:SI
10570                 (match_operand 1 "ext_register_operand" "")
10571                 (const_int 8)
10572                 (const_int 8))
10573               (match_operand:QI 2 "general_operand" ""))
10574             (const_int 0)))
10575      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10576                            (const_int 8)
10577                            (const_int 8))
10578           (xor:SI
10579             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10580             (match_dup 2)))])]
10581   ""
10582   "")
10583
10584 (define_split
10585   [(set (match_operand 0 "register_operand" "")
10586         (xor (match_operand 1 "register_operand" "")
10587              (match_operand 2 "const_int_operand" "")))
10588    (clobber (reg:CC FLAGS_REG))]
10589    "reload_completed
10590     && QI_REG_P (operands[0])
10591     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10592     && !(INTVAL (operands[2]) & ~(255 << 8))
10593     && GET_MODE (operands[0]) != QImode"
10594   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10595                    (xor:SI (zero_extract:SI (match_dup 1)
10596                                             (const_int 8) (const_int 8))
10597                            (match_dup 2)))
10598               (clobber (reg:CC FLAGS_REG))])]
10599   "operands[0] = gen_lowpart (SImode, operands[0]);
10600    operands[1] = gen_lowpart (SImode, operands[1]);
10601    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10602
10603 ;; Since XOR can be encoded with sign extended immediate, this is only
10604 ;; profitable when 7th bit is set.
10605 (define_split
10606   [(set (match_operand 0 "register_operand" "")
10607         (xor (match_operand 1 "general_operand" "")
10608              (match_operand 2 "const_int_operand" "")))
10609    (clobber (reg:CC FLAGS_REG))]
10610    "reload_completed
10611     && ANY_QI_REG_P (operands[0])
10612     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10613     && !(INTVAL (operands[2]) & ~255)
10614     && (INTVAL (operands[2]) & 128)
10615     && GET_MODE (operands[0]) != QImode"
10616   [(parallel [(set (strict_low_part (match_dup 0))
10617                    (xor:QI (match_dup 1)
10618                            (match_dup 2)))
10619               (clobber (reg:CC FLAGS_REG))])]
10620   "operands[0] = gen_lowpart (QImode, operands[0]);
10621    operands[1] = gen_lowpart (QImode, operands[1]);
10622    operands[2] = gen_lowpart (QImode, operands[2]);")
10623 \f
10624 ;; Negation instructions
10625
10626 (define_expand "negti2"
10627   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10628         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10629   "TARGET_64BIT"
10630   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10631
10632 (define_insn "*negti2_1"
10633   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10634         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10635    (clobber (reg:CC FLAGS_REG))]
10636   "TARGET_64BIT
10637    && ix86_unary_operator_ok (NEG, TImode, operands)"
10638   "#")
10639
10640 (define_split
10641   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10642         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10643    (clobber (reg:CC FLAGS_REG))]
10644   "TARGET_64BIT && reload_completed"
10645   [(parallel
10646     [(set (reg:CCZ FLAGS_REG)
10647           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10648      (set (match_dup 0) (neg:DI (match_dup 1)))])
10649    (parallel
10650     [(set (match_dup 2)
10651           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10652                             (match_dup 3))
10653                    (const_int 0)))
10654      (clobber (reg:CC FLAGS_REG))])
10655    (parallel
10656     [(set (match_dup 2)
10657           (neg:DI (match_dup 2)))
10658      (clobber (reg:CC FLAGS_REG))])]
10659   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10660
10661 (define_expand "negdi2"
10662   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10663         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10664   ""
10665   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10666
10667 (define_insn "*negdi2_1"
10668   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10669         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10670    (clobber (reg:CC FLAGS_REG))]
10671   "!TARGET_64BIT
10672    && ix86_unary_operator_ok (NEG, DImode, operands)"
10673   "#")
10674
10675 (define_split
10676   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10677         (neg:DI (match_operand:DI 1 "general_operand" "")))
10678    (clobber (reg:CC FLAGS_REG))]
10679   "!TARGET_64BIT && reload_completed"
10680   [(parallel
10681     [(set (reg:CCZ FLAGS_REG)
10682           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10683      (set (match_dup 0) (neg:SI (match_dup 1)))])
10684    (parallel
10685     [(set (match_dup 2)
10686           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10687                             (match_dup 3))
10688                    (const_int 0)))
10689      (clobber (reg:CC FLAGS_REG))])
10690    (parallel
10691     [(set (match_dup 2)
10692           (neg:SI (match_dup 2)))
10693      (clobber (reg:CC FLAGS_REG))])]
10694   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10695
10696 (define_insn "*negdi2_1_rex64"
10697   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10698         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10699    (clobber (reg:CC FLAGS_REG))]
10700   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10701   "neg{q}\t%0"
10702   [(set_attr "type" "negnot")
10703    (set_attr "mode" "DI")])
10704
10705 ;; The problem with neg is that it does not perform (compare x 0),
10706 ;; it really performs (compare 0 x), which leaves us with the zero
10707 ;; flag being the only useful item.
10708
10709 (define_insn "*negdi2_cmpz_rex64"
10710   [(set (reg:CCZ FLAGS_REG)
10711         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10712                      (const_int 0)))
10713    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10714         (neg:DI (match_dup 1)))]
10715   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10716   "neg{q}\t%0"
10717   [(set_attr "type" "negnot")
10718    (set_attr "mode" "DI")])
10719
10720
10721 (define_expand "negsi2"
10722   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10723         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10724   ""
10725   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10726
10727 (define_insn "*negsi2_1"
10728   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10729         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10730    (clobber (reg:CC FLAGS_REG))]
10731   "ix86_unary_operator_ok (NEG, SImode, operands)"
10732   "neg{l}\t%0"
10733   [(set_attr "type" "negnot")
10734    (set_attr "mode" "SI")])
10735
10736 ;; Combine is quite creative about this pattern.
10737 (define_insn "*negsi2_1_zext"
10738   [(set (match_operand:DI 0 "register_operand" "=r")
10739         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10740                                         (const_int 32)))
10741                      (const_int 32)))
10742    (clobber (reg:CC FLAGS_REG))]
10743   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10744   "neg{l}\t%k0"
10745   [(set_attr "type" "negnot")
10746    (set_attr "mode" "SI")])
10747
10748 ;; The problem with neg is that it does not perform (compare x 0),
10749 ;; it really performs (compare 0 x), which leaves us with the zero
10750 ;; flag being the only useful item.
10751
10752 (define_insn "*negsi2_cmpz"
10753   [(set (reg:CCZ FLAGS_REG)
10754         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10755                      (const_int 0)))
10756    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10757         (neg:SI (match_dup 1)))]
10758   "ix86_unary_operator_ok (NEG, SImode, operands)"
10759   "neg{l}\t%0"
10760   [(set_attr "type" "negnot")
10761    (set_attr "mode" "SI")])
10762
10763 (define_insn "*negsi2_cmpz_zext"
10764   [(set (reg:CCZ FLAGS_REG)
10765         (compare:CCZ (lshiftrt:DI
10766                        (neg:DI (ashift:DI
10767                                  (match_operand:DI 1 "register_operand" "0")
10768                                  (const_int 32)))
10769                        (const_int 32))
10770                      (const_int 0)))
10771    (set (match_operand:DI 0 "register_operand" "=r")
10772         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10773                                         (const_int 32)))
10774                      (const_int 32)))]
10775   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10776   "neg{l}\t%k0"
10777   [(set_attr "type" "negnot")
10778    (set_attr "mode" "SI")])
10779
10780 (define_expand "neghi2"
10781   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10782         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10783   "TARGET_HIMODE_MATH"
10784   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10785
10786 (define_insn "*neghi2_1"
10787   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10788         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10789    (clobber (reg:CC FLAGS_REG))]
10790   "ix86_unary_operator_ok (NEG, HImode, operands)"
10791   "neg{w}\t%0"
10792   [(set_attr "type" "negnot")
10793    (set_attr "mode" "HI")])
10794
10795 (define_insn "*neghi2_cmpz"
10796   [(set (reg:CCZ FLAGS_REG)
10797         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10798                      (const_int 0)))
10799    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10800         (neg:HI (match_dup 1)))]
10801   "ix86_unary_operator_ok (NEG, HImode, operands)"
10802   "neg{w}\t%0"
10803   [(set_attr "type" "negnot")
10804    (set_attr "mode" "HI")])
10805
10806 (define_expand "negqi2"
10807   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10808         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10809   "TARGET_QIMODE_MATH"
10810   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10811
10812 (define_insn "*negqi2_1"
10813   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10814         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10815    (clobber (reg:CC FLAGS_REG))]
10816   "ix86_unary_operator_ok (NEG, QImode, operands)"
10817   "neg{b}\t%0"
10818   [(set_attr "type" "negnot")
10819    (set_attr "mode" "QI")])
10820
10821 (define_insn "*negqi2_cmpz"
10822   [(set (reg:CCZ FLAGS_REG)
10823         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10824                      (const_int 0)))
10825    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10826         (neg:QI (match_dup 1)))]
10827   "ix86_unary_operator_ok (NEG, QImode, operands)"
10828   "neg{b}\t%0"
10829   [(set_attr "type" "negnot")
10830    (set_attr "mode" "QI")])
10831
10832 ;; Changing of sign for FP values is doable using integer unit too.
10833
10834 (define_expand "<code><mode>2"
10835   [(set (match_operand:X87MODEF 0 "register_operand" "")
10836         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10837   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10838   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10839
10840 (define_insn "*absneg<mode>2_mixed"
10841   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10842         (match_operator:MODEF 3 "absneg_operator"
10843           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10844    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10845    (clobber (reg:CC FLAGS_REG))]
10846   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10847   "#")
10848
10849 (define_insn "*absneg<mode>2_sse"
10850   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10851         (match_operator:MODEF 3 "absneg_operator"
10852           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10853    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10854    (clobber (reg:CC FLAGS_REG))]
10855   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10856   "#")
10857
10858 (define_insn "*absneg<mode>2_i387"
10859   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10860         (match_operator:X87MODEF 3 "absneg_operator"
10861           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10862    (use (match_operand 2 "" ""))
10863    (clobber (reg:CC FLAGS_REG))]
10864   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10865   "#")
10866
10867 (define_expand "<code>tf2"
10868   [(set (match_operand:TF 0 "register_operand" "")
10869         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10870   "TARGET_SSE2"
10871   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10872
10873 (define_insn "*absnegtf2_sse"
10874   [(set (match_operand:TF 0 "register_operand" "=x,x")
10875         (match_operator:TF 3 "absneg_operator"
10876           [(match_operand:TF 1 "register_operand" "0,x")]))
10877    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10878    (clobber (reg:CC FLAGS_REG))]
10879   "TARGET_SSE2"
10880   "#")
10881
10882 ;; Splitters for fp abs and neg.
10883
10884 (define_split
10885   [(set (match_operand 0 "fp_register_operand" "")
10886         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10887    (use (match_operand 2 "" ""))
10888    (clobber (reg:CC FLAGS_REG))]
10889   "reload_completed"
10890   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10891
10892 (define_split
10893   [(set (match_operand 0 "register_operand" "")
10894         (match_operator 3 "absneg_operator"
10895           [(match_operand 1 "register_operand" "")]))
10896    (use (match_operand 2 "nonimmediate_operand" ""))
10897    (clobber (reg:CC FLAGS_REG))]
10898   "reload_completed && SSE_REG_P (operands[0])"
10899   [(set (match_dup 0) (match_dup 3))]
10900 {
10901   enum machine_mode mode = GET_MODE (operands[0]);
10902   enum machine_mode vmode = GET_MODE (operands[2]);
10903   rtx tmp;
10904
10905   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10906   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10907   if (operands_match_p (operands[0], operands[2]))
10908     {
10909       tmp = operands[1];
10910       operands[1] = operands[2];
10911       operands[2] = tmp;
10912     }
10913   if (GET_CODE (operands[3]) == ABS)
10914     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10915   else
10916     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10917   operands[3] = tmp;
10918 })
10919
10920 (define_split
10921   [(set (match_operand:SF 0 "register_operand" "")
10922         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10923    (use (match_operand:V4SF 2 "" ""))
10924    (clobber (reg:CC FLAGS_REG))]
10925   "reload_completed"
10926   [(parallel [(set (match_dup 0) (match_dup 1))
10927               (clobber (reg:CC FLAGS_REG))])]
10928 {
10929   rtx tmp;
10930   operands[0] = gen_lowpart (SImode, operands[0]);
10931   if (GET_CODE (operands[1]) == ABS)
10932     {
10933       tmp = gen_int_mode (0x7fffffff, SImode);
10934       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10935     }
10936   else
10937     {
10938       tmp = gen_int_mode (0x80000000, SImode);
10939       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10940     }
10941   operands[1] = tmp;
10942 })
10943
10944 (define_split
10945   [(set (match_operand:DF 0 "register_operand" "")
10946         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10947    (use (match_operand 2 "" ""))
10948    (clobber (reg:CC FLAGS_REG))]
10949   "reload_completed"
10950   [(parallel [(set (match_dup 0) (match_dup 1))
10951               (clobber (reg:CC FLAGS_REG))])]
10952 {
10953   rtx tmp;
10954   if (TARGET_64BIT)
10955     {
10956       tmp = gen_lowpart (DImode, operands[0]);
10957       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10958       operands[0] = tmp;
10959
10960       if (GET_CODE (operands[1]) == ABS)
10961         tmp = const0_rtx;
10962       else
10963         tmp = gen_rtx_NOT (DImode, tmp);
10964     }
10965   else
10966     {
10967       operands[0] = gen_highpart (SImode, operands[0]);
10968       if (GET_CODE (operands[1]) == ABS)
10969         {
10970           tmp = gen_int_mode (0x7fffffff, SImode);
10971           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10972         }
10973       else
10974         {
10975           tmp = gen_int_mode (0x80000000, SImode);
10976           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10977         }
10978     }
10979   operands[1] = tmp;
10980 })
10981
10982 (define_split
10983   [(set (match_operand:XF 0 "register_operand" "")
10984         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10985    (use (match_operand 2 "" ""))
10986    (clobber (reg:CC FLAGS_REG))]
10987   "reload_completed"
10988   [(parallel [(set (match_dup 0) (match_dup 1))
10989               (clobber (reg:CC FLAGS_REG))])]
10990 {
10991   rtx tmp;
10992   operands[0] = gen_rtx_REG (SImode,
10993                              true_regnum (operands[0])
10994                              + (TARGET_64BIT ? 1 : 2));
10995   if (GET_CODE (operands[1]) == ABS)
10996     {
10997       tmp = GEN_INT (0x7fff);
10998       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10999     }
11000   else
11001     {
11002       tmp = GEN_INT (0x8000);
11003       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11004     }
11005   operands[1] = tmp;
11006 })
11007
11008 ;; Conditionalize these after reload. If they match before reload, we
11009 ;; lose the clobber and ability to use integer instructions.
11010
11011 (define_insn "*<code><mode>2_1"
11012   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
11013         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
11014   "TARGET_80387
11015    && (reload_completed
11016        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
11017   "f<absnegprefix>"
11018   [(set_attr "type" "fsgn")
11019    (set_attr "mode" "<MODE>")])
11020
11021 (define_insn "*<code>extendsfdf2"
11022   [(set (match_operand:DF 0 "register_operand" "=f")
11023         (absneg:DF (float_extend:DF
11024                      (match_operand:SF 1 "register_operand" "0"))))]
11025   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
11026   "f<absnegprefix>"
11027   [(set_attr "type" "fsgn")
11028    (set_attr "mode" "DF")])
11029
11030 (define_insn "*<code>extendsfxf2"
11031   [(set (match_operand:XF 0 "register_operand" "=f")
11032         (absneg:XF (float_extend:XF
11033                      (match_operand:SF 1 "register_operand" "0"))))]
11034   "TARGET_80387"
11035   "f<absnegprefix>"
11036   [(set_attr "type" "fsgn")
11037    (set_attr "mode" "XF")])
11038
11039 (define_insn "*<code>extenddfxf2"
11040   [(set (match_operand:XF 0 "register_operand" "=f")
11041         (absneg:XF (float_extend:XF
11042                       (match_operand:DF 1 "register_operand" "0"))))]
11043   "TARGET_80387"
11044   "f<absnegprefix>"
11045   [(set_attr "type" "fsgn")
11046    (set_attr "mode" "XF")])
11047
11048 ;; Copysign instructions
11049
11050 (define_mode_iterator CSGNMODE [SF DF TF])
11051 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
11052
11053 (define_expand "copysign<mode>3"
11054   [(match_operand:CSGNMODE 0 "register_operand" "")
11055    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
11056    (match_operand:CSGNMODE 2 "register_operand" "")]
11057   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11058    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11059 {
11060   ix86_expand_copysign (operands);
11061   DONE;
11062 })
11063
11064 (define_insn_and_split "copysign<mode>3_const"
11065   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
11066         (unspec:CSGNMODE
11067           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
11068            (match_operand:CSGNMODE 2 "register_operand" "0")
11069            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
11070           UNSPEC_COPYSIGN))]
11071   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11072    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11073   "#"
11074   "&& reload_completed"
11075   [(const_int 0)]
11076 {
11077   ix86_split_copysign_const (operands);
11078   DONE;
11079 })
11080
11081 (define_insn "copysign<mode>3_var"
11082   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
11083         (unspec:CSGNMODE
11084           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
11085            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
11086            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
11087            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
11088           UNSPEC_COPYSIGN))
11089    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
11090   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11091    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11092   "#")
11093
11094 (define_split
11095   [(set (match_operand:CSGNMODE 0 "register_operand" "")
11096         (unspec:CSGNMODE
11097           [(match_operand:CSGNMODE 2 "register_operand" "")
11098            (match_operand:CSGNMODE 3 "register_operand" "")
11099            (match_operand:<CSGNVMODE> 4 "" "")
11100            (match_operand:<CSGNVMODE> 5 "" "")]
11101           UNSPEC_COPYSIGN))
11102    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
11103   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11104     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
11105    && reload_completed"
11106   [(const_int 0)]
11107 {
11108   ix86_split_copysign_var (operands);
11109   DONE;
11110 })
11111 \f
11112 ;; One complement instructions
11113
11114 (define_expand "one_cmpldi2"
11115   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11116         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
11117   "TARGET_64BIT"
11118   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
11119
11120 (define_insn "*one_cmpldi2_1_rex64"
11121   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11122         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
11123   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
11124   "not{q}\t%0"
11125   [(set_attr "type" "negnot")
11126    (set_attr "mode" "DI")])
11127
11128 (define_insn "*one_cmpldi2_2_rex64"
11129   [(set (reg FLAGS_REG)
11130         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
11131                  (const_int 0)))
11132    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11133         (not:DI (match_dup 1)))]
11134   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11135    && ix86_unary_operator_ok (NOT, DImode, operands)"
11136   "#"
11137   [(set_attr "type" "alu1")
11138    (set_attr "mode" "DI")])
11139
11140 (define_split
11141   [(set (match_operand 0 "flags_reg_operand" "")
11142         (match_operator 2 "compare_operator"
11143           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
11144            (const_int 0)]))
11145    (set (match_operand:DI 1 "nonimmediate_operand" "")
11146         (not:DI (match_dup 3)))]
11147   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
11148   [(parallel [(set (match_dup 0)
11149                    (match_op_dup 2
11150                      [(xor:DI (match_dup 3) (const_int -1))
11151                       (const_int 0)]))
11152               (set (match_dup 1)
11153                    (xor:DI (match_dup 3) (const_int -1)))])]
11154   "")
11155
11156 (define_expand "one_cmplsi2"
11157   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11158         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
11159   ""
11160   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
11161
11162 (define_insn "*one_cmplsi2_1"
11163   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11164         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
11165   "ix86_unary_operator_ok (NOT, SImode, operands)"
11166   "not{l}\t%0"
11167   [(set_attr "type" "negnot")
11168    (set_attr "mode" "SI")])
11169
11170 ;; ??? Currently never generated - xor is used instead.
11171 (define_insn "*one_cmplsi2_1_zext"
11172   [(set (match_operand:DI 0 "register_operand" "=r")
11173         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
11174   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
11175   "not{l}\t%k0"
11176   [(set_attr "type" "negnot")
11177    (set_attr "mode" "SI")])
11178
11179 (define_insn "*one_cmplsi2_2"
11180   [(set (reg FLAGS_REG)
11181         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11182                  (const_int 0)))
11183    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11184         (not:SI (match_dup 1)))]
11185   "ix86_match_ccmode (insn, CCNOmode)
11186    && ix86_unary_operator_ok (NOT, SImode, operands)"
11187   "#"
11188   [(set_attr "type" "alu1")
11189    (set_attr "mode" "SI")])
11190
11191 (define_split
11192   [(set (match_operand 0 "flags_reg_operand" "")
11193         (match_operator 2 "compare_operator"
11194           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
11195            (const_int 0)]))
11196    (set (match_operand:SI 1 "nonimmediate_operand" "")
11197         (not:SI (match_dup 3)))]
11198   "ix86_match_ccmode (insn, CCNOmode)"
11199   [(parallel [(set (match_dup 0)
11200                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11201                                     (const_int 0)]))
11202               (set (match_dup 1)
11203                    (xor:SI (match_dup 3) (const_int -1)))])]
11204   "")
11205
11206 ;; ??? Currently never generated - xor is used instead.
11207 (define_insn "*one_cmplsi2_2_zext"
11208   [(set (reg FLAGS_REG)
11209         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
11210                  (const_int 0)))
11211    (set (match_operand:DI 0 "register_operand" "=r")
11212         (zero_extend:DI (not:SI (match_dup 1))))]
11213   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11214    && ix86_unary_operator_ok (NOT, SImode, operands)"
11215   "#"
11216   [(set_attr "type" "alu1")
11217    (set_attr "mode" "SI")])
11218
11219 (define_split
11220   [(set (match_operand 0 "flags_reg_operand" "")
11221         (match_operator 2 "compare_operator"
11222           [(not:SI (match_operand:SI 3 "register_operand" ""))
11223            (const_int 0)]))
11224    (set (match_operand:DI 1 "register_operand" "")
11225         (zero_extend:DI (not:SI (match_dup 3))))]
11226   "ix86_match_ccmode (insn, CCNOmode)"
11227   [(parallel [(set (match_dup 0)
11228                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11229                                     (const_int 0)]))
11230               (set (match_dup 1)
11231                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
11232   "")
11233
11234 (define_expand "one_cmplhi2"
11235   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11236         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11237   "TARGET_HIMODE_MATH"
11238   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11239
11240 (define_insn "*one_cmplhi2_1"
11241   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11242         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11243   "ix86_unary_operator_ok (NOT, HImode, operands)"
11244   "not{w}\t%0"
11245   [(set_attr "type" "negnot")
11246    (set_attr "mode" "HI")])
11247
11248 (define_insn "*one_cmplhi2_2"
11249   [(set (reg FLAGS_REG)
11250         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11251                  (const_int 0)))
11252    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11253         (not:HI (match_dup 1)))]
11254   "ix86_match_ccmode (insn, CCNOmode)
11255    && ix86_unary_operator_ok (NEG, HImode, operands)"
11256   "#"
11257   [(set_attr "type" "alu1")
11258    (set_attr "mode" "HI")])
11259
11260 (define_split
11261   [(set (match_operand 0 "flags_reg_operand" "")
11262         (match_operator 2 "compare_operator"
11263           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11264            (const_int 0)]))
11265    (set (match_operand:HI 1 "nonimmediate_operand" "")
11266         (not:HI (match_dup 3)))]
11267   "ix86_match_ccmode (insn, CCNOmode)"
11268   [(parallel [(set (match_dup 0)
11269                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11270                                     (const_int 0)]))
11271               (set (match_dup 1)
11272                    (xor:HI (match_dup 3) (const_int -1)))])]
11273   "")
11274
11275 ;; %%% Potential partial reg stall on alternative 1.  What to do?
11276 (define_expand "one_cmplqi2"
11277   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11278         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11279   "TARGET_QIMODE_MATH"
11280   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11281
11282 (define_insn "*one_cmplqi2_1"
11283   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11284         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11285   "ix86_unary_operator_ok (NOT, QImode, operands)"
11286   "@
11287    not{b}\t%0
11288    not{l}\t%k0"
11289   [(set_attr "type" "negnot")
11290    (set_attr "mode" "QI,SI")])
11291
11292 (define_insn "*one_cmplqi2_2"
11293   [(set (reg FLAGS_REG)
11294         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11295                  (const_int 0)))
11296    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11297         (not:QI (match_dup 1)))]
11298   "ix86_match_ccmode (insn, CCNOmode)
11299    && ix86_unary_operator_ok (NOT, QImode, operands)"
11300   "#"
11301   [(set_attr "type" "alu1")
11302    (set_attr "mode" "QI")])
11303
11304 (define_split
11305   [(set (match_operand 0 "flags_reg_operand" "")
11306         (match_operator 2 "compare_operator"
11307           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11308            (const_int 0)]))
11309    (set (match_operand:QI 1 "nonimmediate_operand" "")
11310         (not:QI (match_dup 3)))]
11311   "ix86_match_ccmode (insn, CCNOmode)"
11312   [(parallel [(set (match_dup 0)
11313                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11314                                     (const_int 0)]))
11315               (set (match_dup 1)
11316                    (xor:QI (match_dup 3) (const_int -1)))])]
11317   "")
11318 \f
11319 ;; Arithmetic shift instructions
11320
11321 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11322 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11323 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11324 ;; from the assembler input.
11325 ;;
11326 ;; This instruction shifts the target reg/mem as usual, but instead of
11327 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11328 ;; is a left shift double, bits are taken from the high order bits of
11329 ;; reg, else if the insn is a shift right double, bits are taken from the
11330 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11331 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11332 ;;
11333 ;; Since sh[lr]d does not change the `reg' operand, that is done
11334 ;; separately, making all shifts emit pairs of shift double and normal
11335 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11336 ;; support a 63 bit shift, each shift where the count is in a reg expands
11337 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11338 ;;
11339 ;; If the shift count is a constant, we need never emit more than one
11340 ;; shift pair, instead using moves and sign extension for counts greater
11341 ;; than 31.
11342
11343 (define_expand "ashlti3"
11344   [(set (match_operand:TI 0 "register_operand" "")
11345         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11346                    (match_operand:QI 2 "nonmemory_operand" "")))]
11347   "TARGET_64BIT"
11348   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11349
11350 ;; This pattern must be defined before *ashlti3_1 to prevent
11351 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11352
11353 (define_insn "*avx_ashlti3"
11354   [(set (match_operand:TI 0 "register_operand" "=x")
11355         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11356                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11357   "TARGET_AVX"
11358 {
11359   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11360   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11361 }
11362   [(set_attr "type" "sseishft")
11363    (set_attr "prefix" "vex")
11364    (set_attr "mode" "TI")])
11365
11366 (define_insn "sse2_ashlti3"
11367   [(set (match_operand:TI 0 "register_operand" "=x")
11368         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11369                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11370   "TARGET_SSE2"
11371 {
11372   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11373   return "pslldq\t{%2, %0|%0, %2}";
11374 }
11375   [(set_attr "type" "sseishft")
11376    (set_attr "prefix_data16" "1")
11377    (set_attr "mode" "TI")])
11378
11379 (define_insn "*ashlti3_1"
11380   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11381         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11382                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11383    (clobber (reg:CC FLAGS_REG))]
11384   "TARGET_64BIT"
11385   "#"
11386   [(set_attr "type" "multi")])
11387
11388 (define_peephole2
11389   [(match_scratch:DI 3 "r")
11390    (parallel [(set (match_operand:TI 0 "register_operand" "")
11391                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11392                               (match_operand:QI 2 "nonmemory_operand" "")))
11393               (clobber (reg:CC FLAGS_REG))])
11394    (match_dup 3)]
11395   "TARGET_64BIT"
11396   [(const_int 0)]
11397   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11398
11399 (define_split
11400   [(set (match_operand:TI 0 "register_operand" "")
11401         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11402                    (match_operand:QI 2 "nonmemory_operand" "")))
11403    (clobber (reg:CC FLAGS_REG))]
11404   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11405                     ? epilogue_completed : reload_completed)"
11406   [(const_int 0)]
11407   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11408
11409 (define_insn "x86_64_shld"
11410   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11411         (ior:DI (ashift:DI (match_dup 0)
11412                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11413                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11414                   (minus:QI (const_int 64) (match_dup 2)))))
11415    (clobber (reg:CC FLAGS_REG))]
11416   "TARGET_64BIT"
11417   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11418   [(set_attr "type" "ishift")
11419    (set_attr "prefix_0f" "1")
11420    (set_attr "mode" "DI")
11421    (set_attr "athlon_decode" "vector")
11422    (set_attr "amdfam10_decode" "vector")])
11423
11424 (define_expand "x86_64_shift_adj_1"
11425   [(set (reg:CCZ FLAGS_REG)
11426         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11427                              (const_int 64))
11428                      (const_int 0)))
11429    (set (match_operand:DI 0 "register_operand" "")
11430         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11431                          (match_operand:DI 1 "register_operand" "")
11432                          (match_dup 0)))
11433    (set (match_dup 1)
11434         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11435                          (match_operand:DI 3 "register_operand" "r")
11436                          (match_dup 1)))]
11437   "TARGET_64BIT"
11438   "")
11439
11440 (define_expand "x86_64_shift_adj_2"
11441   [(use (match_operand:DI 0 "register_operand" ""))
11442    (use (match_operand:DI 1 "register_operand" ""))
11443    (use (match_operand:QI 2 "register_operand" ""))]
11444   "TARGET_64BIT"
11445 {
11446   rtx label = gen_label_rtx ();
11447   rtx tmp;
11448
11449   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11450
11451   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11452   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11453   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11454                               gen_rtx_LABEL_REF (VOIDmode, label),
11455                               pc_rtx);
11456   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11457   JUMP_LABEL (tmp) = label;
11458
11459   emit_move_insn (operands[0], operands[1]);
11460   ix86_expand_clear (operands[1]);
11461
11462   emit_label (label);
11463   LABEL_NUSES (label) = 1;
11464
11465   DONE;
11466 })
11467
11468 (define_expand "ashldi3"
11469   [(set (match_operand:DI 0 "shiftdi_operand" "")
11470         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11471                    (match_operand:QI 2 "nonmemory_operand" "")))]
11472   ""
11473   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11474
11475 (define_insn "*ashldi3_1_rex64"
11476   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11477         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11478                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11479    (clobber (reg:CC FLAGS_REG))]
11480   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11481 {
11482   switch (get_attr_type (insn))
11483     {
11484     case TYPE_ALU:
11485       gcc_assert (operands[2] == const1_rtx);
11486       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11487       return "add{q}\t%0, %0";
11488
11489     case TYPE_LEA:
11490       gcc_assert (CONST_INT_P (operands[2]));
11491       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11492       operands[1] = gen_rtx_MULT (DImode, operands[1],
11493                                   GEN_INT (1 << INTVAL (operands[2])));
11494       return "lea{q}\t{%a1, %0|%0, %a1}";
11495
11496     default:
11497       if (REG_P (operands[2]))
11498         return "sal{q}\t{%b2, %0|%0, %b2}";
11499       else if (operands[2] == const1_rtx
11500                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11501         return "sal{q}\t%0";
11502       else
11503         return "sal{q}\t{%2, %0|%0, %2}";
11504     }
11505 }
11506   [(set (attr "type")
11507      (cond [(eq_attr "alternative" "1")
11508               (const_string "lea")
11509             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11510                           (const_int 0))
11511                       (match_operand 0 "register_operand" ""))
11512                  (match_operand 2 "const1_operand" ""))
11513               (const_string "alu")
11514            ]
11515            (const_string "ishift")))
11516    (set_attr "mode" "DI")])
11517
11518 ;; Convert lea to the lea pattern to avoid flags dependency.
11519 (define_split
11520   [(set (match_operand:DI 0 "register_operand" "")
11521         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11522                    (match_operand:QI 2 "immediate_operand" "")))
11523    (clobber (reg:CC FLAGS_REG))]
11524   "TARGET_64BIT && reload_completed
11525    && true_regnum (operands[0]) != true_regnum (operands[1])"
11526   [(set (match_dup 0)
11527         (mult:DI (match_dup 1)
11528                  (match_dup 2)))]
11529   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11530
11531 ;; This pattern can't accept a variable shift count, since shifts by
11532 ;; zero don't affect the flags.  We assume that shifts by constant
11533 ;; zero are optimized away.
11534 (define_insn "*ashldi3_cmp_rex64"
11535   [(set (reg FLAGS_REG)
11536         (compare
11537           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11538                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11539           (const_int 0)))
11540    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11541         (ashift:DI (match_dup 1) (match_dup 2)))]
11542   "TARGET_64BIT
11543    && (optimize_function_for_size_p (cfun)
11544        || !TARGET_PARTIAL_FLAG_REG_STALL
11545        || (operands[2] == const1_rtx
11546            && (TARGET_SHIFT1
11547                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11548    && ix86_match_ccmode (insn, CCGOCmode)
11549    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11550 {
11551   switch (get_attr_type (insn))
11552     {
11553     case TYPE_ALU:
11554       gcc_assert (operands[2] == const1_rtx);
11555       return "add{q}\t%0, %0";
11556
11557     default:
11558       if (REG_P (operands[2]))
11559         return "sal{q}\t{%b2, %0|%0, %b2}";
11560       else if (operands[2] == const1_rtx
11561                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11562         return "sal{q}\t%0";
11563       else
11564         return "sal{q}\t{%2, %0|%0, %2}";
11565     }
11566 }
11567   [(set (attr "type")
11568      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11569                           (const_int 0))
11570                       (match_operand 0 "register_operand" ""))
11571                  (match_operand 2 "const1_operand" ""))
11572               (const_string "alu")
11573            ]
11574            (const_string "ishift")))
11575    (set_attr "mode" "DI")])
11576
11577 (define_insn "*ashldi3_cconly_rex64"
11578   [(set (reg FLAGS_REG)
11579         (compare
11580           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11581                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11582           (const_int 0)))
11583    (clobber (match_scratch:DI 0 "=r"))]
11584   "TARGET_64BIT
11585    && (optimize_function_for_size_p (cfun)
11586        || !TARGET_PARTIAL_FLAG_REG_STALL
11587        || (operands[2] == const1_rtx
11588            && (TARGET_SHIFT1
11589                || TARGET_DOUBLE_WITH_ADD)))
11590    && ix86_match_ccmode (insn, CCGOCmode)
11591    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11592 {
11593   switch (get_attr_type (insn))
11594     {
11595     case TYPE_ALU:
11596       gcc_assert (operands[2] == const1_rtx);
11597       return "add{q}\t%0, %0";
11598
11599     default:
11600       if (REG_P (operands[2]))
11601         return "sal{q}\t{%b2, %0|%0, %b2}";
11602       else if (operands[2] == const1_rtx
11603                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11604         return "sal{q}\t%0";
11605       else
11606         return "sal{q}\t{%2, %0|%0, %2}";
11607     }
11608 }
11609   [(set (attr "type")
11610      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11611                           (const_int 0))
11612                       (match_operand 0 "register_operand" ""))
11613                  (match_operand 2 "const1_operand" ""))
11614               (const_string "alu")
11615            ]
11616            (const_string "ishift")))
11617    (set_attr "mode" "DI")])
11618
11619 (define_insn "*ashldi3_1"
11620   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11621         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11622                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11623    (clobber (reg:CC FLAGS_REG))]
11624   "!TARGET_64BIT"
11625   "#"
11626   [(set_attr "type" "multi")])
11627
11628 ;; By default we don't ask for a scratch register, because when DImode
11629 ;; values are manipulated, registers are already at a premium.  But if
11630 ;; we have one handy, we won't turn it away.
11631 (define_peephole2
11632   [(match_scratch:SI 3 "r")
11633    (parallel [(set (match_operand:DI 0 "register_operand" "")
11634                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11635                               (match_operand:QI 2 "nonmemory_operand" "")))
11636               (clobber (reg:CC FLAGS_REG))])
11637    (match_dup 3)]
11638   "!TARGET_64BIT && TARGET_CMOVE"
11639   [(const_int 0)]
11640   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11641
11642 (define_split
11643   [(set (match_operand:DI 0 "register_operand" "")
11644         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11645                    (match_operand:QI 2 "nonmemory_operand" "")))
11646    (clobber (reg:CC FLAGS_REG))]
11647   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11648                      ? epilogue_completed : reload_completed)"
11649   [(const_int 0)]
11650   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11651
11652 (define_insn "x86_shld"
11653   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11654         (ior:SI (ashift:SI (match_dup 0)
11655                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11656                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11657                   (minus:QI (const_int 32) (match_dup 2)))))
11658    (clobber (reg:CC FLAGS_REG))]
11659   ""
11660   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11661   [(set_attr "type" "ishift")
11662    (set_attr "prefix_0f" "1")
11663    (set_attr "mode" "SI")
11664    (set_attr "pent_pair" "np")
11665    (set_attr "athlon_decode" "vector")
11666    (set_attr "amdfam10_decode" "vector")])
11667
11668 (define_expand "x86_shift_adj_1"
11669   [(set (reg:CCZ FLAGS_REG)
11670         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11671                              (const_int 32))
11672                      (const_int 0)))
11673    (set (match_operand:SI 0 "register_operand" "")
11674         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11675                          (match_operand:SI 1 "register_operand" "")
11676                          (match_dup 0)))
11677    (set (match_dup 1)
11678         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11679                          (match_operand:SI 3 "register_operand" "r")
11680                          (match_dup 1)))]
11681   "TARGET_CMOVE"
11682   "")
11683
11684 (define_expand "x86_shift_adj_2"
11685   [(use (match_operand:SI 0 "register_operand" ""))
11686    (use (match_operand:SI 1 "register_operand" ""))
11687    (use (match_operand:QI 2 "register_operand" ""))]
11688   ""
11689 {
11690   rtx label = gen_label_rtx ();
11691   rtx tmp;
11692
11693   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11694
11695   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11696   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11697   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11698                               gen_rtx_LABEL_REF (VOIDmode, label),
11699                               pc_rtx);
11700   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11701   JUMP_LABEL (tmp) = label;
11702
11703   emit_move_insn (operands[0], operands[1]);
11704   ix86_expand_clear (operands[1]);
11705
11706   emit_label (label);
11707   LABEL_NUSES (label) = 1;
11708
11709   DONE;
11710 })
11711
11712 (define_expand "ashlsi3"
11713   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11714         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11715                    (match_operand:QI 2 "nonmemory_operand" "")))]
11716   ""
11717   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11718
11719 (define_insn "*ashlsi3_1"
11720   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11721         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11722                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11723    (clobber (reg:CC FLAGS_REG))]
11724   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11725 {
11726   switch (get_attr_type (insn))
11727     {
11728     case TYPE_ALU:
11729       gcc_assert (operands[2] == const1_rtx);
11730       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11731       return "add{l}\t%0, %0";
11732
11733     case TYPE_LEA:
11734       return "#";
11735
11736     default:
11737       if (REG_P (operands[2]))
11738         return "sal{l}\t{%b2, %0|%0, %b2}";
11739       else if (operands[2] == const1_rtx
11740                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11741         return "sal{l}\t%0";
11742       else
11743         return "sal{l}\t{%2, %0|%0, %2}";
11744     }
11745 }
11746   [(set (attr "type")
11747      (cond [(eq_attr "alternative" "1")
11748               (const_string "lea")
11749             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11750                           (const_int 0))
11751                       (match_operand 0 "register_operand" ""))
11752                  (match_operand 2 "const1_operand" ""))
11753               (const_string "alu")
11754            ]
11755            (const_string "ishift")))
11756    (set_attr "mode" "SI")])
11757
11758 ;; Convert lea to the lea pattern to avoid flags dependency.
11759 (define_split
11760   [(set (match_operand 0 "register_operand" "")
11761         (ashift (match_operand 1 "index_register_operand" "")
11762                 (match_operand:QI 2 "const_int_operand" "")))
11763    (clobber (reg:CC FLAGS_REG))]
11764   "reload_completed
11765    && true_regnum (operands[0]) != true_regnum (operands[1])
11766    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11767   [(const_int 0)]
11768 {
11769   rtx pat;
11770   enum machine_mode mode = GET_MODE (operands[0]);
11771
11772   if (GET_MODE_SIZE (mode) < 4)
11773     operands[0] = gen_lowpart (SImode, operands[0]);
11774   if (mode != Pmode)
11775     operands[1] = gen_lowpart (Pmode, operands[1]);
11776   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11777
11778   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11779   if (Pmode != SImode)
11780     pat = gen_rtx_SUBREG (SImode, pat, 0);
11781   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11782   DONE;
11783 })
11784
11785 ;; Rare case of shifting RSP is handled by generating move and shift
11786 (define_split
11787   [(set (match_operand 0 "register_operand" "")
11788         (ashift (match_operand 1 "register_operand" "")
11789                 (match_operand:QI 2 "const_int_operand" "")))
11790    (clobber (reg:CC FLAGS_REG))]
11791   "reload_completed
11792    && true_regnum (operands[0]) != true_regnum (operands[1])"
11793   [(const_int 0)]
11794 {
11795   rtx pat, clob;
11796   emit_move_insn (operands[0], operands[1]);
11797   pat = gen_rtx_SET (VOIDmode, operands[0],
11798                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11799                                      operands[0], operands[2]));
11800   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11801   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11802   DONE;
11803 })
11804
11805 (define_insn "*ashlsi3_1_zext"
11806   [(set (match_operand:DI 0 "register_operand" "=r,r")
11807         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11808                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11809    (clobber (reg:CC FLAGS_REG))]
11810   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11811 {
11812   switch (get_attr_type (insn))
11813     {
11814     case TYPE_ALU:
11815       gcc_assert (operands[2] == const1_rtx);
11816       return "add{l}\t%k0, %k0";
11817
11818     case TYPE_LEA:
11819       return "#";
11820
11821     default:
11822       if (REG_P (operands[2]))
11823         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11824       else if (operands[2] == const1_rtx
11825                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11826         return "sal{l}\t%k0";
11827       else
11828         return "sal{l}\t{%2, %k0|%k0, %2}";
11829     }
11830 }
11831   [(set (attr "type")
11832      (cond [(eq_attr "alternative" "1")
11833               (const_string "lea")
11834             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11835                      (const_int 0))
11836                  (match_operand 2 "const1_operand" ""))
11837               (const_string "alu")
11838            ]
11839            (const_string "ishift")))
11840    (set_attr "mode" "SI")])
11841
11842 ;; Convert lea to the lea pattern to avoid flags dependency.
11843 (define_split
11844   [(set (match_operand:DI 0 "register_operand" "")
11845         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11846                                 (match_operand:QI 2 "const_int_operand" ""))))
11847    (clobber (reg:CC FLAGS_REG))]
11848   "TARGET_64BIT && reload_completed
11849    && true_regnum (operands[0]) != true_regnum (operands[1])"
11850   [(set (match_dup 0) (zero_extend:DI
11851                         (subreg:SI (mult:SI (match_dup 1)
11852                                             (match_dup 2)) 0)))]
11853 {
11854   operands[1] = gen_lowpart (Pmode, operands[1]);
11855   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11856 })
11857
11858 ;; This pattern can't accept a variable shift count, since shifts by
11859 ;; zero don't affect the flags.  We assume that shifts by constant
11860 ;; zero are optimized away.
11861 (define_insn "*ashlsi3_cmp"
11862   [(set (reg FLAGS_REG)
11863         (compare
11864           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11865                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11866           (const_int 0)))
11867    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11868         (ashift:SI (match_dup 1) (match_dup 2)))]
11869    "(optimize_function_for_size_p (cfun)
11870      || !TARGET_PARTIAL_FLAG_REG_STALL
11871      || (operands[2] == const1_rtx
11872          && (TARGET_SHIFT1
11873              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11874    && ix86_match_ccmode (insn, CCGOCmode)
11875    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11876 {
11877   switch (get_attr_type (insn))
11878     {
11879     case TYPE_ALU:
11880       gcc_assert (operands[2] == const1_rtx);
11881       return "add{l}\t%0, %0";
11882
11883     default:
11884       if (REG_P (operands[2]))
11885         return "sal{l}\t{%b2, %0|%0, %b2}";
11886       else if (operands[2] == const1_rtx
11887                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11888         return "sal{l}\t%0";
11889       else
11890         return "sal{l}\t{%2, %0|%0, %2}";
11891     }
11892 }
11893   [(set (attr "type")
11894      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11895                           (const_int 0))
11896                       (match_operand 0 "register_operand" ""))
11897                  (match_operand 2 "const1_operand" ""))
11898               (const_string "alu")
11899            ]
11900            (const_string "ishift")))
11901    (set_attr "mode" "SI")])
11902
11903 (define_insn "*ashlsi3_cconly"
11904   [(set (reg FLAGS_REG)
11905         (compare
11906           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11907                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11908           (const_int 0)))
11909    (clobber (match_scratch:SI 0 "=r"))]
11910   "(optimize_function_for_size_p (cfun)
11911     || !TARGET_PARTIAL_FLAG_REG_STALL
11912     || (operands[2] == const1_rtx
11913         && (TARGET_SHIFT1
11914             || TARGET_DOUBLE_WITH_ADD)))
11915    && ix86_match_ccmode (insn, CCGOCmode)
11916    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11917 {
11918   switch (get_attr_type (insn))
11919     {
11920     case TYPE_ALU:
11921       gcc_assert (operands[2] == const1_rtx);
11922       return "add{l}\t%0, %0";
11923
11924     default:
11925       if (REG_P (operands[2]))
11926         return "sal{l}\t{%b2, %0|%0, %b2}";
11927       else if (operands[2] == const1_rtx
11928                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11929         return "sal{l}\t%0";
11930       else
11931         return "sal{l}\t{%2, %0|%0, %2}";
11932     }
11933 }
11934   [(set (attr "type")
11935      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11936                           (const_int 0))
11937                       (match_operand 0 "register_operand" ""))
11938                  (match_operand 2 "const1_operand" ""))
11939               (const_string "alu")
11940            ]
11941            (const_string "ishift")))
11942    (set_attr "mode" "SI")])
11943
11944 (define_insn "*ashlsi3_cmp_zext"
11945   [(set (reg FLAGS_REG)
11946         (compare
11947           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11948                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11949           (const_int 0)))
11950    (set (match_operand:DI 0 "register_operand" "=r")
11951         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11952   "TARGET_64BIT
11953    && (optimize_function_for_size_p (cfun)
11954        || !TARGET_PARTIAL_FLAG_REG_STALL
11955        || (operands[2] == const1_rtx
11956            && (TARGET_SHIFT1
11957                || TARGET_DOUBLE_WITH_ADD)))
11958    && ix86_match_ccmode (insn, CCGOCmode)
11959    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11960 {
11961   switch (get_attr_type (insn))
11962     {
11963     case TYPE_ALU:
11964       gcc_assert (operands[2] == const1_rtx);
11965       return "add{l}\t%k0, %k0";
11966
11967     default:
11968       if (REG_P (operands[2]))
11969         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11970       else if (operands[2] == const1_rtx
11971                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11972         return "sal{l}\t%k0";
11973       else
11974         return "sal{l}\t{%2, %k0|%k0, %2}";
11975     }
11976 }
11977   [(set (attr "type")
11978      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11979                      (const_int 0))
11980                  (match_operand 2 "const1_operand" ""))
11981               (const_string "alu")
11982            ]
11983            (const_string "ishift")))
11984    (set_attr "mode" "SI")])
11985
11986 (define_expand "ashlhi3"
11987   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11988         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11989                    (match_operand:QI 2 "nonmemory_operand" "")))]
11990   "TARGET_HIMODE_MATH"
11991   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11992
11993 (define_insn "*ashlhi3_1_lea"
11994   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11995         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11996                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11997    (clobber (reg:CC FLAGS_REG))]
11998   "!TARGET_PARTIAL_REG_STALL
11999    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12000 {
12001   switch (get_attr_type (insn))
12002     {
12003     case TYPE_LEA:
12004       return "#";
12005     case TYPE_ALU:
12006       gcc_assert (operands[2] == const1_rtx);
12007       return "add{w}\t%0, %0";
12008
12009     default:
12010       if (REG_P (operands[2]))
12011         return "sal{w}\t{%b2, %0|%0, %b2}";
12012       else if (operands[2] == const1_rtx
12013                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12014         return "sal{w}\t%0";
12015       else
12016         return "sal{w}\t{%2, %0|%0, %2}";
12017     }
12018 }
12019   [(set (attr "type")
12020      (cond [(eq_attr "alternative" "1")
12021               (const_string "lea")
12022             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12023                           (const_int 0))
12024                       (match_operand 0 "register_operand" ""))
12025                  (match_operand 2 "const1_operand" ""))
12026               (const_string "alu")
12027            ]
12028            (const_string "ishift")))
12029    (set_attr "mode" "HI,SI")])
12030
12031 (define_insn "*ashlhi3_1"
12032   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12033         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12034                    (match_operand:QI 2 "nonmemory_operand" "cI")))
12035    (clobber (reg:CC FLAGS_REG))]
12036   "TARGET_PARTIAL_REG_STALL
12037    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12038 {
12039   switch (get_attr_type (insn))
12040     {
12041     case TYPE_ALU:
12042       gcc_assert (operands[2] == const1_rtx);
12043       return "add{w}\t%0, %0";
12044
12045     default:
12046       if (REG_P (operands[2]))
12047         return "sal{w}\t{%b2, %0|%0, %b2}";
12048       else if (operands[2] == const1_rtx
12049                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12050         return "sal{w}\t%0";
12051       else
12052         return "sal{w}\t{%2, %0|%0, %2}";
12053     }
12054 }
12055   [(set (attr "type")
12056      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12057                           (const_int 0))
12058                       (match_operand 0 "register_operand" ""))
12059                  (match_operand 2 "const1_operand" ""))
12060               (const_string "alu")
12061            ]
12062            (const_string "ishift")))
12063    (set_attr "mode" "HI")])
12064
12065 ;; This pattern can't accept a variable shift count, since shifts by
12066 ;; zero don't affect the flags.  We assume that shifts by constant
12067 ;; zero are optimized away.
12068 (define_insn "*ashlhi3_cmp"
12069   [(set (reg FLAGS_REG)
12070         (compare
12071           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12072                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12073           (const_int 0)))
12074    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12075         (ashift:HI (match_dup 1) (match_dup 2)))]
12076   "(optimize_function_for_size_p (cfun)
12077     || !TARGET_PARTIAL_FLAG_REG_STALL
12078     || (operands[2] == const1_rtx
12079         && (TARGET_SHIFT1
12080             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12081    && ix86_match_ccmode (insn, CCGOCmode)
12082    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12083 {
12084   switch (get_attr_type (insn))
12085     {
12086     case TYPE_ALU:
12087       gcc_assert (operands[2] == const1_rtx);
12088       return "add{w}\t%0, %0";
12089
12090     default:
12091       if (REG_P (operands[2]))
12092         return "sal{w}\t{%b2, %0|%0, %b2}";
12093       else if (operands[2] == const1_rtx
12094                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12095         return "sal{w}\t%0";
12096       else
12097         return "sal{w}\t{%2, %0|%0, %2}";
12098     }
12099 }
12100   [(set (attr "type")
12101      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12102                           (const_int 0))
12103                       (match_operand 0 "register_operand" ""))
12104                  (match_operand 2 "const1_operand" ""))
12105               (const_string "alu")
12106            ]
12107            (const_string "ishift")))
12108    (set_attr "mode" "HI")])
12109
12110 (define_insn "*ashlhi3_cconly"
12111   [(set (reg FLAGS_REG)
12112         (compare
12113           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12114                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12115           (const_int 0)))
12116    (clobber (match_scratch:HI 0 "=r"))]
12117   "(optimize_function_for_size_p (cfun)
12118     || !TARGET_PARTIAL_FLAG_REG_STALL
12119     || (operands[2] == const1_rtx
12120         && (TARGET_SHIFT1
12121             || TARGET_DOUBLE_WITH_ADD)))
12122    && ix86_match_ccmode (insn, CCGOCmode)
12123    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12124 {
12125   switch (get_attr_type (insn))
12126     {
12127     case TYPE_ALU:
12128       gcc_assert (operands[2] == const1_rtx);
12129       return "add{w}\t%0, %0";
12130
12131     default:
12132       if (REG_P (operands[2]))
12133         return "sal{w}\t{%b2, %0|%0, %b2}";
12134       else if (operands[2] == const1_rtx
12135                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12136         return "sal{w}\t%0";
12137       else
12138         return "sal{w}\t{%2, %0|%0, %2}";
12139     }
12140 }
12141   [(set (attr "type")
12142      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12143                           (const_int 0))
12144                       (match_operand 0 "register_operand" ""))
12145                  (match_operand 2 "const1_operand" ""))
12146               (const_string "alu")
12147            ]
12148            (const_string "ishift")))
12149    (set_attr "mode" "HI")])
12150
12151 (define_expand "ashlqi3"
12152   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12153         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
12154                    (match_operand:QI 2 "nonmemory_operand" "")))]
12155   "TARGET_QIMODE_MATH"
12156   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
12157
12158 ;; %%% Potential partial reg stall on alternative 2.  What to do?
12159
12160 (define_insn "*ashlqi3_1_lea"
12161   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
12162         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
12163                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
12164    (clobber (reg:CC FLAGS_REG))]
12165   "!TARGET_PARTIAL_REG_STALL
12166    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12167 {
12168   switch (get_attr_type (insn))
12169     {
12170     case TYPE_LEA:
12171       return "#";
12172     case TYPE_ALU:
12173       gcc_assert (operands[2] == const1_rtx);
12174       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12175         return "add{l}\t%k0, %k0";
12176       else
12177         return "add{b}\t%0, %0";
12178
12179     default:
12180       if (REG_P (operands[2]))
12181         {
12182           if (get_attr_mode (insn) == MODE_SI)
12183             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12184           else
12185             return "sal{b}\t{%b2, %0|%0, %b2}";
12186         }
12187       else if (operands[2] == const1_rtx
12188                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12189         {
12190           if (get_attr_mode (insn) == MODE_SI)
12191             return "sal{l}\t%0";
12192           else
12193             return "sal{b}\t%0";
12194         }
12195       else
12196         {
12197           if (get_attr_mode (insn) == MODE_SI)
12198             return "sal{l}\t{%2, %k0|%k0, %2}";
12199           else
12200             return "sal{b}\t{%2, %0|%0, %2}";
12201         }
12202     }
12203 }
12204   [(set (attr "type")
12205      (cond [(eq_attr "alternative" "2")
12206               (const_string "lea")
12207             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12208                           (const_int 0))
12209                       (match_operand 0 "register_operand" ""))
12210                  (match_operand 2 "const1_operand" ""))
12211               (const_string "alu")
12212            ]
12213            (const_string "ishift")))
12214    (set_attr "mode" "QI,SI,SI")])
12215
12216 (define_insn "*ashlqi3_1"
12217   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
12218         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12219                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
12220    (clobber (reg:CC FLAGS_REG))]
12221   "TARGET_PARTIAL_REG_STALL
12222    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12223 {
12224   switch (get_attr_type (insn))
12225     {
12226     case TYPE_ALU:
12227       gcc_assert (operands[2] == const1_rtx);
12228       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12229         return "add{l}\t%k0, %k0";
12230       else
12231         return "add{b}\t%0, %0";
12232
12233     default:
12234       if (REG_P (operands[2]))
12235         {
12236           if (get_attr_mode (insn) == MODE_SI)
12237             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12238           else
12239             return "sal{b}\t{%b2, %0|%0, %b2}";
12240         }
12241       else if (operands[2] == const1_rtx
12242                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12243         {
12244           if (get_attr_mode (insn) == MODE_SI)
12245             return "sal{l}\t%0";
12246           else
12247             return "sal{b}\t%0";
12248         }
12249       else
12250         {
12251           if (get_attr_mode (insn) == MODE_SI)
12252             return "sal{l}\t{%2, %k0|%k0, %2}";
12253           else
12254             return "sal{b}\t{%2, %0|%0, %2}";
12255         }
12256     }
12257 }
12258   [(set (attr "type")
12259      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12260                           (const_int 0))
12261                       (match_operand 0 "register_operand" ""))
12262                  (match_operand 2 "const1_operand" ""))
12263               (const_string "alu")
12264            ]
12265            (const_string "ishift")))
12266    (set_attr "mode" "QI,SI")])
12267
12268 ;; This pattern can't accept a variable shift count, since shifts by
12269 ;; zero don't affect the flags.  We assume that shifts by constant
12270 ;; zero are optimized away.
12271 (define_insn "*ashlqi3_cmp"
12272   [(set (reg FLAGS_REG)
12273         (compare
12274           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12275                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12276           (const_int 0)))
12277    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12278         (ashift:QI (match_dup 1) (match_dup 2)))]
12279   "(optimize_function_for_size_p (cfun)
12280     || !TARGET_PARTIAL_FLAG_REG_STALL
12281     || (operands[2] == const1_rtx
12282         && (TARGET_SHIFT1
12283             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12284    && ix86_match_ccmode (insn, CCGOCmode)
12285    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12286 {
12287   switch (get_attr_type (insn))
12288     {
12289     case TYPE_ALU:
12290       gcc_assert (operands[2] == const1_rtx);
12291       return "add{b}\t%0, %0";
12292
12293     default:
12294       if (REG_P (operands[2]))
12295         return "sal{b}\t{%b2, %0|%0, %b2}";
12296       else if (operands[2] == const1_rtx
12297                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12298         return "sal{b}\t%0";
12299       else
12300         return "sal{b}\t{%2, %0|%0, %2}";
12301     }
12302 }
12303   [(set (attr "type")
12304      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12305                           (const_int 0))
12306                       (match_operand 0 "register_operand" ""))
12307                  (match_operand 2 "const1_operand" ""))
12308               (const_string "alu")
12309            ]
12310            (const_string "ishift")))
12311    (set_attr "mode" "QI")])
12312
12313 (define_insn "*ashlqi3_cconly"
12314   [(set (reg FLAGS_REG)
12315         (compare
12316           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12317                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12318           (const_int 0)))
12319    (clobber (match_scratch:QI 0 "=q"))]
12320   "(optimize_function_for_size_p (cfun)
12321     || !TARGET_PARTIAL_FLAG_REG_STALL
12322     || (operands[2] == const1_rtx
12323         && (TARGET_SHIFT1
12324             || TARGET_DOUBLE_WITH_ADD)))
12325    && ix86_match_ccmode (insn, CCGOCmode)
12326    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12327 {
12328   switch (get_attr_type (insn))
12329     {
12330     case TYPE_ALU:
12331       gcc_assert (operands[2] == const1_rtx);
12332       return "add{b}\t%0, %0";
12333
12334     default:
12335       if (REG_P (operands[2]))
12336         return "sal{b}\t{%b2, %0|%0, %b2}";
12337       else if (operands[2] == const1_rtx
12338                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12339         return "sal{b}\t%0";
12340       else
12341         return "sal{b}\t{%2, %0|%0, %2}";
12342     }
12343 }
12344   [(set (attr "type")
12345      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12346                           (const_int 0))
12347                       (match_operand 0 "register_operand" ""))
12348                  (match_operand 2 "const1_operand" ""))
12349               (const_string "alu")
12350            ]
12351            (const_string "ishift")))
12352    (set_attr "mode" "QI")])
12353
12354 ;; See comment above `ashldi3' about how this works.
12355
12356 (define_expand "ashrti3"
12357   [(set (match_operand:TI 0 "register_operand" "")
12358         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12359                      (match_operand:QI 2 "nonmemory_operand" "")))]
12360   "TARGET_64BIT"
12361   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12362
12363 (define_insn "*ashrti3_1"
12364   [(set (match_operand:TI 0 "register_operand" "=r")
12365         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12366                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12367    (clobber (reg:CC FLAGS_REG))]
12368   "TARGET_64BIT"
12369   "#"
12370   [(set_attr "type" "multi")])
12371
12372 (define_peephole2
12373   [(match_scratch:DI 3 "r")
12374    (parallel [(set (match_operand:TI 0 "register_operand" "")
12375                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12376                                 (match_operand:QI 2 "nonmemory_operand" "")))
12377               (clobber (reg:CC FLAGS_REG))])
12378    (match_dup 3)]
12379   "TARGET_64BIT"
12380   [(const_int 0)]
12381   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12382
12383 (define_split
12384   [(set (match_operand:TI 0 "register_operand" "")
12385         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12386                      (match_operand:QI 2 "nonmemory_operand" "")))
12387    (clobber (reg:CC FLAGS_REG))]
12388   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12389                     ? epilogue_completed : reload_completed)"
12390   [(const_int 0)]
12391   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12392
12393 (define_insn "x86_64_shrd"
12394   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12395         (ior:DI (ashiftrt:DI (match_dup 0)
12396                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12397                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12398                   (minus:QI (const_int 64) (match_dup 2)))))
12399    (clobber (reg:CC FLAGS_REG))]
12400   "TARGET_64BIT"
12401   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12402   [(set_attr "type" "ishift")
12403    (set_attr "prefix_0f" "1")
12404    (set_attr "mode" "DI")
12405    (set_attr "athlon_decode" "vector")
12406    (set_attr "amdfam10_decode" "vector")])
12407
12408 (define_expand "ashrdi3"
12409   [(set (match_operand:DI 0 "shiftdi_operand" "")
12410         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12411                      (match_operand:QI 2 "nonmemory_operand" "")))]
12412   ""
12413   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12414
12415 (define_expand "x86_64_shift_adj_3"
12416   [(use (match_operand:DI 0 "register_operand" ""))
12417    (use (match_operand:DI 1 "register_operand" ""))
12418    (use (match_operand:QI 2 "register_operand" ""))]
12419   ""
12420 {
12421   rtx label = gen_label_rtx ();
12422   rtx tmp;
12423
12424   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12425
12426   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12427   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12428   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12429                               gen_rtx_LABEL_REF (VOIDmode, label),
12430                               pc_rtx);
12431   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12432   JUMP_LABEL (tmp) = label;
12433
12434   emit_move_insn (operands[0], operands[1]);
12435   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12436
12437   emit_label (label);
12438   LABEL_NUSES (label) = 1;
12439
12440   DONE;
12441 })
12442
12443 (define_insn "ashrdi3_63_rex64"
12444   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12445         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12446                      (match_operand:DI 2 "const_int_operand" "i,i")))
12447    (clobber (reg:CC FLAGS_REG))]
12448   "TARGET_64BIT && INTVAL (operands[2]) == 63
12449    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12450    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12451   "@
12452    {cqto|cqo}
12453    sar{q}\t{%2, %0|%0, %2}"
12454   [(set_attr "type" "imovx,ishift")
12455    (set_attr "prefix_0f" "0,*")
12456    (set_attr "length_immediate" "0,*")
12457    (set_attr "modrm" "0,1")
12458    (set_attr "mode" "DI")])
12459
12460 (define_insn "*ashrdi3_1_one_bit_rex64"
12461   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12462         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12463                      (match_operand:QI 2 "const1_operand" "")))
12464    (clobber (reg:CC FLAGS_REG))]
12465   "TARGET_64BIT
12466    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12467    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12468   "sar{q}\t%0"
12469   [(set_attr "type" "ishift")
12470    (set (attr "length")
12471      (if_then_else (match_operand:DI 0 "register_operand" "")
12472         (const_string "2")
12473         (const_string "*")))])
12474
12475 (define_insn "*ashrdi3_1_rex64"
12476   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12477         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12478                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12479    (clobber (reg:CC FLAGS_REG))]
12480   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12481   "@
12482    sar{q}\t{%2, %0|%0, %2}
12483    sar{q}\t{%b2, %0|%0, %b2}"
12484   [(set_attr "type" "ishift")
12485    (set_attr "mode" "DI")])
12486
12487 ;; This pattern can't accept a variable shift count, since shifts by
12488 ;; zero don't affect the flags.  We assume that shifts by constant
12489 ;; zero are optimized away.
12490 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12491   [(set (reg FLAGS_REG)
12492         (compare
12493           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12494                        (match_operand:QI 2 "const1_operand" ""))
12495           (const_int 0)))
12496    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12497         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12498   "TARGET_64BIT
12499    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12500    && ix86_match_ccmode (insn, CCGOCmode)
12501    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12502   "sar{q}\t%0"
12503   [(set_attr "type" "ishift")
12504    (set (attr "length")
12505      (if_then_else (match_operand:DI 0 "register_operand" "")
12506         (const_string "2")
12507         (const_string "*")))])
12508
12509 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12510   [(set (reg FLAGS_REG)
12511         (compare
12512           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12513                        (match_operand:QI 2 "const1_operand" ""))
12514           (const_int 0)))
12515    (clobber (match_scratch:DI 0 "=r"))]
12516   "TARGET_64BIT
12517    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12518    && ix86_match_ccmode (insn, CCGOCmode)
12519    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12520   "sar{q}\t%0"
12521   [(set_attr "type" "ishift")
12522    (set_attr "length" "2")])
12523
12524 ;; This pattern can't accept a variable shift count, since shifts by
12525 ;; zero don't affect the flags.  We assume that shifts by constant
12526 ;; zero are optimized away.
12527 (define_insn "*ashrdi3_cmp_rex64"
12528   [(set (reg FLAGS_REG)
12529         (compare
12530           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12531                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12532           (const_int 0)))
12533    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12534         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12535   "TARGET_64BIT
12536    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12537    && ix86_match_ccmode (insn, CCGOCmode)
12538    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12539   "sar{q}\t{%2, %0|%0, %2}"
12540   [(set_attr "type" "ishift")
12541    (set_attr "mode" "DI")])
12542
12543 (define_insn "*ashrdi3_cconly_rex64"
12544   [(set (reg FLAGS_REG)
12545         (compare
12546           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12547                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12548           (const_int 0)))
12549    (clobber (match_scratch:DI 0 "=r"))]
12550   "TARGET_64BIT
12551    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12552    && ix86_match_ccmode (insn, CCGOCmode)
12553    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12554   "sar{q}\t{%2, %0|%0, %2}"
12555   [(set_attr "type" "ishift")
12556    (set_attr "mode" "DI")])
12557
12558 (define_insn "*ashrdi3_1"
12559   [(set (match_operand:DI 0 "register_operand" "=r")
12560         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12561                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12562    (clobber (reg:CC FLAGS_REG))]
12563   "!TARGET_64BIT"
12564   "#"
12565   [(set_attr "type" "multi")])
12566
12567 ;; By default we don't ask for a scratch register, because when DImode
12568 ;; values are manipulated, registers are already at a premium.  But if
12569 ;; we have one handy, we won't turn it away.
12570 (define_peephole2
12571   [(match_scratch:SI 3 "r")
12572    (parallel [(set (match_operand:DI 0 "register_operand" "")
12573                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12574                                 (match_operand:QI 2 "nonmemory_operand" "")))
12575               (clobber (reg:CC FLAGS_REG))])
12576    (match_dup 3)]
12577   "!TARGET_64BIT && TARGET_CMOVE"
12578   [(const_int 0)]
12579   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12580
12581 (define_split
12582   [(set (match_operand:DI 0 "register_operand" "")
12583         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12584                      (match_operand:QI 2 "nonmemory_operand" "")))
12585    (clobber (reg:CC FLAGS_REG))]
12586   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12587                      ? epilogue_completed : reload_completed)"
12588   [(const_int 0)]
12589   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12590
12591 (define_insn "x86_shrd"
12592   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12593         (ior:SI (ashiftrt:SI (match_dup 0)
12594                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12595                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12596                   (minus:QI (const_int 32) (match_dup 2)))))
12597    (clobber (reg:CC FLAGS_REG))]
12598   ""
12599   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12600   [(set_attr "type" "ishift")
12601    (set_attr "prefix_0f" "1")
12602    (set_attr "pent_pair" "np")
12603    (set_attr "mode" "SI")])
12604
12605 (define_expand "x86_shift_adj_3"
12606   [(use (match_operand:SI 0 "register_operand" ""))
12607    (use (match_operand:SI 1 "register_operand" ""))
12608    (use (match_operand:QI 2 "register_operand" ""))]
12609   ""
12610 {
12611   rtx label = gen_label_rtx ();
12612   rtx tmp;
12613
12614   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12615
12616   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12617   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12618   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12619                               gen_rtx_LABEL_REF (VOIDmode, label),
12620                               pc_rtx);
12621   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12622   JUMP_LABEL (tmp) = label;
12623
12624   emit_move_insn (operands[0], operands[1]);
12625   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12626
12627   emit_label (label);
12628   LABEL_NUSES (label) = 1;
12629
12630   DONE;
12631 })
12632
12633 (define_expand "ashrsi3_31"
12634   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12635                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12636                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12637               (clobber (reg:CC FLAGS_REG))])]
12638   "")
12639
12640 (define_insn "*ashrsi3_31"
12641   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12642         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12643                      (match_operand:SI 2 "const_int_operand" "i,i")))
12644    (clobber (reg:CC FLAGS_REG))]
12645   "INTVAL (operands[2]) == 31
12646    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12647    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12648   "@
12649    {cltd|cdq}
12650    sar{l}\t{%2, %0|%0, %2}"
12651   [(set_attr "type" "imovx,ishift")
12652    (set_attr "prefix_0f" "0,*")
12653    (set_attr "length_immediate" "0,*")
12654    (set_attr "modrm" "0,1")
12655    (set_attr "mode" "SI")])
12656
12657 (define_insn "*ashrsi3_31_zext"
12658   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12659         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12660                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12661    (clobber (reg:CC FLAGS_REG))]
12662   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12663    && INTVAL (operands[2]) == 31
12664    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12665   "@
12666    {cltd|cdq}
12667    sar{l}\t{%2, %k0|%k0, %2}"
12668   [(set_attr "type" "imovx,ishift")
12669    (set_attr "prefix_0f" "0,*")
12670    (set_attr "length_immediate" "0,*")
12671    (set_attr "modrm" "0,1")
12672    (set_attr "mode" "SI")])
12673
12674 (define_expand "ashrsi3"
12675   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12676         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12677                      (match_operand:QI 2 "nonmemory_operand" "")))]
12678   ""
12679   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12680
12681 (define_insn "*ashrsi3_1_one_bit"
12682   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12683         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12684                      (match_operand:QI 2 "const1_operand" "")))
12685    (clobber (reg:CC FLAGS_REG))]
12686   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12687    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12688   "sar{l}\t%0"
12689   [(set_attr "type" "ishift")
12690    (set (attr "length")
12691      (if_then_else (match_operand:SI 0 "register_operand" "")
12692         (const_string "2")
12693         (const_string "*")))])
12694
12695 (define_insn "*ashrsi3_1_one_bit_zext"
12696   [(set (match_operand:DI 0 "register_operand" "=r")
12697         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12698                                      (match_operand:QI 2 "const1_operand" ""))))
12699    (clobber (reg:CC FLAGS_REG))]
12700   "TARGET_64BIT
12701    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12702    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12703   "sar{l}\t%k0"
12704   [(set_attr "type" "ishift")
12705    (set_attr "length" "2")])
12706
12707 (define_insn "*ashrsi3_1"
12708   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12709         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12710                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12711    (clobber (reg:CC FLAGS_REG))]
12712   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12713   "@
12714    sar{l}\t{%2, %0|%0, %2}
12715    sar{l}\t{%b2, %0|%0, %b2}"
12716   [(set_attr "type" "ishift")
12717    (set_attr "mode" "SI")])
12718
12719 (define_insn "*ashrsi3_1_zext"
12720   [(set (match_operand:DI 0 "register_operand" "=r,r")
12721         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12722                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12723    (clobber (reg:CC FLAGS_REG))]
12724   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12725   "@
12726    sar{l}\t{%2, %k0|%k0, %2}
12727    sar{l}\t{%b2, %k0|%k0, %b2}"
12728   [(set_attr "type" "ishift")
12729    (set_attr "mode" "SI")])
12730
12731 ;; This pattern can't accept a variable shift count, since shifts by
12732 ;; zero don't affect the flags.  We assume that shifts by constant
12733 ;; zero are optimized away.
12734 (define_insn "*ashrsi3_one_bit_cmp"
12735   [(set (reg FLAGS_REG)
12736         (compare
12737           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12738                        (match_operand:QI 2 "const1_operand" ""))
12739           (const_int 0)))
12740    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12741         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12742   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12743    && ix86_match_ccmode (insn, CCGOCmode)
12744    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12745   "sar{l}\t%0"
12746   [(set_attr "type" "ishift")
12747    (set (attr "length")
12748      (if_then_else (match_operand:SI 0 "register_operand" "")
12749         (const_string "2")
12750         (const_string "*")))])
12751
12752 (define_insn "*ashrsi3_one_bit_cconly"
12753   [(set (reg FLAGS_REG)
12754         (compare
12755           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12756                        (match_operand:QI 2 "const1_operand" ""))
12757           (const_int 0)))
12758    (clobber (match_scratch:SI 0 "=r"))]
12759   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12760    && ix86_match_ccmode (insn, CCGOCmode)
12761    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12762   "sar{l}\t%0"
12763   [(set_attr "type" "ishift")
12764    (set_attr "length" "2")])
12765
12766 (define_insn "*ashrsi3_one_bit_cmp_zext"
12767   [(set (reg FLAGS_REG)
12768         (compare
12769           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12770                        (match_operand:QI 2 "const1_operand" ""))
12771           (const_int 0)))
12772    (set (match_operand:DI 0 "register_operand" "=r")
12773         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12774   "TARGET_64BIT
12775    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12776    && ix86_match_ccmode (insn, CCmode)
12777    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12778   "sar{l}\t%k0"
12779   [(set_attr "type" "ishift")
12780    (set_attr "length" "2")])
12781
12782 ;; This pattern can't accept a variable shift count, since shifts by
12783 ;; zero don't affect the flags.  We assume that shifts by constant
12784 ;; zero are optimized away.
12785 (define_insn "*ashrsi3_cmp"
12786   [(set (reg FLAGS_REG)
12787         (compare
12788           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12789                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12790           (const_int 0)))
12791    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12792         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12793   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12794    && ix86_match_ccmode (insn, CCGOCmode)
12795    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12796   "sar{l}\t{%2, %0|%0, %2}"
12797   [(set_attr "type" "ishift")
12798    (set_attr "mode" "SI")])
12799
12800 (define_insn "*ashrsi3_cconly"
12801   [(set (reg FLAGS_REG)
12802         (compare
12803           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12804                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12805           (const_int 0)))
12806    (clobber (match_scratch:SI 0 "=r"))]
12807   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12808    && ix86_match_ccmode (insn, CCGOCmode)
12809    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12810   "sar{l}\t{%2, %0|%0, %2}"
12811   [(set_attr "type" "ishift")
12812    (set_attr "mode" "SI")])
12813
12814 (define_insn "*ashrsi3_cmp_zext"
12815   [(set (reg FLAGS_REG)
12816         (compare
12817           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12818                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12819           (const_int 0)))
12820    (set (match_operand:DI 0 "register_operand" "=r")
12821         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12822   "TARGET_64BIT
12823    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12824    && ix86_match_ccmode (insn, CCGOCmode)
12825    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12826   "sar{l}\t{%2, %k0|%k0, %2}"
12827   [(set_attr "type" "ishift")
12828    (set_attr "mode" "SI")])
12829
12830 (define_expand "ashrhi3"
12831   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12832         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12833                      (match_operand:QI 2 "nonmemory_operand" "")))]
12834   "TARGET_HIMODE_MATH"
12835   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12836
12837 (define_insn "*ashrhi3_1_one_bit"
12838   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12839         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12840                      (match_operand:QI 2 "const1_operand" "")))
12841    (clobber (reg:CC FLAGS_REG))]
12842   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12843    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12844   "sar{w}\t%0"
12845   [(set_attr "type" "ishift")
12846    (set (attr "length")
12847      (if_then_else (match_operand 0 "register_operand" "")
12848         (const_string "2")
12849         (const_string "*")))])
12850
12851 (define_insn "*ashrhi3_1"
12852   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12853         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12854                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12855    (clobber (reg:CC FLAGS_REG))]
12856   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12857   "@
12858    sar{w}\t{%2, %0|%0, %2}
12859    sar{w}\t{%b2, %0|%0, %b2}"
12860   [(set_attr "type" "ishift")
12861    (set_attr "mode" "HI")])
12862
12863 ;; This pattern can't accept a variable shift count, since shifts by
12864 ;; zero don't affect the flags.  We assume that shifts by constant
12865 ;; zero are optimized away.
12866 (define_insn "*ashrhi3_one_bit_cmp"
12867   [(set (reg FLAGS_REG)
12868         (compare
12869           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12870                        (match_operand:QI 2 "const1_operand" ""))
12871           (const_int 0)))
12872    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12873         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12874   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12875    && ix86_match_ccmode (insn, CCGOCmode)
12876    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12877   "sar{w}\t%0"
12878   [(set_attr "type" "ishift")
12879    (set (attr "length")
12880      (if_then_else (match_operand 0 "register_operand" "")
12881         (const_string "2")
12882         (const_string "*")))])
12883
12884 (define_insn "*ashrhi3_one_bit_cconly"
12885   [(set (reg FLAGS_REG)
12886         (compare
12887           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12888                        (match_operand:QI 2 "const1_operand" ""))
12889           (const_int 0)))
12890    (clobber (match_scratch:HI 0 "=r"))]
12891   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12892    && ix86_match_ccmode (insn, CCGOCmode)
12893    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12894   "sar{w}\t%0"
12895   [(set_attr "type" "ishift")
12896    (set_attr "length" "2")])
12897
12898 ;; This pattern can't accept a variable shift count, since shifts by
12899 ;; zero don't affect the flags.  We assume that shifts by constant
12900 ;; zero are optimized away.
12901 (define_insn "*ashrhi3_cmp"
12902   [(set (reg FLAGS_REG)
12903         (compare
12904           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12905                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12906           (const_int 0)))
12907    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12908         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12909   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12910    && ix86_match_ccmode (insn, CCGOCmode)
12911    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12912   "sar{w}\t{%2, %0|%0, %2}"
12913   [(set_attr "type" "ishift")
12914    (set_attr "mode" "HI")])
12915
12916 (define_insn "*ashrhi3_cconly"
12917   [(set (reg FLAGS_REG)
12918         (compare
12919           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12920                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12921           (const_int 0)))
12922    (clobber (match_scratch:HI 0 "=r"))]
12923   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12924    && ix86_match_ccmode (insn, CCGOCmode)
12925    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12926   "sar{w}\t{%2, %0|%0, %2}"
12927   [(set_attr "type" "ishift")
12928    (set_attr "mode" "HI")])
12929
12930 (define_expand "ashrqi3"
12931   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12932         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12933                      (match_operand:QI 2 "nonmemory_operand" "")))]
12934   "TARGET_QIMODE_MATH"
12935   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12936
12937 (define_insn "*ashrqi3_1_one_bit"
12938   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12939         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12940                      (match_operand:QI 2 "const1_operand" "")))
12941    (clobber (reg:CC FLAGS_REG))]
12942   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12943    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12944   "sar{b}\t%0"
12945   [(set_attr "type" "ishift")
12946    (set (attr "length")
12947      (if_then_else (match_operand 0 "register_operand" "")
12948         (const_string "2")
12949         (const_string "*")))])
12950
12951 (define_insn "*ashrqi3_1_one_bit_slp"
12952   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12953         (ashiftrt:QI (match_dup 0)
12954                      (match_operand:QI 1 "const1_operand" "")))
12955    (clobber (reg:CC FLAGS_REG))]
12956   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12957    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12958    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12959   "sar{b}\t%0"
12960   [(set_attr "type" "ishift1")
12961    (set (attr "length")
12962      (if_then_else (match_operand 0 "register_operand" "")
12963         (const_string "2")
12964         (const_string "*")))])
12965
12966 (define_insn "*ashrqi3_1"
12967   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12968         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12969                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12970    (clobber (reg:CC FLAGS_REG))]
12971   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12972   "@
12973    sar{b}\t{%2, %0|%0, %2}
12974    sar{b}\t{%b2, %0|%0, %b2}"
12975   [(set_attr "type" "ishift")
12976    (set_attr "mode" "QI")])
12977
12978 (define_insn "*ashrqi3_1_slp"
12979   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12980         (ashiftrt:QI (match_dup 0)
12981                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12982    (clobber (reg:CC FLAGS_REG))]
12983   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12984    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12985   "@
12986    sar{b}\t{%1, %0|%0, %1}
12987    sar{b}\t{%b1, %0|%0, %b1}"
12988   [(set_attr "type" "ishift1")
12989    (set_attr "mode" "QI")])
12990
12991 ;; This pattern can't accept a variable shift count, since shifts by
12992 ;; zero don't affect the flags.  We assume that shifts by constant
12993 ;; zero are optimized away.
12994 (define_insn "*ashrqi3_one_bit_cmp"
12995   [(set (reg FLAGS_REG)
12996         (compare
12997           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12998                        (match_operand:QI 2 "const1_operand" "I"))
12999           (const_int 0)))
13000    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13001         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13002   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13003    && ix86_match_ccmode (insn, CCGOCmode)
13004    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13005   "sar{b}\t%0"
13006   [(set_attr "type" "ishift")
13007    (set (attr "length")
13008      (if_then_else (match_operand 0 "register_operand" "")
13009         (const_string "2")
13010         (const_string "*")))])
13011
13012 (define_insn "*ashrqi3_one_bit_cconly"
13013   [(set (reg FLAGS_REG)
13014         (compare
13015           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13016                        (match_operand:QI 2 "const1_operand" ""))
13017           (const_int 0)))
13018    (clobber (match_scratch:QI 0 "=q"))]
13019   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13020    && ix86_match_ccmode (insn, CCGOCmode)
13021    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13022   "sar{b}\t%0"
13023   [(set_attr "type" "ishift")
13024    (set_attr "length" "2")])
13025
13026 ;; This pattern can't accept a variable shift count, since shifts by
13027 ;; zero don't affect the flags.  We assume that shifts by constant
13028 ;; zero are optimized away.
13029 (define_insn "*ashrqi3_cmp"
13030   [(set (reg FLAGS_REG)
13031         (compare
13032           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13033                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13034           (const_int 0)))
13035    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13036         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13037   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13038    && ix86_match_ccmode (insn, CCGOCmode)
13039    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13040   "sar{b}\t{%2, %0|%0, %2}"
13041   [(set_attr "type" "ishift")
13042    (set_attr "mode" "QI")])
13043
13044 (define_insn "*ashrqi3_cconly"
13045   [(set (reg FLAGS_REG)
13046         (compare
13047           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13048                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13049           (const_int 0)))
13050    (clobber (match_scratch:QI 0 "=q"))]
13051   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13052    && ix86_match_ccmode (insn, CCGOCmode)
13053    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13054   "sar{b}\t{%2, %0|%0, %2}"
13055   [(set_attr "type" "ishift")
13056    (set_attr "mode" "QI")])
13057
13058 \f
13059 ;; Logical shift instructions
13060
13061 ;; See comment above `ashldi3' about how this works.
13062
13063 (define_expand "lshrti3"
13064   [(set (match_operand:TI 0 "register_operand" "")
13065         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13066                      (match_operand:QI 2 "nonmemory_operand" "")))]
13067   "TARGET_64BIT"
13068   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
13069
13070 ;; This pattern must be defined before *lshrti3_1 to prevent
13071 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
13072
13073 (define_insn "*avx_lshrti3"
13074   [(set (match_operand:TI 0 "register_operand" "=x")
13075         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
13076                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13077   "TARGET_AVX"
13078 {
13079   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13080   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
13081 }
13082   [(set_attr "type" "sseishft")
13083    (set_attr "prefix" "vex")
13084    (set_attr "mode" "TI")])
13085
13086 (define_insn "sse2_lshrti3"
13087   [(set (match_operand:TI 0 "register_operand" "=x")
13088         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13089                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13090   "TARGET_SSE2"
13091 {
13092   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13093   return "psrldq\t{%2, %0|%0, %2}";
13094 }
13095   [(set_attr "type" "sseishft")
13096    (set_attr "prefix_data16" "1")
13097    (set_attr "mode" "TI")])
13098
13099 (define_insn "*lshrti3_1"
13100   [(set (match_operand:TI 0 "register_operand" "=r")
13101         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13102                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
13103    (clobber (reg:CC FLAGS_REG))]
13104   "TARGET_64BIT"
13105   "#"
13106   [(set_attr "type" "multi")])
13107
13108 (define_peephole2
13109   [(match_scratch:DI 3 "r")
13110    (parallel [(set (match_operand:TI 0 "register_operand" "")
13111                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13112                                 (match_operand:QI 2 "nonmemory_operand" "")))
13113               (clobber (reg:CC FLAGS_REG))])
13114    (match_dup 3)]
13115   "TARGET_64BIT"
13116   [(const_int 0)]
13117   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
13118
13119 (define_split
13120   [(set (match_operand:TI 0 "register_operand" "")
13121         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13122                      (match_operand:QI 2 "nonmemory_operand" "")))
13123    (clobber (reg:CC FLAGS_REG))]
13124   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13125                     ? epilogue_completed : reload_completed)"
13126   [(const_int 0)]
13127   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
13128
13129 (define_expand "lshrdi3"
13130   [(set (match_operand:DI 0 "shiftdi_operand" "")
13131         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
13132                      (match_operand:QI 2 "nonmemory_operand" "")))]
13133   ""
13134   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
13135
13136 (define_insn "*lshrdi3_1_one_bit_rex64"
13137   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13138         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13139                      (match_operand:QI 2 "const1_operand" "")))
13140    (clobber (reg:CC FLAGS_REG))]
13141   "TARGET_64BIT
13142    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13143    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13144   "shr{q}\t%0"
13145   [(set_attr "type" "ishift")
13146    (set (attr "length")
13147      (if_then_else (match_operand:DI 0 "register_operand" "")
13148         (const_string "2")
13149         (const_string "*")))])
13150
13151 (define_insn "*lshrdi3_1_rex64"
13152   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13153         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13154                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13155    (clobber (reg:CC FLAGS_REG))]
13156   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13157   "@
13158    shr{q}\t{%2, %0|%0, %2}
13159    shr{q}\t{%b2, %0|%0, %b2}"
13160   [(set_attr "type" "ishift")
13161    (set_attr "mode" "DI")])
13162
13163 ;; This pattern can't accept a variable shift count, since shifts by
13164 ;; zero don't affect the flags.  We assume that shifts by constant
13165 ;; zero are optimized away.
13166 (define_insn "*lshrdi3_cmp_one_bit_rex64"
13167   [(set (reg FLAGS_REG)
13168         (compare
13169           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13170                        (match_operand:QI 2 "const1_operand" ""))
13171           (const_int 0)))
13172    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13173         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13174   "TARGET_64BIT
13175    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13176    && ix86_match_ccmode (insn, CCGOCmode)
13177    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13178   "shr{q}\t%0"
13179   [(set_attr "type" "ishift")
13180    (set (attr "length")
13181      (if_then_else (match_operand:DI 0 "register_operand" "")
13182         (const_string "2")
13183         (const_string "*")))])
13184
13185 (define_insn "*lshrdi3_cconly_one_bit_rex64"
13186   [(set (reg FLAGS_REG)
13187         (compare
13188           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13189                        (match_operand:QI 2 "const1_operand" ""))
13190           (const_int 0)))
13191    (clobber (match_scratch:DI 0 "=r"))]
13192   "TARGET_64BIT
13193    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13194    && ix86_match_ccmode (insn, CCGOCmode)
13195    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13196   "shr{q}\t%0"
13197   [(set_attr "type" "ishift")
13198    (set_attr "length" "2")])
13199
13200 ;; This pattern can't accept a variable shift count, since shifts by
13201 ;; zero don't affect the flags.  We assume that shifts by constant
13202 ;; zero are optimized away.
13203 (define_insn "*lshrdi3_cmp_rex64"
13204   [(set (reg FLAGS_REG)
13205         (compare
13206           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13207                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
13208           (const_int 0)))
13209    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13210         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13211   "TARGET_64BIT
13212    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13213    && ix86_match_ccmode (insn, CCGOCmode)
13214    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13215   "shr{q}\t{%2, %0|%0, %2}"
13216   [(set_attr "type" "ishift")
13217    (set_attr "mode" "DI")])
13218
13219 (define_insn "*lshrdi3_cconly_rex64"
13220   [(set (reg FLAGS_REG)
13221         (compare
13222           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13223                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
13224           (const_int 0)))
13225    (clobber (match_scratch:DI 0 "=r"))]
13226   "TARGET_64BIT
13227    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13228    && ix86_match_ccmode (insn, CCGOCmode)
13229    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13230   "shr{q}\t{%2, %0|%0, %2}"
13231   [(set_attr "type" "ishift")
13232    (set_attr "mode" "DI")])
13233
13234 (define_insn "*lshrdi3_1"
13235   [(set (match_operand:DI 0 "register_operand" "=r")
13236         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13237                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
13238    (clobber (reg:CC FLAGS_REG))]
13239   "!TARGET_64BIT"
13240   "#"
13241   [(set_attr "type" "multi")])
13242
13243 ;; By default we don't ask for a scratch register, because when DImode
13244 ;; values are manipulated, registers are already at a premium.  But if
13245 ;; we have one handy, we won't turn it away.
13246 (define_peephole2
13247   [(match_scratch:SI 3 "r")
13248    (parallel [(set (match_operand:DI 0 "register_operand" "")
13249                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13250                                 (match_operand:QI 2 "nonmemory_operand" "")))
13251               (clobber (reg:CC FLAGS_REG))])
13252    (match_dup 3)]
13253   "!TARGET_64BIT && TARGET_CMOVE"
13254   [(const_int 0)]
13255   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13256
13257 (define_split
13258   [(set (match_operand:DI 0 "register_operand" "")
13259         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13260                      (match_operand:QI 2 "nonmemory_operand" "")))
13261    (clobber (reg:CC FLAGS_REG))]
13262   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13263                      ? epilogue_completed : reload_completed)"
13264   [(const_int 0)]
13265   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13266
13267 (define_expand "lshrsi3"
13268   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13269         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13270                      (match_operand:QI 2 "nonmemory_operand" "")))]
13271   ""
13272   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13273
13274 (define_insn "*lshrsi3_1_one_bit"
13275   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13276         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13277                      (match_operand:QI 2 "const1_operand" "")))
13278    (clobber (reg:CC FLAGS_REG))]
13279   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13280    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13281   "shr{l}\t%0"
13282   [(set_attr "type" "ishift")
13283    (set (attr "length")
13284      (if_then_else (match_operand:SI 0 "register_operand" "")
13285         (const_string "2")
13286         (const_string "*")))])
13287
13288 (define_insn "*lshrsi3_1_one_bit_zext"
13289   [(set (match_operand:DI 0 "register_operand" "=r")
13290         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13291                      (match_operand:QI 2 "const1_operand" "")))
13292    (clobber (reg:CC FLAGS_REG))]
13293   "TARGET_64BIT
13294    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13295    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13296   "shr{l}\t%k0"
13297   [(set_attr "type" "ishift")
13298    (set_attr "length" "2")])
13299
13300 (define_insn "*lshrsi3_1"
13301   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13302         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13303                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13304    (clobber (reg:CC FLAGS_REG))]
13305   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13306   "@
13307    shr{l}\t{%2, %0|%0, %2}
13308    shr{l}\t{%b2, %0|%0, %b2}"
13309   [(set_attr "type" "ishift")
13310    (set_attr "mode" "SI")])
13311
13312 (define_insn "*lshrsi3_1_zext"
13313   [(set (match_operand:DI 0 "register_operand" "=r,r")
13314         (zero_extend:DI
13315           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13316                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13317    (clobber (reg:CC FLAGS_REG))]
13318   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13319   "@
13320    shr{l}\t{%2, %k0|%k0, %2}
13321    shr{l}\t{%b2, %k0|%k0, %b2}"
13322   [(set_attr "type" "ishift")
13323    (set_attr "mode" "SI")])
13324
13325 ;; This pattern can't accept a variable shift count, since shifts by
13326 ;; zero don't affect the flags.  We assume that shifts by constant
13327 ;; zero are optimized away.
13328 (define_insn "*lshrsi3_one_bit_cmp"
13329   [(set (reg FLAGS_REG)
13330         (compare
13331           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13332                        (match_operand:QI 2 "const1_operand" ""))
13333           (const_int 0)))
13334    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13335         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13336   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13337    && ix86_match_ccmode (insn, CCGOCmode)
13338    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13339   "shr{l}\t%0"
13340   [(set_attr "type" "ishift")
13341    (set (attr "length")
13342      (if_then_else (match_operand:SI 0 "register_operand" "")
13343         (const_string "2")
13344         (const_string "*")))])
13345
13346 (define_insn "*lshrsi3_one_bit_cconly"
13347   [(set (reg FLAGS_REG)
13348         (compare
13349           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13350                        (match_operand:QI 2 "const1_operand" ""))
13351           (const_int 0)))
13352    (clobber (match_scratch:SI 0 "=r"))]
13353   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13354    && ix86_match_ccmode (insn, CCGOCmode)
13355    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13356   "shr{l}\t%0"
13357   [(set_attr "type" "ishift")
13358    (set_attr "length" "2")])
13359
13360 (define_insn "*lshrsi3_cmp_one_bit_zext"
13361   [(set (reg FLAGS_REG)
13362         (compare
13363           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13364                        (match_operand:QI 2 "const1_operand" ""))
13365           (const_int 0)))
13366    (set (match_operand:DI 0 "register_operand" "=r")
13367         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13368   "TARGET_64BIT
13369    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13370    && ix86_match_ccmode (insn, CCGOCmode)
13371    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13372   "shr{l}\t%k0"
13373   [(set_attr "type" "ishift")
13374    (set_attr "length" "2")])
13375
13376 ;; This pattern can't accept a variable shift count, since shifts by
13377 ;; zero don't affect the flags.  We assume that shifts by constant
13378 ;; zero are optimized away.
13379 (define_insn "*lshrsi3_cmp"
13380   [(set (reg FLAGS_REG)
13381         (compare
13382           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13383                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13384           (const_int 0)))
13385    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13386         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13387   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13388    && ix86_match_ccmode (insn, CCGOCmode)
13389    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13390   "shr{l}\t{%2, %0|%0, %2}"
13391   [(set_attr "type" "ishift")
13392    (set_attr "mode" "SI")])
13393
13394 (define_insn "*lshrsi3_cconly"
13395   [(set (reg FLAGS_REG)
13396       (compare
13397         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13398                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13399         (const_int 0)))
13400    (clobber (match_scratch:SI 0 "=r"))]
13401   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13402    && ix86_match_ccmode (insn, CCGOCmode)
13403    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13404   "shr{l}\t{%2, %0|%0, %2}"
13405   [(set_attr "type" "ishift")
13406    (set_attr "mode" "SI")])
13407
13408 (define_insn "*lshrsi3_cmp_zext"
13409   [(set (reg FLAGS_REG)
13410         (compare
13411           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13412                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13413           (const_int 0)))
13414    (set (match_operand:DI 0 "register_operand" "=r")
13415         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13416   "TARGET_64BIT
13417    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13418    && ix86_match_ccmode (insn, CCGOCmode)
13419    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13420   "shr{l}\t{%2, %k0|%k0, %2}"
13421   [(set_attr "type" "ishift")
13422    (set_attr "mode" "SI")])
13423
13424 (define_expand "lshrhi3"
13425   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13426         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13427                      (match_operand:QI 2 "nonmemory_operand" "")))]
13428   "TARGET_HIMODE_MATH"
13429   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13430
13431 (define_insn "*lshrhi3_1_one_bit"
13432   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13433         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13434                      (match_operand:QI 2 "const1_operand" "")))
13435    (clobber (reg:CC FLAGS_REG))]
13436   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13437    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13438   "shr{w}\t%0"
13439   [(set_attr "type" "ishift")
13440    (set (attr "length")
13441      (if_then_else (match_operand 0 "register_operand" "")
13442         (const_string "2")
13443         (const_string "*")))])
13444
13445 (define_insn "*lshrhi3_1"
13446   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13447         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13448                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13449    (clobber (reg:CC FLAGS_REG))]
13450   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13451   "@
13452    shr{w}\t{%2, %0|%0, %2}
13453    shr{w}\t{%b2, %0|%0, %b2}"
13454   [(set_attr "type" "ishift")
13455    (set_attr "mode" "HI")])
13456
13457 ;; This pattern can't accept a variable shift count, since shifts by
13458 ;; zero don't affect the flags.  We assume that shifts by constant
13459 ;; zero are optimized away.
13460 (define_insn "*lshrhi3_one_bit_cmp"
13461   [(set (reg FLAGS_REG)
13462         (compare
13463           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13464                        (match_operand:QI 2 "const1_operand" ""))
13465           (const_int 0)))
13466    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13467         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13468   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13469    && ix86_match_ccmode (insn, CCGOCmode)
13470    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13471   "shr{w}\t%0"
13472   [(set_attr "type" "ishift")
13473    (set (attr "length")
13474      (if_then_else (match_operand:SI 0 "register_operand" "")
13475         (const_string "2")
13476         (const_string "*")))])
13477
13478 (define_insn "*lshrhi3_one_bit_cconly"
13479   [(set (reg FLAGS_REG)
13480         (compare
13481           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13482                        (match_operand:QI 2 "const1_operand" ""))
13483           (const_int 0)))
13484    (clobber (match_scratch:HI 0 "=r"))]
13485   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13486    && ix86_match_ccmode (insn, CCGOCmode)
13487    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13488   "shr{w}\t%0"
13489   [(set_attr "type" "ishift")
13490    (set_attr "length" "2")])
13491
13492 ;; This pattern can't accept a variable shift count, since shifts by
13493 ;; zero don't affect the flags.  We assume that shifts by constant
13494 ;; zero are optimized away.
13495 (define_insn "*lshrhi3_cmp"
13496   [(set (reg FLAGS_REG)
13497         (compare
13498           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13499                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13500           (const_int 0)))
13501    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13502         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13503   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13504    && ix86_match_ccmode (insn, CCGOCmode)
13505    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13506   "shr{w}\t{%2, %0|%0, %2}"
13507   [(set_attr "type" "ishift")
13508    (set_attr "mode" "HI")])
13509
13510 (define_insn "*lshrhi3_cconly"
13511   [(set (reg FLAGS_REG)
13512         (compare
13513           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13514                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13515           (const_int 0)))
13516    (clobber (match_scratch:HI 0 "=r"))]
13517   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13518    && ix86_match_ccmode (insn, CCGOCmode)
13519    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13520   "shr{w}\t{%2, %0|%0, %2}"
13521   [(set_attr "type" "ishift")
13522    (set_attr "mode" "HI")])
13523
13524 (define_expand "lshrqi3"
13525   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13526         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13527                      (match_operand:QI 2 "nonmemory_operand" "")))]
13528   "TARGET_QIMODE_MATH"
13529   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13530
13531 (define_insn "*lshrqi3_1_one_bit"
13532   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13533         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13534                      (match_operand:QI 2 "const1_operand" "")))
13535    (clobber (reg:CC FLAGS_REG))]
13536   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13537    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13538   "shr{b}\t%0"
13539   [(set_attr "type" "ishift")
13540    (set (attr "length")
13541      (if_then_else (match_operand 0 "register_operand" "")
13542         (const_string "2")
13543         (const_string "*")))])
13544
13545 (define_insn "*lshrqi3_1_one_bit_slp"
13546   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13547         (lshiftrt:QI (match_dup 0)
13548                      (match_operand:QI 1 "const1_operand" "")))
13549    (clobber (reg:CC FLAGS_REG))]
13550   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13551    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13552   "shr{b}\t%0"
13553   [(set_attr "type" "ishift1")
13554    (set (attr "length")
13555      (if_then_else (match_operand 0 "register_operand" "")
13556         (const_string "2")
13557         (const_string "*")))])
13558
13559 (define_insn "*lshrqi3_1"
13560   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13561         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13562                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13563    (clobber (reg:CC FLAGS_REG))]
13564   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13565   "@
13566    shr{b}\t{%2, %0|%0, %2}
13567    shr{b}\t{%b2, %0|%0, %b2}"
13568   [(set_attr "type" "ishift")
13569    (set_attr "mode" "QI")])
13570
13571 (define_insn "*lshrqi3_1_slp"
13572   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13573         (lshiftrt:QI (match_dup 0)
13574                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13575    (clobber (reg:CC FLAGS_REG))]
13576   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13577    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13578   "@
13579    shr{b}\t{%1, %0|%0, %1}
13580    shr{b}\t{%b1, %0|%0, %b1}"
13581   [(set_attr "type" "ishift1")
13582    (set_attr "mode" "QI")])
13583
13584 ;; This pattern can't accept a variable shift count, since shifts by
13585 ;; zero don't affect the flags.  We assume that shifts by constant
13586 ;; zero are optimized away.
13587 (define_insn "*lshrqi2_one_bit_cmp"
13588   [(set (reg FLAGS_REG)
13589         (compare
13590           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13591                        (match_operand:QI 2 "const1_operand" ""))
13592           (const_int 0)))
13593    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13594         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13595   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13596    && ix86_match_ccmode (insn, CCGOCmode)
13597    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13598   "shr{b}\t%0"
13599   [(set_attr "type" "ishift")
13600    (set (attr "length")
13601      (if_then_else (match_operand:SI 0 "register_operand" "")
13602         (const_string "2")
13603         (const_string "*")))])
13604
13605 (define_insn "*lshrqi2_one_bit_cconly"
13606   [(set (reg FLAGS_REG)
13607         (compare
13608           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13609                        (match_operand:QI 2 "const1_operand" ""))
13610           (const_int 0)))
13611    (clobber (match_scratch:QI 0 "=q"))]
13612   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13613    && ix86_match_ccmode (insn, CCGOCmode)
13614    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13615   "shr{b}\t%0"
13616   [(set_attr "type" "ishift")
13617    (set_attr "length" "2")])
13618
13619 ;; This pattern can't accept a variable shift count, since shifts by
13620 ;; zero don't affect the flags.  We assume that shifts by constant
13621 ;; zero are optimized away.
13622 (define_insn "*lshrqi2_cmp"
13623   [(set (reg FLAGS_REG)
13624         (compare
13625           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13626                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13627           (const_int 0)))
13628    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13629         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13630   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13631    && ix86_match_ccmode (insn, CCGOCmode)
13632    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13633   "shr{b}\t{%2, %0|%0, %2}"
13634   [(set_attr "type" "ishift")
13635    (set_attr "mode" "QI")])
13636
13637 (define_insn "*lshrqi2_cconly"
13638   [(set (reg FLAGS_REG)
13639         (compare
13640           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13641                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13642           (const_int 0)))
13643    (clobber (match_scratch:QI 0 "=q"))]
13644   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13645    && ix86_match_ccmode (insn, CCGOCmode)
13646    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13647   "shr{b}\t{%2, %0|%0, %2}"
13648   [(set_attr "type" "ishift")
13649    (set_attr "mode" "QI")])
13650 \f
13651 ;; Rotate instructions
13652
13653 (define_expand "rotldi3"
13654   [(set (match_operand:DI 0 "shiftdi_operand" "")
13655         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13656                    (match_operand:QI 2 "nonmemory_operand" "")))]
13657  ""
13658 {
13659   if (TARGET_64BIT)
13660     {
13661       ix86_expand_binary_operator (ROTATE, DImode, operands);
13662       DONE;
13663     }
13664   if (!const_1_to_31_operand (operands[2], VOIDmode))
13665     FAIL;
13666   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13667   DONE;
13668 })
13669
13670 ;; Implement rotation using two double-precision shift instructions
13671 ;; and a scratch register.
13672 (define_insn_and_split "ix86_rotldi3"
13673  [(set (match_operand:DI 0 "register_operand" "=r")
13674        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13675                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13676   (clobber (reg:CC FLAGS_REG))
13677   (clobber (match_scratch:SI 3 "=&r"))]
13678  "!TARGET_64BIT"
13679  ""
13680  "&& reload_completed"
13681  [(set (match_dup 3) (match_dup 4))
13682   (parallel
13683    [(set (match_dup 4)
13684          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13685                  (lshiftrt:SI (match_dup 5)
13686                               (minus:QI (const_int 32) (match_dup 2)))))
13687     (clobber (reg:CC FLAGS_REG))])
13688   (parallel
13689    [(set (match_dup 5)
13690          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13691                  (lshiftrt:SI (match_dup 3)
13692                               (minus:QI (const_int 32) (match_dup 2)))))
13693     (clobber (reg:CC FLAGS_REG))])]
13694  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13695
13696 (define_insn "*rotlsi3_1_one_bit_rex64"
13697   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13698         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13699                    (match_operand:QI 2 "const1_operand" "")))
13700    (clobber (reg:CC FLAGS_REG))]
13701   "TARGET_64BIT
13702    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13703    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13704   "rol{q}\t%0"
13705   [(set_attr "type" "rotate")
13706    (set (attr "length")
13707      (if_then_else (match_operand:DI 0 "register_operand" "")
13708         (const_string "2")
13709         (const_string "*")))])
13710
13711 (define_insn "*rotldi3_1_rex64"
13712   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13713         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13714                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13715    (clobber (reg:CC FLAGS_REG))]
13716   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13717   "@
13718    rol{q}\t{%2, %0|%0, %2}
13719    rol{q}\t{%b2, %0|%0, %b2}"
13720   [(set_attr "type" "rotate")
13721    (set_attr "mode" "DI")])
13722
13723 (define_expand "rotlsi3"
13724   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13725         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13726                    (match_operand:QI 2 "nonmemory_operand" "")))]
13727   ""
13728   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13729
13730 (define_insn "*rotlsi3_1_one_bit"
13731   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13732         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13733                    (match_operand:QI 2 "const1_operand" "")))
13734    (clobber (reg:CC FLAGS_REG))]
13735   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13736    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13737   "rol{l}\t%0"
13738   [(set_attr "type" "rotate")
13739    (set (attr "length")
13740      (if_then_else (match_operand:SI 0 "register_operand" "")
13741         (const_string "2")
13742         (const_string "*")))])
13743
13744 (define_insn "*rotlsi3_1_one_bit_zext"
13745   [(set (match_operand:DI 0 "register_operand" "=r")
13746         (zero_extend:DI
13747           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13748                      (match_operand:QI 2 "const1_operand" ""))))
13749    (clobber (reg:CC FLAGS_REG))]
13750   "TARGET_64BIT
13751    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13752    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13753   "rol{l}\t%k0"
13754   [(set_attr "type" "rotate")
13755    (set_attr "length" "2")])
13756
13757 (define_insn "*rotlsi3_1"
13758   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13759         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13760                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13761    (clobber (reg:CC FLAGS_REG))]
13762   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13763   "@
13764    rol{l}\t{%2, %0|%0, %2}
13765    rol{l}\t{%b2, %0|%0, %b2}"
13766   [(set_attr "type" "rotate")
13767    (set_attr "mode" "SI")])
13768
13769 (define_insn "*rotlsi3_1_zext"
13770   [(set (match_operand:DI 0 "register_operand" "=r,r")
13771         (zero_extend:DI
13772           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13773                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13774    (clobber (reg:CC FLAGS_REG))]
13775   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13776   "@
13777    rol{l}\t{%2, %k0|%k0, %2}
13778    rol{l}\t{%b2, %k0|%k0, %b2}"
13779   [(set_attr "type" "rotate")
13780    (set_attr "mode" "SI")])
13781
13782 (define_expand "rotlhi3"
13783   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13784         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13785                    (match_operand:QI 2 "nonmemory_operand" "")))]
13786   "TARGET_HIMODE_MATH"
13787   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13788
13789 (define_insn "*rotlhi3_1_one_bit"
13790   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13791         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13792                    (match_operand:QI 2 "const1_operand" "")))
13793    (clobber (reg:CC FLAGS_REG))]
13794   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13795    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13796   "rol{w}\t%0"
13797   [(set_attr "type" "rotate")
13798    (set (attr "length")
13799      (if_then_else (match_operand 0 "register_operand" "")
13800         (const_string "2")
13801         (const_string "*")))])
13802
13803 (define_insn "*rotlhi3_1"
13804   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13805         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13806                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13807    (clobber (reg:CC FLAGS_REG))]
13808   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13809   "@
13810    rol{w}\t{%2, %0|%0, %2}
13811    rol{w}\t{%b2, %0|%0, %b2}"
13812   [(set_attr "type" "rotate")
13813    (set_attr "mode" "HI")])
13814
13815 (define_split
13816  [(set (match_operand:HI 0 "register_operand" "")
13817        (rotate:HI (match_dup 0) (const_int 8)))
13818   (clobber (reg:CC FLAGS_REG))]
13819  "reload_completed"
13820  [(parallel [(set (strict_low_part (match_dup 0))
13821                   (bswap:HI (match_dup 0)))
13822              (clobber (reg:CC FLAGS_REG))])]
13823  "")
13824
13825 (define_expand "rotlqi3"
13826   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13827         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13828                    (match_operand:QI 2 "nonmemory_operand" "")))]
13829   "TARGET_QIMODE_MATH"
13830   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13831
13832 (define_insn "*rotlqi3_1_one_bit_slp"
13833   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13834         (rotate:QI (match_dup 0)
13835                    (match_operand:QI 1 "const1_operand" "")))
13836    (clobber (reg:CC FLAGS_REG))]
13837   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13838    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13839   "rol{b}\t%0"
13840   [(set_attr "type" "rotate1")
13841    (set (attr "length")
13842      (if_then_else (match_operand 0 "register_operand" "")
13843         (const_string "2")
13844         (const_string "*")))])
13845
13846 (define_insn "*rotlqi3_1_one_bit"
13847   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13848         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13849                    (match_operand:QI 2 "const1_operand" "")))
13850    (clobber (reg:CC FLAGS_REG))]
13851   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13852    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13853   "rol{b}\t%0"
13854   [(set_attr "type" "rotate")
13855    (set (attr "length")
13856      (if_then_else (match_operand 0 "register_operand" "")
13857         (const_string "2")
13858         (const_string "*")))])
13859
13860 (define_insn "*rotlqi3_1_slp"
13861   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13862         (rotate:QI (match_dup 0)
13863                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13864    (clobber (reg:CC FLAGS_REG))]
13865   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13866    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13867   "@
13868    rol{b}\t{%1, %0|%0, %1}
13869    rol{b}\t{%b1, %0|%0, %b1}"
13870   [(set_attr "type" "rotate1")
13871    (set_attr "mode" "QI")])
13872
13873 (define_insn "*rotlqi3_1"
13874   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13875         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13876                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13877    (clobber (reg:CC FLAGS_REG))]
13878   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13879   "@
13880    rol{b}\t{%2, %0|%0, %2}
13881    rol{b}\t{%b2, %0|%0, %b2}"
13882   [(set_attr "type" "rotate")
13883    (set_attr "mode" "QI")])
13884
13885 (define_expand "rotrdi3"
13886   [(set (match_operand:DI 0 "shiftdi_operand" "")
13887         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13888                    (match_operand:QI 2 "nonmemory_operand" "")))]
13889  ""
13890 {
13891   if (TARGET_64BIT)
13892     {
13893       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13894       DONE;
13895     }
13896   if (!const_1_to_31_operand (operands[2], VOIDmode))
13897     FAIL;
13898   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13899   DONE;
13900 })
13901
13902 ;; Implement rotation using two double-precision shift instructions
13903 ;; and a scratch register.
13904 (define_insn_and_split "ix86_rotrdi3"
13905  [(set (match_operand:DI 0 "register_operand" "=r")
13906        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13907                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13908   (clobber (reg:CC FLAGS_REG))
13909   (clobber (match_scratch:SI 3 "=&r"))]
13910  "!TARGET_64BIT"
13911  ""
13912  "&& reload_completed"
13913  [(set (match_dup 3) (match_dup 4))
13914   (parallel
13915    [(set (match_dup 4)
13916          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13917                  (ashift:SI (match_dup 5)
13918                             (minus:QI (const_int 32) (match_dup 2)))))
13919     (clobber (reg:CC FLAGS_REG))])
13920   (parallel
13921    [(set (match_dup 5)
13922          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13923                  (ashift:SI (match_dup 3)
13924                             (minus:QI (const_int 32) (match_dup 2)))))
13925     (clobber (reg:CC FLAGS_REG))])]
13926  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13927
13928 (define_insn "*rotrdi3_1_one_bit_rex64"
13929   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13930         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13931                      (match_operand:QI 2 "const1_operand" "")))
13932    (clobber (reg:CC FLAGS_REG))]
13933   "TARGET_64BIT
13934    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13935    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13936   "ror{q}\t%0"
13937   [(set_attr "type" "rotate")
13938    (set (attr "length")
13939      (if_then_else (match_operand:DI 0 "register_operand" "")
13940         (const_string "2")
13941         (const_string "*")))])
13942
13943 (define_insn "*rotrdi3_1_rex64"
13944   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13945         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13946                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13947    (clobber (reg:CC FLAGS_REG))]
13948   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13949   "@
13950    ror{q}\t{%2, %0|%0, %2}
13951    ror{q}\t{%b2, %0|%0, %b2}"
13952   [(set_attr "type" "rotate")
13953    (set_attr "mode" "DI")])
13954
13955 (define_expand "rotrsi3"
13956   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13957         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13958                      (match_operand:QI 2 "nonmemory_operand" "")))]
13959   ""
13960   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13961
13962 (define_insn "*rotrsi3_1_one_bit"
13963   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13964         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13965                      (match_operand:QI 2 "const1_operand" "")))
13966    (clobber (reg:CC FLAGS_REG))]
13967   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13968    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13969   "ror{l}\t%0"
13970   [(set_attr "type" "rotate")
13971    (set (attr "length")
13972      (if_then_else (match_operand:SI 0 "register_operand" "")
13973         (const_string "2")
13974         (const_string "*")))])
13975
13976 (define_insn "*rotrsi3_1_one_bit_zext"
13977   [(set (match_operand:DI 0 "register_operand" "=r")
13978         (zero_extend:DI
13979           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13980                        (match_operand:QI 2 "const1_operand" ""))))
13981    (clobber (reg:CC FLAGS_REG))]
13982   "TARGET_64BIT
13983    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13984    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13985   "ror{l}\t%k0"
13986   [(set_attr "type" "rotate")
13987    (set (attr "length")
13988      (if_then_else (match_operand:SI 0 "register_operand" "")
13989         (const_string "2")
13990         (const_string "*")))])
13991
13992 (define_insn "*rotrsi3_1"
13993   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13994         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13995                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13996    (clobber (reg:CC FLAGS_REG))]
13997   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13998   "@
13999    ror{l}\t{%2, %0|%0, %2}
14000    ror{l}\t{%b2, %0|%0, %b2}"
14001   [(set_attr "type" "rotate")
14002    (set_attr "mode" "SI")])
14003
14004 (define_insn "*rotrsi3_1_zext"
14005   [(set (match_operand:DI 0 "register_operand" "=r,r")
14006         (zero_extend:DI
14007           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
14008                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14009    (clobber (reg:CC FLAGS_REG))]
14010   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14011   "@
14012    ror{l}\t{%2, %k0|%k0, %2}
14013    ror{l}\t{%b2, %k0|%k0, %b2}"
14014   [(set_attr "type" "rotate")
14015    (set_attr "mode" "SI")])
14016
14017 (define_expand "rotrhi3"
14018   [(set (match_operand:HI 0 "nonimmediate_operand" "")
14019         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
14020                      (match_operand:QI 2 "nonmemory_operand" "")))]
14021   "TARGET_HIMODE_MATH"
14022   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
14023
14024 (define_insn "*rotrhi3_one_bit"
14025   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14026         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14027                      (match_operand:QI 2 "const1_operand" "")))
14028    (clobber (reg:CC FLAGS_REG))]
14029   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14030    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14031   "ror{w}\t%0"
14032   [(set_attr "type" "rotate")
14033    (set (attr "length")
14034      (if_then_else (match_operand 0 "register_operand" "")
14035         (const_string "2")
14036         (const_string "*")))])
14037
14038 (define_insn "*rotrhi3_1"
14039   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14040         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14041                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14042    (clobber (reg:CC FLAGS_REG))]
14043   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14044   "@
14045    ror{w}\t{%2, %0|%0, %2}
14046    ror{w}\t{%b2, %0|%0, %b2}"
14047   [(set_attr "type" "rotate")
14048    (set_attr "mode" "HI")])
14049
14050 (define_split
14051  [(set (match_operand:HI 0 "register_operand" "")
14052        (rotatert:HI (match_dup 0) (const_int 8)))
14053   (clobber (reg:CC FLAGS_REG))]
14054  "reload_completed"
14055  [(parallel [(set (strict_low_part (match_dup 0))
14056                   (bswap:HI (match_dup 0)))
14057              (clobber (reg:CC FLAGS_REG))])]
14058  "")
14059
14060 (define_expand "rotrqi3"
14061   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14062         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
14063                      (match_operand:QI 2 "nonmemory_operand" "")))]
14064   "TARGET_QIMODE_MATH"
14065   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
14066
14067 (define_insn "*rotrqi3_1_one_bit"
14068   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14069         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14070                      (match_operand:QI 2 "const1_operand" "")))
14071    (clobber (reg:CC FLAGS_REG))]
14072   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14073    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14074   "ror{b}\t%0"
14075   [(set_attr "type" "rotate")
14076    (set (attr "length")
14077      (if_then_else (match_operand 0 "register_operand" "")
14078         (const_string "2")
14079         (const_string "*")))])
14080
14081 (define_insn "*rotrqi3_1_one_bit_slp"
14082   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14083         (rotatert:QI (match_dup 0)
14084                      (match_operand:QI 1 "const1_operand" "")))
14085    (clobber (reg:CC FLAGS_REG))]
14086   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14087    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14088   "ror{b}\t%0"
14089   [(set_attr "type" "rotate1")
14090    (set (attr "length")
14091      (if_then_else (match_operand 0 "register_operand" "")
14092         (const_string "2")
14093         (const_string "*")))])
14094
14095 (define_insn "*rotrqi3_1"
14096   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14097         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14098                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14099    (clobber (reg:CC FLAGS_REG))]
14100   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14101   "@
14102    ror{b}\t{%2, %0|%0, %2}
14103    ror{b}\t{%b2, %0|%0, %b2}"
14104   [(set_attr "type" "rotate")
14105    (set_attr "mode" "QI")])
14106
14107 (define_insn "*rotrqi3_1_slp"
14108   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14109         (rotatert:QI (match_dup 0)
14110                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
14111    (clobber (reg:CC FLAGS_REG))]
14112   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14113    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14114   "@
14115    ror{b}\t{%1, %0|%0, %1}
14116    ror{b}\t{%b1, %0|%0, %b1}"
14117   [(set_attr "type" "rotate1")
14118    (set_attr "mode" "QI")])
14119 \f
14120 ;; Bit set / bit test instructions
14121
14122 (define_expand "extv"
14123   [(set (match_operand:SI 0 "register_operand" "")
14124         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
14125                          (match_operand:SI 2 "const8_operand" "")
14126                          (match_operand:SI 3 "const8_operand" "")))]
14127   ""
14128 {
14129   /* Handle extractions from %ah et al.  */
14130   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14131     FAIL;
14132
14133   /* From mips.md: extract_bit_field doesn't verify that our source
14134      matches the predicate, so check it again here.  */
14135   if (! ext_register_operand (operands[1], VOIDmode))
14136     FAIL;
14137 })
14138
14139 (define_expand "extzv"
14140   [(set (match_operand:SI 0 "register_operand" "")
14141         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
14142                          (match_operand:SI 2 "const8_operand" "")
14143                          (match_operand:SI 3 "const8_operand" "")))]
14144   ""
14145 {
14146   /* Handle extractions from %ah et al.  */
14147   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14148     FAIL;
14149
14150   /* From mips.md: extract_bit_field doesn't verify that our source
14151      matches the predicate, so check it again here.  */
14152   if (! ext_register_operand (operands[1], VOIDmode))
14153     FAIL;
14154 })
14155
14156 (define_expand "insv"
14157   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
14158                       (match_operand 1 "const8_operand" "")
14159                       (match_operand 2 "const8_operand" ""))
14160         (match_operand 3 "register_operand" ""))]
14161   ""
14162 {
14163   /* Handle insertions to %ah et al.  */
14164   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
14165     FAIL;
14166
14167   /* From mips.md: insert_bit_field doesn't verify that our source
14168      matches the predicate, so check it again here.  */
14169   if (! ext_register_operand (operands[0], VOIDmode))
14170     FAIL;
14171
14172   if (TARGET_64BIT)
14173     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
14174   else
14175     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
14176
14177   DONE;
14178 })
14179
14180 ;; %%% bts, btr, btc, bt.
14181 ;; In general these instructions are *slow* when applied to memory,
14182 ;; since they enforce atomic operation.  When applied to registers,
14183 ;; it depends on the cpu implementation.  They're never faster than
14184 ;; the corresponding and/ior/xor operations, so with 32-bit there's
14185 ;; no point.  But in 64-bit, we can't hold the relevant immediates
14186 ;; within the instruction itself, so operating on bits in the high
14187 ;; 32-bits of a register becomes easier.
14188 ;;
14189 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
14190 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
14191 ;; negdf respectively, so they can never be disabled entirely.
14192
14193 (define_insn "*btsq"
14194   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14195                          (const_int 1)
14196                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14197         (const_int 1))
14198    (clobber (reg:CC FLAGS_REG))]
14199   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14200   "bts{q}\t{%1, %0|%0, %1}"
14201   [(set_attr "type" "alu1")])
14202
14203 (define_insn "*btrq"
14204   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14205                          (const_int 1)
14206                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14207         (const_int 0))
14208    (clobber (reg:CC FLAGS_REG))]
14209   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14210   "btr{q}\t{%1, %0|%0, %1}"
14211   [(set_attr "type" "alu1")])
14212
14213 (define_insn "*btcq"
14214   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14215                          (const_int 1)
14216                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14217         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
14218    (clobber (reg:CC FLAGS_REG))]
14219   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14220   "btc{q}\t{%1, %0|%0, %1}"
14221   [(set_attr "type" "alu1")])
14222
14223 ;; Allow Nocona to avoid these instructions if a register is available.
14224
14225 (define_peephole2
14226   [(match_scratch:DI 2 "r")
14227    (parallel [(set (zero_extract:DI
14228                      (match_operand:DI 0 "register_operand" "")
14229                      (const_int 1)
14230                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14231                    (const_int 1))
14232               (clobber (reg:CC FLAGS_REG))])]
14233   "TARGET_64BIT && !TARGET_USE_BT"
14234   [(const_int 0)]
14235 {
14236   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14237   rtx op1;
14238
14239   if (HOST_BITS_PER_WIDE_INT >= 64)
14240     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14241   else if (i < HOST_BITS_PER_WIDE_INT)
14242     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14243   else
14244     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14245
14246   op1 = immed_double_const (lo, hi, DImode);
14247   if (i >= 31)
14248     {
14249       emit_move_insn (operands[2], op1);
14250       op1 = operands[2];
14251     }
14252
14253   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14254   DONE;
14255 })
14256
14257 (define_peephole2
14258   [(match_scratch:DI 2 "r")
14259    (parallel [(set (zero_extract:DI
14260                      (match_operand:DI 0 "register_operand" "")
14261                      (const_int 1)
14262                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14263                    (const_int 0))
14264               (clobber (reg:CC FLAGS_REG))])]
14265   "TARGET_64BIT && !TARGET_USE_BT"
14266   [(const_int 0)]
14267 {
14268   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14269   rtx op1;
14270
14271   if (HOST_BITS_PER_WIDE_INT >= 64)
14272     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14273   else if (i < HOST_BITS_PER_WIDE_INT)
14274     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14275   else
14276     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14277
14278   op1 = immed_double_const (~lo, ~hi, DImode);
14279   if (i >= 32)
14280     {
14281       emit_move_insn (operands[2], op1);
14282       op1 = operands[2];
14283     }
14284
14285   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14286   DONE;
14287 })
14288
14289 (define_peephole2
14290   [(match_scratch:DI 2 "r")
14291    (parallel [(set (zero_extract:DI
14292                      (match_operand:DI 0 "register_operand" "")
14293                      (const_int 1)
14294                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14295               (not:DI (zero_extract:DI
14296                         (match_dup 0) (const_int 1) (match_dup 1))))
14297               (clobber (reg:CC FLAGS_REG))])]
14298   "TARGET_64BIT && !TARGET_USE_BT"
14299   [(const_int 0)]
14300 {
14301   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14302   rtx op1;
14303
14304   if (HOST_BITS_PER_WIDE_INT >= 64)
14305     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14306   else if (i < HOST_BITS_PER_WIDE_INT)
14307     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14308   else
14309     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14310
14311   op1 = immed_double_const (lo, hi, DImode);
14312   if (i >= 31)
14313     {
14314       emit_move_insn (operands[2], op1);
14315       op1 = operands[2];
14316     }
14317
14318   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14319   DONE;
14320 })
14321
14322 (define_insn "*btdi_rex64"
14323   [(set (reg:CCC FLAGS_REG)
14324         (compare:CCC
14325           (zero_extract:DI
14326             (match_operand:DI 0 "register_operand" "r")
14327             (const_int 1)
14328             (match_operand:DI 1 "nonmemory_operand" "rN"))
14329           (const_int 0)))]
14330   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14331   "bt{q}\t{%1, %0|%0, %1}"
14332   [(set_attr "type" "alu1")])
14333
14334 (define_insn "*btsi"
14335   [(set (reg:CCC FLAGS_REG)
14336         (compare:CCC
14337           (zero_extract:SI
14338             (match_operand:SI 0 "register_operand" "r")
14339             (const_int 1)
14340             (match_operand:SI 1 "nonmemory_operand" "rN"))
14341           (const_int 0)))]
14342   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14343   "bt{l}\t{%1, %0|%0, %1}"
14344   [(set_attr "type" "alu1")])
14345 \f
14346 ;; Store-flag instructions.
14347
14348 ;; For all sCOND expanders, also expand the compare or test insn that
14349 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14350
14351 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14352 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14353 ;; way, which can later delete the movzx if only QImode is needed.
14354
14355 (define_insn "*setcc_1"
14356   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14357         (match_operator:QI 1 "ix86_comparison_operator"
14358           [(reg FLAGS_REG) (const_int 0)]))]
14359   ""
14360   "set%C1\t%0"
14361   [(set_attr "type" "setcc")
14362    (set_attr "mode" "QI")])
14363
14364 (define_insn "*setcc_2"
14365   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14366         (match_operator:QI 1 "ix86_comparison_operator"
14367           [(reg FLAGS_REG) (const_int 0)]))]
14368   ""
14369   "set%C1\t%0"
14370   [(set_attr "type" "setcc")
14371    (set_attr "mode" "QI")])
14372
14373 ;; In general it is not safe to assume too much about CCmode registers,
14374 ;; so simplify-rtx stops when it sees a second one.  Under certain
14375 ;; conditions this is safe on x86, so help combine not create
14376 ;;
14377 ;;      seta    %al
14378 ;;      testb   %al, %al
14379 ;;      sete    %al
14380
14381 (define_split
14382   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14383         (ne:QI (match_operator 1 "ix86_comparison_operator"
14384                  [(reg FLAGS_REG) (const_int 0)])
14385             (const_int 0)))]
14386   ""
14387   [(set (match_dup 0) (match_dup 1))]
14388 {
14389   PUT_MODE (operands[1], QImode);
14390 })
14391
14392 (define_split
14393   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14394         (ne:QI (match_operator 1 "ix86_comparison_operator"
14395                  [(reg FLAGS_REG) (const_int 0)])
14396             (const_int 0)))]
14397   ""
14398   [(set (match_dup 0) (match_dup 1))]
14399 {
14400   PUT_MODE (operands[1], QImode);
14401 })
14402
14403 (define_split
14404   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14405         (eq:QI (match_operator 1 "ix86_comparison_operator"
14406                  [(reg FLAGS_REG) (const_int 0)])
14407             (const_int 0)))]
14408   ""
14409   [(set (match_dup 0) (match_dup 1))]
14410 {
14411   rtx new_op1 = copy_rtx (operands[1]);
14412   operands[1] = new_op1;
14413   PUT_MODE (new_op1, QImode);
14414   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14415                                              GET_MODE (XEXP (new_op1, 0))));
14416
14417   /* Make sure that (a) the CCmode we have for the flags is strong
14418      enough for the reversed compare or (b) we have a valid FP compare.  */
14419   if (! ix86_comparison_operator (new_op1, VOIDmode))
14420     FAIL;
14421 })
14422
14423 (define_split
14424   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14425         (eq:QI (match_operator 1 "ix86_comparison_operator"
14426                  [(reg FLAGS_REG) (const_int 0)])
14427             (const_int 0)))]
14428   ""
14429   [(set (match_dup 0) (match_dup 1))]
14430 {
14431   rtx new_op1 = copy_rtx (operands[1]);
14432   operands[1] = new_op1;
14433   PUT_MODE (new_op1, QImode);
14434   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14435                                              GET_MODE (XEXP (new_op1, 0))));
14436
14437   /* Make sure that (a) the CCmode we have for the flags is strong
14438      enough for the reversed compare or (b) we have a valid FP compare.  */
14439   if (! ix86_comparison_operator (new_op1, VOIDmode))
14440     FAIL;
14441 })
14442
14443 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14444 ;; subsequent logical operations are used to imitate conditional moves.
14445 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14446 ;; it directly.
14447
14448 (define_insn "*avx_setcc<mode>"
14449   [(set (match_operand:MODEF 0 "register_operand" "=x")
14450         (match_operator:MODEF 1 "avx_comparison_float_operator"
14451           [(match_operand:MODEF 2 "register_operand" "x")
14452            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14453   "TARGET_AVX"
14454   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14455   [(set_attr "type" "ssecmp")
14456    (set_attr "prefix" "vex")
14457    (set_attr "mode" "<MODE>")])
14458
14459 (define_insn "*sse_setcc<mode>"
14460   [(set (match_operand:MODEF 0 "register_operand" "=x")
14461         (match_operator:MODEF 1 "sse_comparison_operator"
14462           [(match_operand:MODEF 2 "register_operand" "0")
14463            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14464   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14465   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14466   [(set_attr "type" "ssecmp")
14467    (set_attr "mode" "<MODE>")])
14468
14469 (define_insn "*sse5_setcc<mode>"
14470   [(set (match_operand:MODEF 0 "register_operand" "=x")
14471         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14472           [(match_operand:MODEF 2 "register_operand" "x")
14473            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14474   "TARGET_SSE5"
14475   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14476   [(set_attr "type" "sse4arg")
14477    (set_attr "mode" "<MODE>")])
14478
14479 \f
14480 ;; Basic conditional jump instructions.
14481 ;; We ignore the overflow flag for signed branch instructions.
14482
14483 (define_insn "*jcc_1"
14484   [(set (pc)
14485         (if_then_else (match_operator 1 "ix86_comparison_operator"
14486                                       [(reg FLAGS_REG) (const_int 0)])
14487                       (label_ref (match_operand 0 "" ""))
14488                       (pc)))]
14489   ""
14490   "%+j%C1\t%l0"
14491   [(set_attr "type" "ibr")
14492    (set_attr "modrm" "0")
14493    (set (attr "length")
14494            (if_then_else (and (ge (minus (match_dup 0) (pc))
14495                                   (const_int -126))
14496                               (lt (minus (match_dup 0) (pc))
14497                                   (const_int 128)))
14498              (const_int 2)
14499              (const_int 6)))])
14500
14501 (define_insn "*jcc_2"
14502   [(set (pc)
14503         (if_then_else (match_operator 1 "ix86_comparison_operator"
14504                                       [(reg FLAGS_REG) (const_int 0)])
14505                       (pc)
14506                       (label_ref (match_operand 0 "" ""))))]
14507   ""
14508   "%+j%c1\t%l0"
14509   [(set_attr "type" "ibr")
14510    (set_attr "modrm" "0")
14511    (set (attr "length")
14512            (if_then_else (and (ge (minus (match_dup 0) (pc))
14513                                   (const_int -126))
14514                               (lt (minus (match_dup 0) (pc))
14515                                   (const_int 128)))
14516              (const_int 2)
14517              (const_int 6)))])
14518
14519 ;; In general it is not safe to assume too much about CCmode registers,
14520 ;; so simplify-rtx stops when it sees a second one.  Under certain
14521 ;; conditions this is safe on x86, so help combine not create
14522 ;;
14523 ;;      seta    %al
14524 ;;      testb   %al, %al
14525 ;;      je      Lfoo
14526
14527 (define_split
14528   [(set (pc)
14529         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14530                                       [(reg FLAGS_REG) (const_int 0)])
14531                           (const_int 0))
14532                       (label_ref (match_operand 1 "" ""))
14533                       (pc)))]
14534   ""
14535   [(set (pc)
14536         (if_then_else (match_dup 0)
14537                       (label_ref (match_dup 1))
14538                       (pc)))]
14539 {
14540   PUT_MODE (operands[0], VOIDmode);
14541 })
14542
14543 (define_split
14544   [(set (pc)
14545         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14546                                       [(reg FLAGS_REG) (const_int 0)])
14547                           (const_int 0))
14548                       (label_ref (match_operand 1 "" ""))
14549                       (pc)))]
14550   ""
14551   [(set (pc)
14552         (if_then_else (match_dup 0)
14553                       (label_ref (match_dup 1))
14554                       (pc)))]
14555 {
14556   rtx new_op0 = copy_rtx (operands[0]);
14557   operands[0] = new_op0;
14558   PUT_MODE (new_op0, VOIDmode);
14559   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14560                                              GET_MODE (XEXP (new_op0, 0))));
14561
14562   /* Make sure that (a) the CCmode we have for the flags is strong
14563      enough for the reversed compare or (b) we have a valid FP compare.  */
14564   if (! ix86_comparison_operator (new_op0, VOIDmode))
14565     FAIL;
14566 })
14567
14568 ;; zero_extend in SImode is correct, since this is what combine pass
14569 ;; generates from shift insn with QImode operand.  Actually, the mode of
14570 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14571 ;; appropriate modulo of the bit offset value.
14572
14573 (define_insn_and_split "*jcc_btdi_rex64"
14574   [(set (pc)
14575         (if_then_else (match_operator 0 "bt_comparison_operator"
14576                         [(zero_extract:DI
14577                            (match_operand:DI 1 "register_operand" "r")
14578                            (const_int 1)
14579                            (zero_extend:SI
14580                              (match_operand:QI 2 "register_operand" "r")))
14581                          (const_int 0)])
14582                       (label_ref (match_operand 3 "" ""))
14583                       (pc)))
14584    (clobber (reg:CC FLAGS_REG))]
14585   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14586   "#"
14587   "&& 1"
14588   [(set (reg:CCC FLAGS_REG)
14589         (compare:CCC
14590           (zero_extract:DI
14591             (match_dup 1)
14592             (const_int 1)
14593             (match_dup 2))
14594           (const_int 0)))
14595    (set (pc)
14596         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14597                       (label_ref (match_dup 3))
14598                       (pc)))]
14599 {
14600   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14601
14602   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14603 })
14604
14605 ;; avoid useless masking of bit offset operand
14606 (define_insn_and_split "*jcc_btdi_mask_rex64"
14607   [(set (pc)
14608         (if_then_else (match_operator 0 "bt_comparison_operator"
14609                         [(zero_extract:DI
14610                            (match_operand:DI 1 "register_operand" "r")
14611                            (const_int 1)
14612                            (and:SI
14613                              (match_operand:SI 2 "register_operand" "r")
14614                              (match_operand:SI 3 "const_int_operand" "n")))])
14615                       (label_ref (match_operand 4 "" ""))
14616                       (pc)))
14617    (clobber (reg:CC FLAGS_REG))]
14618   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14619    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14620   "#"
14621   "&& 1"
14622   [(set (reg:CCC FLAGS_REG)
14623         (compare:CCC
14624           (zero_extract:DI
14625             (match_dup 1)
14626             (const_int 1)
14627             (match_dup 2))
14628           (const_int 0)))
14629    (set (pc)
14630         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14631                       (label_ref (match_dup 4))
14632                       (pc)))]
14633 {
14634   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14635
14636   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14637 })
14638
14639 (define_insn_and_split "*jcc_btsi"
14640   [(set (pc)
14641         (if_then_else (match_operator 0 "bt_comparison_operator"
14642                         [(zero_extract:SI
14643                            (match_operand:SI 1 "register_operand" "r")
14644                            (const_int 1)
14645                            (zero_extend:SI
14646                              (match_operand:QI 2 "register_operand" "r")))
14647                          (const_int 0)])
14648                       (label_ref (match_operand 3 "" ""))
14649                       (pc)))
14650    (clobber (reg:CC FLAGS_REG))]
14651   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14652   "#"
14653   "&& 1"
14654   [(set (reg:CCC FLAGS_REG)
14655         (compare:CCC
14656           (zero_extract:SI
14657             (match_dup 1)
14658             (const_int 1)
14659             (match_dup 2))
14660           (const_int 0)))
14661    (set (pc)
14662         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14663                       (label_ref (match_dup 3))
14664                       (pc)))]
14665 {
14666   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14667
14668   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14669 })
14670
14671 ;; avoid useless masking of bit offset operand
14672 (define_insn_and_split "*jcc_btsi_mask"
14673   [(set (pc)
14674         (if_then_else (match_operator 0 "bt_comparison_operator"
14675                         [(zero_extract:SI
14676                            (match_operand:SI 1 "register_operand" "r")
14677                            (const_int 1)
14678                            (and:SI
14679                              (match_operand:SI 2 "register_operand" "r")
14680                              (match_operand:SI 3 "const_int_operand" "n")))])
14681                       (label_ref (match_operand 4 "" ""))
14682                       (pc)))
14683    (clobber (reg:CC FLAGS_REG))]
14684   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14685    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14686   "#"
14687   "&& 1"
14688   [(set (reg:CCC FLAGS_REG)
14689         (compare:CCC
14690           (zero_extract:SI
14691             (match_dup 1)
14692             (const_int 1)
14693             (match_dup 2))
14694           (const_int 0)))
14695    (set (pc)
14696         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14697                       (label_ref (match_dup 4))
14698                       (pc)))]
14699   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14700
14701 (define_insn_and_split "*jcc_btsi_1"
14702   [(set (pc)
14703         (if_then_else (match_operator 0 "bt_comparison_operator"
14704                         [(and:SI
14705                            (lshiftrt:SI
14706                              (match_operand:SI 1 "register_operand" "r")
14707                              (match_operand:QI 2 "register_operand" "r"))
14708                            (const_int 1))
14709                          (const_int 0)])
14710                       (label_ref (match_operand 3 "" ""))
14711                       (pc)))
14712    (clobber (reg:CC FLAGS_REG))]
14713   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14714   "#"
14715   "&& 1"
14716   [(set (reg:CCC FLAGS_REG)
14717         (compare:CCC
14718           (zero_extract:SI
14719             (match_dup 1)
14720             (const_int 1)
14721             (match_dup 2))
14722           (const_int 0)))
14723    (set (pc)
14724         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14725                       (label_ref (match_dup 3))
14726                       (pc)))]
14727 {
14728   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14729
14730   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14731 })
14732
14733 ;; avoid useless masking of bit offset operand
14734 (define_insn_and_split "*jcc_btsi_mask_1"
14735   [(set (pc)
14736         (if_then_else
14737           (match_operator 0 "bt_comparison_operator"
14738             [(and:SI
14739                (lshiftrt:SI
14740                  (match_operand:SI 1 "register_operand" "r")
14741                  (subreg:QI
14742                    (and:SI
14743                      (match_operand:SI 2 "register_operand" "r")
14744                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14745                (const_int 1))
14746              (const_int 0)])
14747           (label_ref (match_operand 4 "" ""))
14748           (pc)))
14749    (clobber (reg:CC FLAGS_REG))]
14750   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14751    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14752   "#"
14753   "&& 1"
14754   [(set (reg:CCC FLAGS_REG)
14755         (compare:CCC
14756           (zero_extract:SI
14757             (match_dup 1)
14758             (const_int 1)
14759             (match_dup 2))
14760           (const_int 0)))
14761    (set (pc)
14762         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14763                       (label_ref (match_dup 4))
14764                       (pc)))]
14765   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14766
14767 ;; Define combination compare-and-branch fp compare instructions to use
14768 ;; during early optimization.  Splitting the operation apart early makes
14769 ;; for bad code when we want to reverse the operation.
14770
14771 (define_insn "*fp_jcc_1_mixed"
14772   [(set (pc)
14773         (if_then_else (match_operator 0 "comparison_operator"
14774                         [(match_operand 1 "register_operand" "f,x")
14775                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14776           (label_ref (match_operand 3 "" ""))
14777           (pc)))
14778    (clobber (reg:CCFP FPSR_REG))
14779    (clobber (reg:CCFP FLAGS_REG))]
14780   "TARGET_MIX_SSE_I387
14781    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14782    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14783    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14784   "#")
14785
14786 (define_insn "*fp_jcc_1_sse"
14787   [(set (pc)
14788         (if_then_else (match_operator 0 "comparison_operator"
14789                         [(match_operand 1 "register_operand" "x")
14790                          (match_operand 2 "nonimmediate_operand" "xm")])
14791           (label_ref (match_operand 3 "" ""))
14792           (pc)))
14793    (clobber (reg:CCFP FPSR_REG))
14794    (clobber (reg:CCFP FLAGS_REG))]
14795   "TARGET_SSE_MATH
14796    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14797    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14798    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14799   "#")
14800
14801 (define_insn "*fp_jcc_1_387"
14802   [(set (pc)
14803         (if_then_else (match_operator 0 "comparison_operator"
14804                         [(match_operand 1 "register_operand" "f")
14805                          (match_operand 2 "register_operand" "f")])
14806           (label_ref (match_operand 3 "" ""))
14807           (pc)))
14808    (clobber (reg:CCFP FPSR_REG))
14809    (clobber (reg:CCFP FLAGS_REG))]
14810   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14811    && TARGET_CMOVE
14812    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14813    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14814   "#")
14815
14816 (define_insn "*fp_jcc_2_mixed"
14817   [(set (pc)
14818         (if_then_else (match_operator 0 "comparison_operator"
14819                         [(match_operand 1 "register_operand" "f,x")
14820                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14821           (pc)
14822           (label_ref (match_operand 3 "" ""))))
14823    (clobber (reg:CCFP FPSR_REG))
14824    (clobber (reg:CCFP FLAGS_REG))]
14825   "TARGET_MIX_SSE_I387
14826    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14827    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14828    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14829   "#")
14830
14831 (define_insn "*fp_jcc_2_sse"
14832   [(set (pc)
14833         (if_then_else (match_operator 0 "comparison_operator"
14834                         [(match_operand 1 "register_operand" "x")
14835                          (match_operand 2 "nonimmediate_operand" "xm")])
14836           (pc)
14837           (label_ref (match_operand 3 "" ""))))
14838    (clobber (reg:CCFP FPSR_REG))
14839    (clobber (reg:CCFP FLAGS_REG))]
14840   "TARGET_SSE_MATH
14841    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14842    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14843    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14844   "#")
14845
14846 (define_insn "*fp_jcc_2_387"
14847   [(set (pc)
14848         (if_then_else (match_operator 0 "comparison_operator"
14849                         [(match_operand 1 "register_operand" "f")
14850                          (match_operand 2 "register_operand" "f")])
14851           (pc)
14852           (label_ref (match_operand 3 "" ""))))
14853    (clobber (reg:CCFP FPSR_REG))
14854    (clobber (reg:CCFP FLAGS_REG))]
14855   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14856    && TARGET_CMOVE
14857    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14858    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14859   "#")
14860
14861 (define_insn "*fp_jcc_3_387"
14862   [(set (pc)
14863         (if_then_else (match_operator 0 "comparison_operator"
14864                         [(match_operand 1 "register_operand" "f")
14865                          (match_operand 2 "nonimmediate_operand" "fm")])
14866           (label_ref (match_operand 3 "" ""))
14867           (pc)))
14868    (clobber (reg:CCFP FPSR_REG))
14869    (clobber (reg:CCFP FLAGS_REG))
14870    (clobber (match_scratch:HI 4 "=a"))]
14871   "TARGET_80387
14872    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14873    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14874    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14875    && SELECT_CC_MODE (GET_CODE (operands[0]),
14876                       operands[1], operands[2]) == CCFPmode
14877    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14878   "#")
14879
14880 (define_insn "*fp_jcc_4_387"
14881   [(set (pc)
14882         (if_then_else (match_operator 0 "comparison_operator"
14883                         [(match_operand 1 "register_operand" "f")
14884                          (match_operand 2 "nonimmediate_operand" "fm")])
14885           (pc)
14886           (label_ref (match_operand 3 "" ""))))
14887    (clobber (reg:CCFP FPSR_REG))
14888    (clobber (reg:CCFP FLAGS_REG))
14889    (clobber (match_scratch:HI 4 "=a"))]
14890   "TARGET_80387
14891    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14892    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14893    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14894    && SELECT_CC_MODE (GET_CODE (operands[0]),
14895                       operands[1], operands[2]) == CCFPmode
14896    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14897   "#")
14898
14899 (define_insn "*fp_jcc_5_387"
14900   [(set (pc)
14901         (if_then_else (match_operator 0 "comparison_operator"
14902                         [(match_operand 1 "register_operand" "f")
14903                          (match_operand 2 "register_operand" "f")])
14904           (label_ref (match_operand 3 "" ""))
14905           (pc)))
14906    (clobber (reg:CCFP FPSR_REG))
14907    (clobber (reg:CCFP FLAGS_REG))
14908    (clobber (match_scratch:HI 4 "=a"))]
14909   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14910    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14911    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14912   "#")
14913
14914 (define_insn "*fp_jcc_6_387"
14915   [(set (pc)
14916         (if_then_else (match_operator 0 "comparison_operator"
14917                         [(match_operand 1 "register_operand" "f")
14918                          (match_operand 2 "register_operand" "f")])
14919           (pc)
14920           (label_ref (match_operand 3 "" ""))))
14921    (clobber (reg:CCFP FPSR_REG))
14922    (clobber (reg:CCFP FLAGS_REG))
14923    (clobber (match_scratch:HI 4 "=a"))]
14924   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14925    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14926    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14927   "#")
14928
14929 (define_insn "*fp_jcc_7_387"
14930   [(set (pc)
14931         (if_then_else (match_operator 0 "comparison_operator"
14932                         [(match_operand 1 "register_operand" "f")
14933                          (match_operand 2 "const0_operand" "")])
14934           (label_ref (match_operand 3 "" ""))
14935           (pc)))
14936    (clobber (reg:CCFP FPSR_REG))
14937    (clobber (reg:CCFP FLAGS_REG))
14938    (clobber (match_scratch:HI 4 "=a"))]
14939   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14940    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14941    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14942    && SELECT_CC_MODE (GET_CODE (operands[0]),
14943                       operands[1], operands[2]) == CCFPmode
14944    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14945   "#")
14946
14947 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14948 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14949 ;; with a precedence over other operators and is always put in the first
14950 ;; place. Swap condition and operands to match ficom instruction.
14951
14952 (define_insn "*fp_jcc_8<mode>_387"
14953   [(set (pc)
14954         (if_then_else (match_operator 0 "comparison_operator"
14955                         [(match_operator 1 "float_operator"
14956                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14957                            (match_operand 3 "register_operand" "f,f")])
14958           (label_ref (match_operand 4 "" ""))
14959           (pc)))
14960    (clobber (reg:CCFP FPSR_REG))
14961    (clobber (reg:CCFP FLAGS_REG))
14962    (clobber (match_scratch:HI 5 "=a,a"))]
14963   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14964    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14965    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14966    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14967    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14968    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14969   "#")
14970
14971 (define_split
14972   [(set (pc)
14973         (if_then_else (match_operator 0 "comparison_operator"
14974                         [(match_operand 1 "register_operand" "")
14975                          (match_operand 2 "nonimmediate_operand" "")])
14976           (match_operand 3 "" "")
14977           (match_operand 4 "" "")))
14978    (clobber (reg:CCFP FPSR_REG))
14979    (clobber (reg:CCFP FLAGS_REG))]
14980   "reload_completed"
14981   [(const_int 0)]
14982 {
14983   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14984                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14985   DONE;
14986 })
14987
14988 (define_split
14989   [(set (pc)
14990         (if_then_else (match_operator 0 "comparison_operator"
14991                         [(match_operand 1 "register_operand" "")
14992                          (match_operand 2 "general_operand" "")])
14993           (match_operand 3 "" "")
14994           (match_operand 4 "" "")))
14995    (clobber (reg:CCFP FPSR_REG))
14996    (clobber (reg:CCFP FLAGS_REG))
14997    (clobber (match_scratch:HI 5 "=a"))]
14998   "reload_completed"
14999   [(const_int 0)]
15000 {
15001   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15002                         operands[3], operands[4], operands[5], NULL_RTX);
15003   DONE;
15004 })
15005
15006 (define_split
15007   [(set (pc)
15008         (if_then_else (match_operator 0 "comparison_operator"
15009                         [(match_operator 1 "float_operator"
15010                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
15011                            (match_operand 3 "register_operand" "")])
15012           (match_operand 4 "" "")
15013           (match_operand 5 "" "")))
15014    (clobber (reg:CCFP FPSR_REG))
15015    (clobber (reg:CCFP FLAGS_REG))
15016    (clobber (match_scratch:HI 6 "=a"))]
15017   "reload_completed"
15018   [(const_int 0)]
15019 {
15020   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
15021   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15022                         operands[3], operands[7],
15023                         operands[4], operands[5], operands[6], NULL_RTX);
15024   DONE;
15025 })
15026
15027 ;; %%% Kill this when reload knows how to do it.
15028 (define_split
15029   [(set (pc)
15030         (if_then_else (match_operator 0 "comparison_operator"
15031                         [(match_operator 1 "float_operator"
15032                            [(match_operand:X87MODEI12 2 "register_operand" "")])
15033                            (match_operand 3 "register_operand" "")])
15034           (match_operand 4 "" "")
15035           (match_operand 5 "" "")))
15036    (clobber (reg:CCFP FPSR_REG))
15037    (clobber (reg:CCFP FLAGS_REG))
15038    (clobber (match_scratch:HI 6 "=a"))]
15039   "reload_completed"
15040   [(const_int 0)]
15041 {
15042   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15043   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
15044   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15045                         operands[3], operands[7],
15046                         operands[4], operands[5], operands[6], operands[2]);
15047   DONE;
15048 })
15049 \f
15050 ;; Unconditional and other jump instructions
15051
15052 (define_insn "jump"
15053   [(set (pc)
15054         (label_ref (match_operand 0 "" "")))]
15055   ""
15056   "jmp\t%l0"
15057   [(set_attr "type" "ibr")
15058    (set (attr "length")
15059            (if_then_else (and (ge (minus (match_dup 0) (pc))
15060                                   (const_int -126))
15061                               (lt (minus (match_dup 0) (pc))
15062                                   (const_int 128)))
15063              (const_int 2)
15064              (const_int 5)))
15065    (set_attr "modrm" "0")])
15066
15067 (define_expand "indirect_jump"
15068   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
15069   ""
15070   "")
15071
15072 (define_insn "*indirect_jump"
15073   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
15074   ""
15075   "jmp\t%A0"
15076   [(set_attr "type" "ibr")
15077    (set_attr "length_immediate" "0")])
15078
15079 (define_expand "tablejump"
15080   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
15081               (use (label_ref (match_operand 1 "" "")))])]
15082   ""
15083 {
15084   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
15085      relative.  Convert the relative address to an absolute address.  */
15086   if (flag_pic)
15087     {
15088       rtx op0, op1;
15089       enum rtx_code code;
15090
15091       /* We can't use @GOTOFF for text labels on VxWorks;
15092          see gotoff_operand.  */
15093       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
15094         {
15095           code = PLUS;
15096           op0 = operands[0];
15097           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
15098         }
15099       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
15100         {
15101           code = PLUS;
15102           op0 = operands[0];
15103           op1 = pic_offset_table_rtx;
15104         }
15105       else
15106         {
15107           code = MINUS;
15108           op0 = pic_offset_table_rtx;
15109           op1 = operands[0];
15110         }
15111
15112       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
15113                                          OPTAB_DIRECT);
15114     }
15115 })
15116
15117 (define_insn "*tablejump_1"
15118   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
15119    (use (label_ref (match_operand 1 "" "")))]
15120   ""
15121   "jmp\t%A0"
15122   [(set_attr "type" "ibr")
15123    (set_attr "length_immediate" "0")])
15124 \f
15125 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
15126
15127 (define_peephole2
15128   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15129    (set (match_operand:QI 1 "register_operand" "")
15130         (match_operator:QI 2 "ix86_comparison_operator"
15131           [(reg FLAGS_REG) (const_int 0)]))
15132    (set (match_operand 3 "q_regs_operand" "")
15133         (zero_extend (match_dup 1)))]
15134   "(peep2_reg_dead_p (3, operands[1])
15135     || operands_match_p (operands[1], operands[3]))
15136    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15137   [(set (match_dup 4) (match_dup 0))
15138    (set (strict_low_part (match_dup 5))
15139         (match_dup 2))]
15140 {
15141   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15142   operands[5] = gen_lowpart (QImode, operands[3]);
15143   ix86_expand_clear (operands[3]);
15144 })
15145
15146 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
15147
15148 (define_peephole2
15149   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15150    (set (match_operand:QI 1 "register_operand" "")
15151         (match_operator:QI 2 "ix86_comparison_operator"
15152           [(reg FLAGS_REG) (const_int 0)]))
15153    (parallel [(set (match_operand 3 "q_regs_operand" "")
15154                    (zero_extend (match_dup 1)))
15155               (clobber (reg:CC FLAGS_REG))])]
15156   "(peep2_reg_dead_p (3, operands[1])
15157     || operands_match_p (operands[1], operands[3]))
15158    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15159   [(set (match_dup 4) (match_dup 0))
15160    (set (strict_low_part (match_dup 5))
15161         (match_dup 2))]
15162 {
15163   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15164   operands[5] = gen_lowpart (QImode, operands[3]);
15165   ix86_expand_clear (operands[3]);
15166 })
15167 \f
15168 ;; Call instructions.
15169
15170 ;; The predicates normally associated with named expanders are not properly
15171 ;; checked for calls.  This is a bug in the generic code, but it isn't that
15172 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
15173
15174 ;; Call subroutine returning no value.
15175
15176 (define_expand "call_pop"
15177   [(parallel [(call (match_operand:QI 0 "" "")
15178                     (match_operand:SI 1 "" ""))
15179               (set (reg:SI SP_REG)
15180                    (plus:SI (reg:SI SP_REG)
15181                             (match_operand:SI 3 "" "")))])]
15182   "!TARGET_64BIT"
15183 {
15184   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
15185   DONE;
15186 })
15187
15188 (define_insn "*call_pop_0"
15189   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
15190          (match_operand:SI 1 "" ""))
15191    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15192                             (match_operand:SI 2 "immediate_operand" "")))]
15193   "!TARGET_64BIT"
15194 {
15195   if (SIBLING_CALL_P (insn))
15196     return "jmp\t%P0";
15197   else
15198     return "call\t%P0";
15199 }
15200   [(set_attr "type" "call")])
15201
15202 (define_insn "*call_pop_1"
15203   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15204          (match_operand:SI 1 "" ""))
15205    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15206                             (match_operand:SI 2 "immediate_operand" "i")))]
15207   "!TARGET_64BIT"
15208 {
15209   if (constant_call_address_operand (operands[0], Pmode))
15210     {
15211       if (SIBLING_CALL_P (insn))
15212         return "jmp\t%P0";
15213       else
15214         return "call\t%P0";
15215     }
15216   if (SIBLING_CALL_P (insn))
15217     return "jmp\t%A0";
15218   else
15219     return "call\t%A0";
15220 }
15221   [(set_attr "type" "call")])
15222
15223 (define_expand "call"
15224   [(call (match_operand:QI 0 "" "")
15225          (match_operand 1 "" ""))
15226    (use (match_operand 2 "" ""))]
15227   ""
15228 {
15229   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15230   DONE;
15231 })
15232
15233 (define_expand "sibcall"
15234   [(call (match_operand:QI 0 "" "")
15235          (match_operand 1 "" ""))
15236    (use (match_operand 2 "" ""))]
15237   ""
15238 {
15239   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15240   DONE;
15241 })
15242
15243 (define_insn "*call_0"
15244   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15245          (match_operand 1 "" ""))]
15246   ""
15247 {
15248   if (SIBLING_CALL_P (insn))
15249     return "jmp\t%P0";
15250   else
15251     return "call\t%P0";
15252 }
15253   [(set_attr "type" "call")])
15254
15255 (define_insn "*call_1"
15256   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15257          (match_operand 1 "" ""))]
15258   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15259 {
15260   if (constant_call_address_operand (operands[0], Pmode))
15261     return "call\t%P0";
15262   return "call\t%A0";
15263 }
15264   [(set_attr "type" "call")])
15265
15266 (define_insn "*sibcall_1"
15267   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15268          (match_operand 1 "" ""))]
15269   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15270 {
15271   if (constant_call_address_operand (operands[0], Pmode))
15272     return "jmp\t%P0";
15273   return "jmp\t%A0";
15274 }
15275   [(set_attr "type" "call")])
15276
15277 (define_insn "*call_1_rex64"
15278   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15279          (match_operand 1 "" ""))]
15280   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15281    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15282 {
15283   if (constant_call_address_operand (operands[0], Pmode))
15284     return "call\t%P0";
15285   return "call\t%A0";
15286 }
15287   [(set_attr "type" "call")])
15288
15289 (define_insn "*call_1_rex64_ms_sysv"
15290   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15291          (match_operand 1 "" ""))
15292    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15293    (clobber (reg:TI XMM6_REG))
15294    (clobber (reg:TI XMM7_REG))
15295    (clobber (reg:TI XMM8_REG))
15296    (clobber (reg:TI XMM9_REG))
15297    (clobber (reg:TI XMM10_REG))
15298    (clobber (reg:TI XMM11_REG))
15299    (clobber (reg:TI XMM12_REG))
15300    (clobber (reg:TI XMM13_REG))
15301    (clobber (reg:TI XMM14_REG))
15302    (clobber (reg:TI XMM15_REG))
15303    (clobber (reg:DI SI_REG))
15304    (clobber (reg:DI DI_REG))]
15305   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15306 {
15307   if (constant_call_address_operand (operands[0], Pmode))
15308     return "call\t%P0";
15309   return "call\t%A0";
15310 }
15311   [(set_attr "type" "call")])
15312
15313 (define_insn "*call_1_rex64_large"
15314   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15315          (match_operand 1 "" ""))]
15316   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15317   "call\t%A0"
15318   [(set_attr "type" "call")])
15319
15320 (define_insn "*sibcall_1_rex64"
15321   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15322          (match_operand 1 "" ""))]
15323   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15324   "jmp\t%P0"
15325   [(set_attr "type" "call")])
15326
15327 (define_insn "*sibcall_1_rex64_v"
15328   [(call (mem:QI (reg:DI R11_REG))
15329          (match_operand 0 "" ""))]
15330   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15331   "jmp\t{*%%}r11"
15332   [(set_attr "type" "call")])
15333
15334
15335 ;; Call subroutine, returning value in operand 0
15336
15337 (define_expand "call_value_pop"
15338   [(parallel [(set (match_operand 0 "" "")
15339                    (call (match_operand:QI 1 "" "")
15340                          (match_operand:SI 2 "" "")))
15341               (set (reg:SI SP_REG)
15342                    (plus:SI (reg:SI SP_REG)
15343                             (match_operand:SI 4 "" "")))])]
15344   "!TARGET_64BIT"
15345 {
15346   ix86_expand_call (operands[0], operands[1], operands[2],
15347                     operands[3], operands[4], 0);
15348   DONE;
15349 })
15350
15351 (define_expand "call_value"
15352   [(set (match_operand 0 "" "")
15353         (call (match_operand:QI 1 "" "")
15354               (match_operand:SI 2 "" "")))
15355    (use (match_operand:SI 3 "" ""))]
15356   ;; Operand 2 not used on the i386.
15357   ""
15358 {
15359   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15360   DONE;
15361 })
15362
15363 (define_expand "sibcall_value"
15364   [(set (match_operand 0 "" "")
15365         (call (match_operand:QI 1 "" "")
15366               (match_operand:SI 2 "" "")))
15367    (use (match_operand:SI 3 "" ""))]
15368   ;; Operand 2 not used on the i386.
15369   ""
15370 {
15371   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15372   DONE;
15373 })
15374
15375 ;; Call subroutine returning any type.
15376
15377 (define_expand "untyped_call"
15378   [(parallel [(call (match_operand 0 "" "")
15379                     (const_int 0))
15380               (match_operand 1 "" "")
15381               (match_operand 2 "" "")])]
15382   ""
15383 {
15384   int i;
15385
15386   /* In order to give reg-stack an easier job in validating two
15387      coprocessor registers as containing a possible return value,
15388      simply pretend the untyped call returns a complex long double
15389      value. 
15390
15391      We can't use SSE_REGPARM_MAX here since callee is unprototyped
15392      and should have the default ABI.  */
15393
15394   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15395                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15396                     operands[0], const0_rtx,
15397                     GEN_INT ((TARGET_64BIT
15398                               ? (ix86_abi == SYSV_ABI
15399                                  ? X86_64_SSE_REGPARM_MAX
15400                                  : X64_SSE_REGPARM_MAX)
15401                               : X86_32_SSE_REGPARM_MAX)
15402                              - 1),
15403                     NULL, 0);
15404
15405   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15406     {
15407       rtx set = XVECEXP (operands[2], 0, i);
15408       emit_move_insn (SET_DEST (set), SET_SRC (set));
15409     }
15410
15411   /* The optimizer does not know that the call sets the function value
15412      registers we stored in the result block.  We avoid problems by
15413      claiming that all hard registers are used and clobbered at this
15414      point.  */
15415   emit_insn (gen_blockage ());
15416
15417   DONE;
15418 })
15419 \f
15420 ;; Prologue and epilogue instructions
15421
15422 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15423 ;; all of memory.  This blocks insns from being moved across this point.
15424
15425 (define_insn "blockage"
15426   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15427   ""
15428   ""
15429   [(set_attr "length" "0")])
15430
15431 ;; Do not schedule instructions accessing memory across this point.
15432
15433 (define_expand "memory_blockage"
15434   [(set (match_dup 0)
15435         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15436   ""
15437 {
15438   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15439   MEM_VOLATILE_P (operands[0]) = 1;
15440 })
15441
15442 (define_insn "*memory_blockage"
15443   [(set (match_operand:BLK 0 "" "")
15444         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15445   ""
15446   ""
15447   [(set_attr "length" "0")])
15448
15449 ;; As USE insns aren't meaningful after reload, this is used instead
15450 ;; to prevent deleting instructions setting registers for PIC code
15451 (define_insn "prologue_use"
15452   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15453   ""
15454   ""
15455   [(set_attr "length" "0")])
15456
15457 ;; Insn emitted into the body of a function to return from a function.
15458 ;; This is only done if the function's epilogue is known to be simple.
15459 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15460
15461 (define_expand "return"
15462   [(return)]
15463   "ix86_can_use_return_insn_p ()"
15464 {
15465   if (crtl->args.pops_args)
15466     {
15467       rtx popc = GEN_INT (crtl->args.pops_args);
15468       emit_jump_insn (gen_return_pop_internal (popc));
15469       DONE;
15470     }
15471 })
15472
15473 (define_insn "return_internal"
15474   [(return)]
15475   "reload_completed"
15476   "ret"
15477   [(set_attr "length" "1")
15478    (set_attr "atom_unit" "jeu")
15479    (set_attr "length_immediate" "0")
15480    (set_attr "modrm" "0")])
15481
15482 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15483 ;; instruction Athlon and K8 have.
15484
15485 (define_insn "return_internal_long"
15486   [(return)
15487    (unspec [(const_int 0)] UNSPEC_REP)]
15488   "reload_completed"
15489   "rep\;ret"
15490   [(set_attr "length" "1")
15491    (set_attr "atom_unit" "jeu")
15492    (set_attr "length_immediate" "0")
15493    (set_attr "prefix_rep" "1")
15494    (set_attr "modrm" "0")])
15495
15496 (define_insn "return_pop_internal"
15497   [(return)
15498    (use (match_operand:SI 0 "const_int_operand" ""))]
15499   "reload_completed"
15500   "ret\t%0"
15501   [(set_attr "length" "3")
15502    (set_attr "atom_unit" "jeu")
15503    (set_attr "length_immediate" "2")
15504    (set_attr "modrm" "0")])
15505
15506 (define_insn "return_indirect_internal"
15507   [(return)
15508    (use (match_operand:SI 0 "register_operand" "r"))]
15509   "reload_completed"
15510   "jmp\t%A0"
15511   [(set_attr "type" "ibr")
15512    (set_attr "length_immediate" "0")])
15513
15514 (define_insn "nop"
15515   [(const_int 0)]
15516   ""
15517   "nop"
15518   [(set_attr "length" "1")
15519    (set_attr "length_immediate" "0")
15520    (set_attr "modrm" "0")])
15521
15522 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
15523 ;; branch prediction penalty for the third jump in a 16-byte
15524 ;; block on K8.
15525
15526 (define_insn "pad"
15527   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15528   ""
15529 {
15530 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
15531   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
15532 #else
15533   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15534      The align insn is used to avoid 3 jump instructions in the row to improve
15535      branch prediction and the benefits hardly outweigh the cost of extra 8
15536      nops on the average inserted by full alignment pseudo operation.  */
15537 #endif
15538   return "";
15539 }
15540   [(set_attr "length" "16")])
15541
15542 (define_expand "prologue"
15543   [(const_int 0)]
15544   ""
15545   "ix86_expand_prologue (); DONE;")
15546
15547 (define_insn "set_got"
15548   [(set (match_operand:SI 0 "register_operand" "=r")
15549         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15550    (clobber (reg:CC FLAGS_REG))]
15551   "!TARGET_64BIT"
15552   { return output_set_got (operands[0], NULL_RTX); }
15553   [(set_attr "type" "multi")
15554    (set_attr "length" "12")])
15555
15556 (define_insn "set_got_labelled"
15557   [(set (match_operand:SI 0 "register_operand" "=r")
15558         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15559          UNSPEC_SET_GOT))
15560    (clobber (reg:CC FLAGS_REG))]
15561   "!TARGET_64BIT"
15562   { return output_set_got (operands[0], operands[1]); }
15563   [(set_attr "type" "multi")
15564    (set_attr "length" "12")])
15565
15566 (define_insn "set_got_rex64"
15567   [(set (match_operand:DI 0 "register_operand" "=r")
15568         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15569   "TARGET_64BIT"
15570   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15571   [(set_attr "type" "lea")
15572    (set_attr "length" "6")])
15573
15574 (define_insn "set_rip_rex64"
15575   [(set (match_operand:DI 0 "register_operand" "=r")
15576         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15577   "TARGET_64BIT"
15578   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15579   [(set_attr "type" "lea")
15580    (set_attr "length" "6")])
15581
15582 (define_insn "set_got_offset_rex64"
15583   [(set (match_operand:DI 0 "register_operand" "=r")
15584         (unspec:DI
15585           [(label_ref (match_operand 1 "" ""))]
15586           UNSPEC_SET_GOT_OFFSET))]
15587   "TARGET_64BIT"
15588   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15589   [(set_attr "type" "imov")
15590    (set_attr "length" "11")])
15591
15592 (define_expand "epilogue"
15593   [(const_int 0)]
15594   ""
15595   "ix86_expand_epilogue (1); DONE;")
15596
15597 (define_expand "sibcall_epilogue"
15598   [(const_int 0)]
15599   ""
15600   "ix86_expand_epilogue (0); DONE;")
15601
15602 (define_expand "eh_return"
15603   [(use (match_operand 0 "register_operand" ""))]
15604   ""
15605 {
15606   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15607
15608   /* Tricky bit: we write the address of the handler to which we will
15609      be returning into someone else's stack frame, one word below the
15610      stack address we wish to restore.  */
15611   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15612   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15613   tmp = gen_rtx_MEM (Pmode, tmp);
15614   emit_move_insn (tmp, ra);
15615
15616   if (Pmode == SImode)
15617     emit_jump_insn (gen_eh_return_si (sa));
15618   else
15619     emit_jump_insn (gen_eh_return_di (sa));
15620   emit_barrier ();
15621   DONE;
15622 })
15623
15624 (define_insn_and_split "eh_return_<mode>"
15625   [(set (pc)
15626         (unspec [(match_operand:P 0 "register_operand" "c")]
15627                  UNSPEC_EH_RETURN))]
15628   ""
15629   "#"
15630   "reload_completed"
15631   [(const_int 0)]
15632   "ix86_expand_epilogue (2); DONE;")
15633
15634 (define_insn "leave"
15635   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15636    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15637    (clobber (mem:BLK (scratch)))]
15638   "!TARGET_64BIT"
15639   "leave"
15640   [(set_attr "type" "leave")])
15641
15642 (define_insn "leave_rex64"
15643   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15644    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15645    (clobber (mem:BLK (scratch)))]
15646   "TARGET_64BIT"
15647   "leave"
15648   [(set_attr "type" "leave")])
15649 \f
15650 (define_expand "ffssi2"
15651   [(parallel
15652      [(set (match_operand:SI 0 "register_operand" "")
15653            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15654       (clobber (match_scratch:SI 2 ""))
15655       (clobber (reg:CC FLAGS_REG))])]
15656   ""
15657 {
15658   if (TARGET_CMOVE)
15659     {
15660       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15661       DONE;
15662     }
15663 })
15664
15665 (define_expand "ffs_cmove"
15666   [(set (match_dup 2) (const_int -1))
15667    (parallel [(set (reg:CCZ FLAGS_REG)
15668                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15669                                 (const_int 0)))
15670               (set (match_operand:SI 0 "register_operand" "")
15671                    (ctz:SI (match_dup 1)))])
15672    (set (match_dup 0) (if_then_else:SI
15673                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15674                         (match_dup 2)
15675                         (match_dup 0)))
15676    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15677               (clobber (reg:CC FLAGS_REG))])]
15678   "TARGET_CMOVE"
15679   "operands[2] = gen_reg_rtx (SImode);")
15680
15681 (define_insn_and_split "*ffs_no_cmove"
15682   [(set (match_operand:SI 0 "register_operand" "=r")
15683         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15684    (clobber (match_scratch:SI 2 "=&q"))
15685    (clobber (reg:CC FLAGS_REG))]
15686   "!TARGET_CMOVE"
15687   "#"
15688   "&& reload_completed"
15689   [(parallel [(set (reg:CCZ FLAGS_REG)
15690                    (compare:CCZ (match_dup 1) (const_int 0)))
15691               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15692    (set (strict_low_part (match_dup 3))
15693         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15694    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15695               (clobber (reg:CC FLAGS_REG))])
15696    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15697               (clobber (reg:CC FLAGS_REG))])
15698    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15699               (clobber (reg:CC FLAGS_REG))])]
15700 {
15701   operands[3] = gen_lowpart (QImode, operands[2]);
15702   ix86_expand_clear (operands[2]);
15703 })
15704
15705 (define_insn "*ffssi_1"
15706   [(set (reg:CCZ FLAGS_REG)
15707         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15708                      (const_int 0)))
15709    (set (match_operand:SI 0 "register_operand" "=r")
15710         (ctz:SI (match_dup 1)))]
15711   ""
15712   "bsf{l}\t{%1, %0|%0, %1}"
15713   [(set_attr "prefix_0f" "1")])
15714
15715 (define_expand "ffsdi2"
15716   [(set (match_dup 2) (const_int -1))
15717    (parallel [(set (reg:CCZ FLAGS_REG)
15718                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15719                                 (const_int 0)))
15720               (set (match_operand:DI 0 "register_operand" "")
15721                    (ctz:DI (match_dup 1)))])
15722    (set (match_dup 0) (if_then_else:DI
15723                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15724                         (match_dup 2)
15725                         (match_dup 0)))
15726    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15727               (clobber (reg:CC FLAGS_REG))])]
15728   "TARGET_64BIT"
15729   "operands[2] = gen_reg_rtx (DImode);")
15730
15731 (define_insn "*ffsdi_1"
15732   [(set (reg:CCZ FLAGS_REG)
15733         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15734                      (const_int 0)))
15735    (set (match_operand:DI 0 "register_operand" "=r")
15736         (ctz:DI (match_dup 1)))]
15737   "TARGET_64BIT"
15738   "bsf{q}\t{%1, %0|%0, %1}"
15739   [(set_attr "prefix_0f" "1")])
15740
15741 (define_insn "ctzsi2"
15742   [(set (match_operand:SI 0 "register_operand" "=r")
15743         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15744    (clobber (reg:CC FLAGS_REG))]
15745   ""
15746   "bsf{l}\t{%1, %0|%0, %1}"
15747   [(set_attr "prefix_0f" "1")])
15748
15749 (define_insn "ctzdi2"
15750   [(set (match_operand:DI 0 "register_operand" "=r")
15751         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15752    (clobber (reg:CC FLAGS_REG))]
15753   "TARGET_64BIT"
15754   "bsf{q}\t{%1, %0|%0, %1}"
15755   [(set_attr "prefix_0f" "1")])
15756
15757 (define_expand "clzsi2"
15758   [(parallel
15759      [(set (match_operand:SI 0 "register_operand" "")
15760            (minus:SI (const_int 31)
15761                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15762       (clobber (reg:CC FLAGS_REG))])
15763    (parallel
15764      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15765       (clobber (reg:CC FLAGS_REG))])]
15766   ""
15767 {
15768   if (TARGET_ABM)
15769     {
15770       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15771       DONE;
15772     }
15773 })
15774
15775 (define_insn "clzsi2_abm"
15776   [(set (match_operand:SI 0 "register_operand" "=r")
15777         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15778    (clobber (reg:CC FLAGS_REG))]
15779   "TARGET_ABM"
15780   "lzcnt{l}\t{%1, %0|%0, %1}"
15781   [(set_attr "prefix_rep" "1")
15782    (set_attr "type" "bitmanip")
15783    (set_attr "mode" "SI")])
15784
15785 (define_insn "*bsr"
15786   [(set (match_operand:SI 0 "register_operand" "=r")
15787         (minus:SI (const_int 31)
15788                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15789    (clobber (reg:CC FLAGS_REG))]
15790   ""
15791   "bsr{l}\t{%1, %0|%0, %1}"
15792   [(set_attr "prefix_0f" "1")
15793    (set_attr "mode" "SI")])
15794
15795 (define_insn "popcount<mode>2"
15796   [(set (match_operand:SWI248 0 "register_operand" "=r")
15797         (popcount:SWI248
15798           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15799    (clobber (reg:CC FLAGS_REG))]
15800   "TARGET_POPCNT"
15801 {
15802 #if TARGET_MACHO
15803   return "popcnt\t{%1, %0|%0, %1}";
15804 #else
15805   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15806 #endif
15807 }
15808   [(set_attr "prefix_rep" "1")
15809    (set_attr "type" "bitmanip")
15810    (set_attr "mode" "<MODE>")])
15811
15812 (define_insn "*popcount<mode>2_cmp"
15813   [(set (reg FLAGS_REG)
15814         (compare
15815           (popcount:SWI248
15816             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15817           (const_int 0)))
15818    (set (match_operand:SWI248 0 "register_operand" "=r")
15819         (popcount:SWI248 (match_dup 1)))]
15820   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15821 {
15822 #if TARGET_MACHO
15823   return "popcnt\t{%1, %0|%0, %1}";
15824 #else
15825   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15826 #endif
15827 }
15828   [(set_attr "prefix_rep" "1")
15829    (set_attr "type" "bitmanip")
15830    (set_attr "mode" "<MODE>")])
15831
15832 (define_insn "*popcountsi2_cmp_zext"
15833   [(set (reg FLAGS_REG)
15834         (compare
15835           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15836           (const_int 0)))
15837    (set (match_operand:DI 0 "register_operand" "=r")
15838         (zero_extend:DI(popcount:SI (match_dup 1))))]
15839   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15840 {
15841 #if TARGET_MACHO
15842   return "popcnt\t{%1, %0|%0, %1}";
15843 #else
15844   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15845 #endif
15846 }
15847   [(set_attr "prefix_rep" "1")
15848    (set_attr "type" "bitmanip")
15849    (set_attr "mode" "SI")])
15850
15851 (define_expand "bswapsi2"
15852   [(set (match_operand:SI 0 "register_operand" "")
15853         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15854   ""
15855 {
15856   if (!TARGET_BSWAP)
15857     {
15858       rtx x = operands[0];
15859
15860       emit_move_insn (x, operands[1]);
15861       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15862       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15863       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15864       DONE;
15865     }
15866 })
15867
15868 (define_insn "*bswapsi_1"
15869   [(set (match_operand:SI 0 "register_operand" "=r")
15870         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15871   "TARGET_BSWAP"
15872   "bswap\t%0"
15873   [(set_attr "prefix_0f" "1")
15874    (set_attr "length" "2")])
15875
15876 (define_insn "*bswaphi_lowpart_1"
15877   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15878         (bswap:HI (match_dup 0)))
15879    (clobber (reg:CC FLAGS_REG))]
15880   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15881   "@
15882     xchg{b}\t{%h0, %b0|%b0, %h0}
15883     rol{w}\t{$8, %0|%0, 8}"
15884   [(set_attr "length" "2,4")
15885    (set_attr "mode" "QI,HI")])
15886
15887 (define_insn "bswaphi_lowpart"
15888   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15889         (bswap:HI (match_dup 0)))
15890    (clobber (reg:CC FLAGS_REG))]
15891   ""
15892   "rol{w}\t{$8, %0|%0, 8}"
15893   [(set_attr "length" "4")
15894    (set_attr "mode" "HI")])
15895
15896 (define_insn "bswapdi2"
15897   [(set (match_operand:DI 0 "register_operand" "=r")
15898         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15899   "TARGET_64BIT"
15900   "bswap\t%0"
15901   [(set_attr "prefix_0f" "1")
15902    (set_attr "length" "3")])
15903
15904 (define_expand "clzdi2"
15905   [(parallel
15906      [(set (match_operand:DI 0 "register_operand" "")
15907            (minus:DI (const_int 63)
15908                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15909       (clobber (reg:CC FLAGS_REG))])
15910    (parallel
15911      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15912       (clobber (reg:CC FLAGS_REG))])]
15913   "TARGET_64BIT"
15914 {
15915   if (TARGET_ABM)
15916     {
15917       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15918       DONE;
15919     }
15920 })
15921
15922 (define_insn "clzdi2_abm"
15923   [(set (match_operand:DI 0 "register_operand" "=r")
15924         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15925    (clobber (reg:CC FLAGS_REG))]
15926   "TARGET_64BIT && TARGET_ABM"
15927   "lzcnt{q}\t{%1, %0|%0, %1}"
15928   [(set_attr "prefix_rep" "1")
15929    (set_attr "type" "bitmanip")
15930    (set_attr "mode" "DI")])
15931
15932 (define_insn "*bsr_rex64"
15933   [(set (match_operand:DI 0 "register_operand" "=r")
15934         (minus:DI (const_int 63)
15935                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15936    (clobber (reg:CC FLAGS_REG))]
15937   "TARGET_64BIT"
15938   "bsr{q}\t{%1, %0|%0, %1}"
15939   [(set_attr "prefix_0f" "1")
15940    (set_attr "mode" "DI")])
15941
15942 (define_expand "clzhi2"
15943   [(parallel
15944      [(set (match_operand:HI 0 "register_operand" "")
15945            (minus:HI (const_int 15)
15946                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15947       (clobber (reg:CC FLAGS_REG))])
15948    (parallel
15949      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15950       (clobber (reg:CC FLAGS_REG))])]
15951   ""
15952 {
15953   if (TARGET_ABM)
15954     {
15955       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15956       DONE;
15957     }
15958 })
15959
15960 (define_insn "clzhi2_abm"
15961   [(set (match_operand:HI 0 "register_operand" "=r")
15962         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15963    (clobber (reg:CC FLAGS_REG))]
15964   "TARGET_ABM"
15965   "lzcnt{w}\t{%1, %0|%0, %1}"
15966   [(set_attr "prefix_rep" "1")
15967    (set_attr "type" "bitmanip")
15968    (set_attr "mode" "HI")])
15969
15970 (define_insn "*bsrhi"
15971   [(set (match_operand:HI 0 "register_operand" "=r")
15972         (minus:HI (const_int 15)
15973                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15974    (clobber (reg:CC FLAGS_REG))]
15975   ""
15976   "bsr{w}\t{%1, %0|%0, %1}"
15977   [(set_attr "prefix_0f" "1")
15978    (set_attr "mode" "HI")])
15979
15980 (define_expand "paritydi2"
15981   [(set (match_operand:DI 0 "register_operand" "")
15982         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15983   "! TARGET_POPCNT"
15984 {
15985   rtx scratch = gen_reg_rtx (QImode);
15986   rtx cond;
15987
15988   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15989                                 NULL_RTX, operands[1]));
15990
15991   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15992                          gen_rtx_REG (CCmode, FLAGS_REG),
15993                          const0_rtx);
15994   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15995
15996   if (TARGET_64BIT)
15997     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15998   else
15999     {
16000       rtx tmp = gen_reg_rtx (SImode);
16001
16002       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
16003       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
16004     }
16005   DONE;
16006 })
16007
16008 (define_insn_and_split "paritydi2_cmp"
16009   [(set (reg:CC FLAGS_REG)
16010         (parity:CC (match_operand:DI 3 "register_operand" "0")))
16011    (clobber (match_scratch:DI 0 "=r"))
16012    (clobber (match_scratch:SI 1 "=&r"))
16013    (clobber (match_scratch:HI 2 "=Q"))]
16014   "! TARGET_POPCNT"
16015   "#"
16016   "&& reload_completed"
16017   [(parallel
16018      [(set (match_dup 1)
16019            (xor:SI (match_dup 1) (match_dup 4)))
16020       (clobber (reg:CC FLAGS_REG))])
16021    (parallel
16022      [(set (reg:CC FLAGS_REG)
16023            (parity:CC (match_dup 1)))
16024       (clobber (match_dup 1))
16025       (clobber (match_dup 2))])]
16026 {
16027   operands[4] = gen_lowpart (SImode, operands[3]);
16028
16029   if (TARGET_64BIT)
16030     {
16031       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
16032       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
16033     }
16034   else
16035     operands[1] = gen_highpart (SImode, operands[3]);
16036 })
16037
16038 (define_expand "paritysi2"
16039   [(set (match_operand:SI 0 "register_operand" "")
16040         (parity:SI (match_operand:SI 1 "register_operand" "")))]
16041   "! TARGET_POPCNT"
16042 {
16043   rtx scratch = gen_reg_rtx (QImode);
16044   rtx cond;
16045
16046   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
16047
16048   cond = gen_rtx_fmt_ee (ORDERED, QImode,
16049                          gen_rtx_REG (CCmode, FLAGS_REG),
16050                          const0_rtx);
16051   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16052
16053   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16054   DONE;
16055 })
16056
16057 (define_insn_and_split "paritysi2_cmp"
16058   [(set (reg:CC FLAGS_REG)
16059         (parity:CC (match_operand:SI 2 "register_operand" "0")))
16060    (clobber (match_scratch:SI 0 "=r"))
16061    (clobber (match_scratch:HI 1 "=&Q"))]
16062   "! TARGET_POPCNT"
16063   "#"
16064   "&& reload_completed"
16065   [(parallel
16066      [(set (match_dup 1)
16067            (xor:HI (match_dup 1) (match_dup 3)))
16068       (clobber (reg:CC FLAGS_REG))])
16069    (parallel
16070      [(set (reg:CC FLAGS_REG)
16071            (parity:CC (match_dup 1)))
16072       (clobber (match_dup 1))])]
16073 {
16074   operands[3] = gen_lowpart (HImode, operands[2]);
16075
16076   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
16077   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
16078 })
16079
16080 (define_insn "*parityhi2_cmp"
16081   [(set (reg:CC FLAGS_REG)
16082         (parity:CC (match_operand:HI 1 "register_operand" "0")))
16083    (clobber (match_scratch:HI 0 "=Q"))]
16084   "! TARGET_POPCNT"
16085   "xor{b}\t{%h0, %b0|%b0, %h0}"
16086   [(set_attr "length" "2")
16087    (set_attr "mode" "HI")])
16088
16089 (define_insn "*parityqi2_cmp"
16090   [(set (reg:CC FLAGS_REG)
16091         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
16092   "! TARGET_POPCNT"
16093   "test{b}\t%0, %0"
16094   [(set_attr "length" "2")
16095    (set_attr "mode" "QI")])
16096 \f
16097 ;; Thread-local storage patterns for ELF.
16098 ;;
16099 ;; Note that these code sequences must appear exactly as shown
16100 ;; in order to allow linker relaxation.
16101
16102 (define_insn "*tls_global_dynamic_32_gnu"
16103   [(set (match_operand:SI 0 "register_operand" "=a")
16104         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16105                     (match_operand:SI 2 "tls_symbolic_operand" "")
16106                     (match_operand:SI 3 "call_insn_operand" "")]
16107                     UNSPEC_TLS_GD))
16108    (clobber (match_scratch:SI 4 "=d"))
16109    (clobber (match_scratch:SI 5 "=c"))
16110    (clobber (reg:CC FLAGS_REG))]
16111   "!TARGET_64BIT && TARGET_GNU_TLS"
16112   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
16113   [(set_attr "type" "multi")
16114    (set_attr "length" "12")])
16115
16116 (define_insn "*tls_global_dynamic_32_sun"
16117   [(set (match_operand:SI 0 "register_operand" "=a")
16118         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16119                     (match_operand:SI 2 "tls_symbolic_operand" "")
16120                     (match_operand:SI 3 "call_insn_operand" "")]
16121                     UNSPEC_TLS_GD))
16122    (clobber (match_scratch:SI 4 "=d"))
16123    (clobber (match_scratch:SI 5 "=c"))
16124    (clobber (reg:CC FLAGS_REG))]
16125   "!TARGET_64BIT && TARGET_SUN_TLS"
16126   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
16127         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
16128   [(set_attr "type" "multi")
16129    (set_attr "length" "14")])
16130
16131 (define_expand "tls_global_dynamic_32"
16132   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16133                    (unspec:SI
16134                     [(match_dup 2)
16135                      (match_operand:SI 1 "tls_symbolic_operand" "")
16136                      (match_dup 3)]
16137                     UNSPEC_TLS_GD))
16138               (clobber (match_scratch:SI 4 ""))
16139               (clobber (match_scratch:SI 5 ""))
16140               (clobber (reg:CC FLAGS_REG))])]
16141   ""
16142 {
16143   if (flag_pic)
16144     operands[2] = pic_offset_table_rtx;
16145   else
16146     {
16147       operands[2] = gen_reg_rtx (Pmode);
16148       emit_insn (gen_set_got (operands[2]));
16149     }
16150   if (TARGET_GNU2_TLS)
16151     {
16152        emit_insn (gen_tls_dynamic_gnu2_32
16153                   (operands[0], operands[1], operands[2]));
16154        DONE;
16155     }
16156   operands[3] = ix86_tls_get_addr ();
16157 })
16158
16159 (define_insn "*tls_global_dynamic_64"
16160   [(set (match_operand:DI 0 "register_operand" "=a")
16161         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16162                  (match_operand:DI 3 "" "")))
16163    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16164               UNSPEC_TLS_GD)]
16165   "TARGET_64BIT"
16166   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
16167   [(set_attr "type" "multi")
16168    (set_attr "length" "16")])
16169
16170 (define_expand "tls_global_dynamic_64"
16171   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16172                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16173               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16174                          UNSPEC_TLS_GD)])]
16175   ""
16176 {
16177   if (TARGET_GNU2_TLS)
16178     {
16179        emit_insn (gen_tls_dynamic_gnu2_64
16180                   (operands[0], operands[1]));
16181        DONE;
16182     }
16183   operands[2] = ix86_tls_get_addr ();
16184 })
16185
16186 (define_insn "*tls_local_dynamic_base_32_gnu"
16187   [(set (match_operand:SI 0 "register_operand" "=a")
16188         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16189                     (match_operand:SI 2 "call_insn_operand" "")]
16190                    UNSPEC_TLS_LD_BASE))
16191    (clobber (match_scratch:SI 3 "=d"))
16192    (clobber (match_scratch:SI 4 "=c"))
16193    (clobber (reg:CC FLAGS_REG))]
16194   "!TARGET_64BIT && TARGET_GNU_TLS"
16195   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16196   [(set_attr "type" "multi")
16197    (set_attr "length" "11")])
16198
16199 (define_insn "*tls_local_dynamic_base_32_sun"
16200   [(set (match_operand:SI 0 "register_operand" "=a")
16201         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16202                     (match_operand:SI 2 "call_insn_operand" "")]
16203                    UNSPEC_TLS_LD_BASE))
16204    (clobber (match_scratch:SI 3 "=d"))
16205    (clobber (match_scratch:SI 4 "=c"))
16206    (clobber (reg:CC FLAGS_REG))]
16207   "!TARGET_64BIT && TARGET_SUN_TLS"
16208   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16209         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16210   [(set_attr "type" "multi")
16211    (set_attr "length" "13")])
16212
16213 (define_expand "tls_local_dynamic_base_32"
16214   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16215                    (unspec:SI [(match_dup 1) (match_dup 2)]
16216                               UNSPEC_TLS_LD_BASE))
16217               (clobber (match_scratch:SI 3 ""))
16218               (clobber (match_scratch:SI 4 ""))
16219               (clobber (reg:CC FLAGS_REG))])]
16220   ""
16221 {
16222   if (flag_pic)
16223     operands[1] = pic_offset_table_rtx;
16224   else
16225     {
16226       operands[1] = gen_reg_rtx (Pmode);
16227       emit_insn (gen_set_got (operands[1]));
16228     }
16229   if (TARGET_GNU2_TLS)
16230     {
16231        emit_insn (gen_tls_dynamic_gnu2_32
16232                   (operands[0], ix86_tls_module_base (), operands[1]));
16233        DONE;
16234     }
16235   operands[2] = ix86_tls_get_addr ();
16236 })
16237
16238 (define_insn "*tls_local_dynamic_base_64"
16239   [(set (match_operand:DI 0 "register_operand" "=a")
16240         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16241                  (match_operand:DI 2 "" "")))
16242    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16243   "TARGET_64BIT"
16244   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16245   [(set_attr "type" "multi")
16246    (set_attr "length" "12")])
16247
16248 (define_expand "tls_local_dynamic_base_64"
16249   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16250                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16251               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16252   ""
16253 {
16254   if (TARGET_GNU2_TLS)
16255     {
16256        emit_insn (gen_tls_dynamic_gnu2_64
16257                   (operands[0], ix86_tls_module_base ()));
16258        DONE;
16259     }
16260   operands[1] = ix86_tls_get_addr ();
16261 })
16262
16263 ;; Local dynamic of a single variable is a lose.  Show combine how
16264 ;; to convert that back to global dynamic.
16265
16266 (define_insn_and_split "*tls_local_dynamic_32_once"
16267   [(set (match_operand:SI 0 "register_operand" "=a")
16268         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16269                              (match_operand:SI 2 "call_insn_operand" "")]
16270                             UNSPEC_TLS_LD_BASE)
16271                  (const:SI (unspec:SI
16272                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16273                             UNSPEC_DTPOFF))))
16274    (clobber (match_scratch:SI 4 "=d"))
16275    (clobber (match_scratch:SI 5 "=c"))
16276    (clobber (reg:CC FLAGS_REG))]
16277   ""
16278   "#"
16279   ""
16280   [(parallel [(set (match_dup 0)
16281                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16282                               UNSPEC_TLS_GD))
16283               (clobber (match_dup 4))
16284               (clobber (match_dup 5))
16285               (clobber (reg:CC FLAGS_REG))])]
16286   "")
16287
16288 ;; Load and add the thread base pointer from %gs:0.
16289
16290 (define_insn "*load_tp_si"
16291   [(set (match_operand:SI 0 "register_operand" "=r")
16292         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16293   "!TARGET_64BIT"
16294   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16295   [(set_attr "type" "imov")
16296    (set_attr "modrm" "0")
16297    (set_attr "length" "7")
16298    (set_attr "memory" "load")
16299    (set_attr "imm_disp" "false")])
16300
16301 (define_insn "*add_tp_si"
16302   [(set (match_operand:SI 0 "register_operand" "=r")
16303         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16304                  (match_operand:SI 1 "register_operand" "0")))
16305    (clobber (reg:CC FLAGS_REG))]
16306   "!TARGET_64BIT"
16307   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16308   [(set_attr "type" "alu")
16309    (set_attr "modrm" "0")
16310    (set_attr "length" "7")
16311    (set_attr "memory" "load")
16312    (set_attr "imm_disp" "false")])
16313
16314 (define_insn "*load_tp_di"
16315   [(set (match_operand:DI 0 "register_operand" "=r")
16316         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16317   "TARGET_64BIT"
16318   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16319   [(set_attr "type" "imov")
16320    (set_attr "modrm" "0")
16321    (set_attr "length" "7")
16322    (set_attr "memory" "load")
16323    (set_attr "imm_disp" "false")])
16324
16325 (define_insn "*add_tp_di"
16326   [(set (match_operand:DI 0 "register_operand" "=r")
16327         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16328                  (match_operand:DI 1 "register_operand" "0")))
16329    (clobber (reg:CC FLAGS_REG))]
16330   "TARGET_64BIT"
16331   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16332   [(set_attr "type" "alu")
16333    (set_attr "modrm" "0")
16334    (set_attr "length" "7")
16335    (set_attr "memory" "load")
16336    (set_attr "imm_disp" "false")])
16337
16338 ;; GNU2 TLS patterns can be split.
16339
16340 (define_expand "tls_dynamic_gnu2_32"
16341   [(set (match_dup 3)
16342         (plus:SI (match_operand:SI 2 "register_operand" "")
16343                  (const:SI
16344                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16345                              UNSPEC_TLSDESC))))
16346    (parallel
16347     [(set (match_operand:SI 0 "register_operand" "")
16348           (unspec:SI [(match_dup 1) (match_dup 3)
16349                       (match_dup 2) (reg:SI SP_REG)]
16350                       UNSPEC_TLSDESC))
16351      (clobber (reg:CC FLAGS_REG))])]
16352   "!TARGET_64BIT && TARGET_GNU2_TLS"
16353 {
16354   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16355   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16356 })
16357
16358 (define_insn "*tls_dynamic_lea_32"
16359   [(set (match_operand:SI 0 "register_operand" "=r")
16360         (plus:SI (match_operand:SI 1 "register_operand" "b")
16361                  (const:SI
16362                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16363                               UNSPEC_TLSDESC))))]
16364   "!TARGET_64BIT && TARGET_GNU2_TLS"
16365   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16366   [(set_attr "type" "lea")
16367    (set_attr "mode" "SI")
16368    (set_attr "length" "6")
16369    (set_attr "length_address" "4")])
16370
16371 (define_insn "*tls_dynamic_call_32"
16372   [(set (match_operand:SI 0 "register_operand" "=a")
16373         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16374                     (match_operand:SI 2 "register_operand" "0")
16375                     ;; we have to make sure %ebx still points to the GOT
16376                     (match_operand:SI 3 "register_operand" "b")
16377                     (reg:SI SP_REG)]
16378                    UNSPEC_TLSDESC))
16379    (clobber (reg:CC FLAGS_REG))]
16380   "!TARGET_64BIT && TARGET_GNU2_TLS"
16381   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16382   [(set_attr "type" "call")
16383    (set_attr "length" "2")
16384    (set_attr "length_address" "0")])
16385
16386 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16387   [(set (match_operand:SI 0 "register_operand" "=&a")
16388         (plus:SI
16389          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16390                      (match_operand:SI 4 "" "")
16391                      (match_operand:SI 2 "register_operand" "b")
16392                      (reg:SI SP_REG)]
16393                     UNSPEC_TLSDESC)
16394          (const:SI (unspec:SI
16395                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16396                     UNSPEC_DTPOFF))))
16397    (clobber (reg:CC FLAGS_REG))]
16398   "!TARGET_64BIT && TARGET_GNU2_TLS"
16399   "#"
16400   ""
16401   [(set (match_dup 0) (match_dup 5))]
16402 {
16403   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16404   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16405 })
16406
16407 (define_expand "tls_dynamic_gnu2_64"
16408   [(set (match_dup 2)
16409         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16410                    UNSPEC_TLSDESC))
16411    (parallel
16412     [(set (match_operand:DI 0 "register_operand" "")
16413           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16414                      UNSPEC_TLSDESC))
16415      (clobber (reg:CC FLAGS_REG))])]
16416   "TARGET_64BIT && TARGET_GNU2_TLS"
16417 {
16418   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16419   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16420 })
16421
16422 (define_insn "*tls_dynamic_lea_64"
16423   [(set (match_operand:DI 0 "register_operand" "=r")
16424         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16425                    UNSPEC_TLSDESC))]
16426   "TARGET_64BIT && TARGET_GNU2_TLS"
16427   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16428   [(set_attr "type" "lea")
16429    (set_attr "mode" "DI")
16430    (set_attr "length" "7")
16431    (set_attr "length_address" "4")])
16432
16433 (define_insn "*tls_dynamic_call_64"
16434   [(set (match_operand:DI 0 "register_operand" "=a")
16435         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16436                     (match_operand:DI 2 "register_operand" "0")
16437                     (reg:DI SP_REG)]
16438                    UNSPEC_TLSDESC))
16439    (clobber (reg:CC FLAGS_REG))]
16440   "TARGET_64BIT && TARGET_GNU2_TLS"
16441   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16442   [(set_attr "type" "call")
16443    (set_attr "length" "2")
16444    (set_attr "length_address" "0")])
16445
16446 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16447   [(set (match_operand:DI 0 "register_operand" "=&a")
16448         (plus:DI
16449          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16450                      (match_operand:DI 3 "" "")
16451                      (reg:DI SP_REG)]
16452                     UNSPEC_TLSDESC)
16453          (const:DI (unspec:DI
16454                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16455                     UNSPEC_DTPOFF))))
16456    (clobber (reg:CC FLAGS_REG))]
16457   "TARGET_64BIT && TARGET_GNU2_TLS"
16458   "#"
16459   ""
16460   [(set (match_dup 0) (match_dup 4))]
16461 {
16462   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16463   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16464 })
16465
16466 ;;
16467 \f
16468 ;; These patterns match the binary 387 instructions for addM3, subM3,
16469 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16470 ;; SFmode.  The first is the normal insn, the second the same insn but
16471 ;; with one operand a conversion, and the third the same insn but with
16472 ;; the other operand a conversion.  The conversion may be SFmode or
16473 ;; SImode if the target mode DFmode, but only SImode if the target mode
16474 ;; is SFmode.
16475
16476 ;; Gcc is slightly more smart about handling normal two address instructions
16477 ;; so use special patterns for add and mull.
16478
16479 (define_insn "*fop_<mode>_comm_mixed_avx"
16480   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16481         (match_operator:MODEF 3 "binary_fp_operator"
16482           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16483            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16484   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16485    && COMMUTATIVE_ARITH_P (operands[3])
16486    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16487   "* return output_387_binary_op (insn, operands);"
16488   [(set (attr "type")
16489         (if_then_else (eq_attr "alternative" "1")
16490            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16491               (const_string "ssemul")
16492               (const_string "sseadd"))
16493            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16494               (const_string "fmul")
16495               (const_string "fop"))))
16496    (set_attr "prefix" "orig,maybe_vex")
16497    (set_attr "mode" "<MODE>")])
16498
16499 (define_insn "*fop_<mode>_comm_mixed"
16500   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16501         (match_operator:MODEF 3 "binary_fp_operator"
16502           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16503            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16504   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16505    && COMMUTATIVE_ARITH_P (operands[3])
16506    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16507   "* return output_387_binary_op (insn, operands);"
16508   [(set (attr "type")
16509         (if_then_else (eq_attr "alternative" "1")
16510            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16511               (const_string "ssemul")
16512               (const_string "sseadd"))
16513            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16514               (const_string "fmul")
16515               (const_string "fop"))))
16516    (set_attr "mode" "<MODE>")])
16517
16518 (define_insn "*fop_<mode>_comm_avx"
16519   [(set (match_operand:MODEF 0 "register_operand" "=x")
16520         (match_operator:MODEF 3 "binary_fp_operator"
16521           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16522            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16523   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16524    && COMMUTATIVE_ARITH_P (operands[3])
16525    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16526   "* return output_387_binary_op (insn, operands);"
16527   [(set (attr "type")
16528         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16529            (const_string "ssemul")
16530            (const_string "sseadd")))
16531    (set_attr "prefix" "vex")
16532    (set_attr "mode" "<MODE>")])
16533
16534 (define_insn "*fop_<mode>_comm_sse"
16535   [(set (match_operand:MODEF 0 "register_operand" "=x")
16536         (match_operator:MODEF 3 "binary_fp_operator"
16537           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16538            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16539   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16540    && COMMUTATIVE_ARITH_P (operands[3])
16541    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16542   "* return output_387_binary_op (insn, operands);"
16543   [(set (attr "type")
16544         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16545            (const_string "ssemul")
16546            (const_string "sseadd")))
16547    (set_attr "mode" "<MODE>")])
16548
16549 (define_insn "*fop_<mode>_comm_i387"
16550   [(set (match_operand:MODEF 0 "register_operand" "=f")
16551         (match_operator:MODEF 3 "binary_fp_operator"
16552           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16553            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16554   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16555    && COMMUTATIVE_ARITH_P (operands[3])
16556    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16557   "* return output_387_binary_op (insn, operands);"
16558   [(set (attr "type")
16559         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16560            (const_string "fmul")
16561            (const_string "fop")))
16562    (set_attr "mode" "<MODE>")])
16563
16564 (define_insn "*fop_<mode>_1_mixed_avx"
16565   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16566         (match_operator:MODEF 3 "binary_fp_operator"
16567           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16568            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16569   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16570    && !COMMUTATIVE_ARITH_P (operands[3])
16571    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16572   "* return output_387_binary_op (insn, operands);"
16573   [(set (attr "type")
16574         (cond [(and (eq_attr "alternative" "2")
16575                     (match_operand:MODEF 3 "mult_operator" ""))
16576                  (const_string "ssemul")
16577                (and (eq_attr "alternative" "2")
16578                     (match_operand:MODEF 3 "div_operator" ""))
16579                  (const_string "ssediv")
16580                (eq_attr "alternative" "2")
16581                  (const_string "sseadd")
16582                (match_operand:MODEF 3 "mult_operator" "")
16583                  (const_string "fmul")
16584                (match_operand:MODEF 3 "div_operator" "")
16585                  (const_string "fdiv")
16586               ]
16587               (const_string "fop")))
16588    (set_attr "prefix" "orig,orig,maybe_vex")
16589    (set_attr "mode" "<MODE>")])
16590
16591 (define_insn "*fop_<mode>_1_mixed"
16592   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16593         (match_operator:MODEF 3 "binary_fp_operator"
16594           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16595            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16596   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16597    && !COMMUTATIVE_ARITH_P (operands[3])
16598    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16599   "* return output_387_binary_op (insn, operands);"
16600   [(set (attr "type")
16601         (cond [(and (eq_attr "alternative" "2")
16602                     (match_operand:MODEF 3 "mult_operator" ""))
16603                  (const_string "ssemul")
16604                (and (eq_attr "alternative" "2")
16605                     (match_operand:MODEF 3 "div_operator" ""))
16606                  (const_string "ssediv")
16607                (eq_attr "alternative" "2")
16608                  (const_string "sseadd")
16609                (match_operand:MODEF 3 "mult_operator" "")
16610                  (const_string "fmul")
16611                (match_operand:MODEF 3 "div_operator" "")
16612                  (const_string "fdiv")
16613               ]
16614               (const_string "fop")))
16615    (set_attr "mode" "<MODE>")])
16616
16617 (define_insn "*rcpsf2_sse"
16618   [(set (match_operand:SF 0 "register_operand" "=x")
16619         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16620                    UNSPEC_RCP))]
16621   "TARGET_SSE_MATH"
16622   "%vrcpss\t{%1, %d0|%d0, %1}"
16623   [(set_attr "type" "sse")
16624    (set_attr "atom_sse_attr" "rcp")
16625    (set_attr "prefix" "maybe_vex")
16626    (set_attr "mode" "SF")])
16627
16628 (define_insn "*fop_<mode>_1_avx"
16629   [(set (match_operand:MODEF 0 "register_operand" "=x")
16630         (match_operator:MODEF 3 "binary_fp_operator"
16631           [(match_operand:MODEF 1 "register_operand" "x")
16632            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16633   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16634    && !COMMUTATIVE_ARITH_P (operands[3])"
16635   "* return output_387_binary_op (insn, operands);"
16636   [(set (attr "type")
16637         (cond [(match_operand:MODEF 3 "mult_operator" "")
16638                  (const_string "ssemul")
16639                (match_operand:MODEF 3 "div_operator" "")
16640                  (const_string "ssediv")
16641               ]
16642               (const_string "sseadd")))
16643    (set_attr "prefix" "vex")
16644    (set_attr "mode" "<MODE>")])
16645
16646 (define_insn "*fop_<mode>_1_sse"
16647   [(set (match_operand:MODEF 0 "register_operand" "=x")
16648         (match_operator:MODEF 3 "binary_fp_operator"
16649           [(match_operand:MODEF 1 "register_operand" "0")
16650            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16651   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16652    && !COMMUTATIVE_ARITH_P (operands[3])"
16653   "* return output_387_binary_op (insn, operands);"
16654   [(set (attr "type")
16655         (cond [(match_operand:MODEF 3 "mult_operator" "")
16656                  (const_string "ssemul")
16657                (match_operand:MODEF 3 "div_operator" "")
16658                  (const_string "ssediv")
16659               ]
16660               (const_string "sseadd")))
16661    (set_attr "mode" "<MODE>")])
16662
16663 ;; This pattern is not fully shadowed by the pattern above.
16664 (define_insn "*fop_<mode>_1_i387"
16665   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16666         (match_operator:MODEF 3 "binary_fp_operator"
16667           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16668            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16669   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16670    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16671    && !COMMUTATIVE_ARITH_P (operands[3])
16672    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16673   "* return output_387_binary_op (insn, operands);"
16674   [(set (attr "type")
16675         (cond [(match_operand:MODEF 3 "mult_operator" "")
16676                  (const_string "fmul")
16677                (match_operand:MODEF 3 "div_operator" "")
16678                  (const_string "fdiv")
16679               ]
16680               (const_string "fop")))
16681    (set_attr "mode" "<MODE>")])
16682
16683 ;; ??? Add SSE splitters for these!
16684 (define_insn "*fop_<MODEF:mode>_2_i387"
16685   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16686         (match_operator:MODEF 3 "binary_fp_operator"
16687           [(float:MODEF
16688              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16689            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16690   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16691    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16692    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16693   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16694   [(set (attr "type")
16695         (cond [(match_operand:MODEF 3 "mult_operator" "")
16696                  (const_string "fmul")
16697                (match_operand:MODEF 3 "div_operator" "")
16698                  (const_string "fdiv")
16699               ]
16700               (const_string "fop")))
16701    (set_attr "fp_int_src" "true")
16702    (set_attr "mode" "<X87MODEI12:MODE>")])
16703
16704 (define_insn "*fop_<MODEF:mode>_3_i387"
16705   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16706         (match_operator:MODEF 3 "binary_fp_operator"
16707           [(match_operand:MODEF 1 "register_operand" "0,0")
16708            (float:MODEF
16709              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16710   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16711    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16712    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16713   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16714   [(set (attr "type")
16715         (cond [(match_operand:MODEF 3 "mult_operator" "")
16716                  (const_string "fmul")
16717                (match_operand:MODEF 3 "div_operator" "")
16718                  (const_string "fdiv")
16719               ]
16720               (const_string "fop")))
16721    (set_attr "fp_int_src" "true")
16722    (set_attr "mode" "<MODE>")])
16723
16724 (define_insn "*fop_df_4_i387"
16725   [(set (match_operand:DF 0 "register_operand" "=f,f")
16726         (match_operator:DF 3 "binary_fp_operator"
16727            [(float_extend:DF
16728              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16729             (match_operand:DF 2 "register_operand" "0,f")]))]
16730   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16731    && !(TARGET_SSE2 && TARGET_SSE_MATH)
16732    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16733   "* return output_387_binary_op (insn, operands);"
16734   [(set (attr "type")
16735         (cond [(match_operand:DF 3 "mult_operator" "")
16736                  (const_string "fmul")
16737                (match_operand:DF 3 "div_operator" "")
16738                  (const_string "fdiv")
16739               ]
16740               (const_string "fop")))
16741    (set_attr "mode" "SF")])
16742
16743 (define_insn "*fop_df_5_i387"
16744   [(set (match_operand:DF 0 "register_operand" "=f,f")
16745         (match_operator:DF 3 "binary_fp_operator"
16746           [(match_operand:DF 1 "register_operand" "0,f")
16747            (float_extend:DF
16748             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16749   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16750    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16751   "* return output_387_binary_op (insn, operands);"
16752   [(set (attr "type")
16753         (cond [(match_operand:DF 3 "mult_operator" "")
16754                  (const_string "fmul")
16755                (match_operand:DF 3 "div_operator" "")
16756                  (const_string "fdiv")
16757               ]
16758               (const_string "fop")))
16759    (set_attr "mode" "SF")])
16760
16761 (define_insn "*fop_df_6_i387"
16762   [(set (match_operand:DF 0 "register_operand" "=f,f")
16763         (match_operator:DF 3 "binary_fp_operator"
16764           [(float_extend:DF
16765             (match_operand:SF 1 "register_operand" "0,f"))
16766            (float_extend:DF
16767             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16768   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16769    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16770   "* return output_387_binary_op (insn, operands);"
16771   [(set (attr "type")
16772         (cond [(match_operand:DF 3 "mult_operator" "")
16773                  (const_string "fmul")
16774                (match_operand:DF 3 "div_operator" "")
16775                  (const_string "fdiv")
16776               ]
16777               (const_string "fop")))
16778    (set_attr "mode" "SF")])
16779
16780 (define_insn "*fop_xf_comm_i387"
16781   [(set (match_operand:XF 0 "register_operand" "=f")
16782         (match_operator:XF 3 "binary_fp_operator"
16783                         [(match_operand:XF 1 "register_operand" "%0")
16784                          (match_operand:XF 2 "register_operand" "f")]))]
16785   "TARGET_80387
16786    && COMMUTATIVE_ARITH_P (operands[3])"
16787   "* return output_387_binary_op (insn, operands);"
16788   [(set (attr "type")
16789         (if_then_else (match_operand:XF 3 "mult_operator" "")
16790            (const_string "fmul")
16791            (const_string "fop")))
16792    (set_attr "mode" "XF")])
16793
16794 (define_insn "*fop_xf_1_i387"
16795   [(set (match_operand:XF 0 "register_operand" "=f,f")
16796         (match_operator:XF 3 "binary_fp_operator"
16797                         [(match_operand:XF 1 "register_operand" "0,f")
16798                          (match_operand:XF 2 "register_operand" "f,0")]))]
16799   "TARGET_80387
16800    && !COMMUTATIVE_ARITH_P (operands[3])"
16801   "* return output_387_binary_op (insn, operands);"
16802   [(set (attr "type")
16803         (cond [(match_operand:XF 3 "mult_operator" "")
16804                  (const_string "fmul")
16805                (match_operand:XF 3 "div_operator" "")
16806                  (const_string "fdiv")
16807               ]
16808               (const_string "fop")))
16809    (set_attr "mode" "XF")])
16810
16811 (define_insn "*fop_xf_2_i387"
16812   [(set (match_operand:XF 0 "register_operand" "=f,f")
16813         (match_operator:XF 3 "binary_fp_operator"
16814           [(float:XF
16815              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16816            (match_operand:XF 2 "register_operand" "0,0")]))]
16817   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16818   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16819   [(set (attr "type")
16820         (cond [(match_operand:XF 3 "mult_operator" "")
16821                  (const_string "fmul")
16822                (match_operand:XF 3 "div_operator" "")
16823                  (const_string "fdiv")
16824               ]
16825               (const_string "fop")))
16826    (set_attr "fp_int_src" "true")
16827    (set_attr "mode" "<MODE>")])
16828
16829 (define_insn "*fop_xf_3_i387"
16830   [(set (match_operand:XF 0 "register_operand" "=f,f")
16831         (match_operator:XF 3 "binary_fp_operator"
16832           [(match_operand:XF 1 "register_operand" "0,0")
16833            (float:XF
16834              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16835   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16836   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16837   [(set (attr "type")
16838         (cond [(match_operand:XF 3 "mult_operator" "")
16839                  (const_string "fmul")
16840                (match_operand:XF 3 "div_operator" "")
16841                  (const_string "fdiv")
16842               ]
16843               (const_string "fop")))
16844    (set_attr "fp_int_src" "true")
16845    (set_attr "mode" "<MODE>")])
16846
16847 (define_insn "*fop_xf_4_i387"
16848   [(set (match_operand:XF 0 "register_operand" "=f,f")
16849         (match_operator:XF 3 "binary_fp_operator"
16850            [(float_extend:XF
16851               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16852             (match_operand:XF 2 "register_operand" "0,f")]))]
16853   "TARGET_80387"
16854   "* return output_387_binary_op (insn, operands);"
16855   [(set (attr "type")
16856         (cond [(match_operand:XF 3 "mult_operator" "")
16857                  (const_string "fmul")
16858                (match_operand:XF 3 "div_operator" "")
16859                  (const_string "fdiv")
16860               ]
16861               (const_string "fop")))
16862    (set_attr "mode" "<MODE>")])
16863
16864 (define_insn "*fop_xf_5_i387"
16865   [(set (match_operand:XF 0 "register_operand" "=f,f")
16866         (match_operator:XF 3 "binary_fp_operator"
16867           [(match_operand:XF 1 "register_operand" "0,f")
16868            (float_extend:XF
16869              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16870   "TARGET_80387"
16871   "* return output_387_binary_op (insn, operands);"
16872   [(set (attr "type")
16873         (cond [(match_operand:XF 3 "mult_operator" "")
16874                  (const_string "fmul")
16875                (match_operand:XF 3 "div_operator" "")
16876                  (const_string "fdiv")
16877               ]
16878               (const_string "fop")))
16879    (set_attr "mode" "<MODE>")])
16880
16881 (define_insn "*fop_xf_6_i387"
16882   [(set (match_operand:XF 0 "register_operand" "=f,f")
16883         (match_operator:XF 3 "binary_fp_operator"
16884           [(float_extend:XF
16885              (match_operand:MODEF 1 "register_operand" "0,f"))
16886            (float_extend:XF
16887              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16888   "TARGET_80387"
16889   "* return output_387_binary_op (insn, operands);"
16890   [(set (attr "type")
16891         (cond [(match_operand:XF 3 "mult_operator" "")
16892                  (const_string "fmul")
16893                (match_operand:XF 3 "div_operator" "")
16894                  (const_string "fdiv")
16895               ]
16896               (const_string "fop")))
16897    (set_attr "mode" "<MODE>")])
16898
16899 (define_split
16900   [(set (match_operand 0 "register_operand" "")
16901         (match_operator 3 "binary_fp_operator"
16902            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16903             (match_operand 2 "register_operand" "")]))]
16904   "reload_completed
16905    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16906    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16907   [(const_int 0)]
16908 {
16909   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16910   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16911   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16912                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16913                                           GET_MODE (operands[3]),
16914                                           operands[4],
16915                                           operands[2])));
16916   ix86_free_from_memory (GET_MODE (operands[1]));
16917   DONE;
16918 })
16919
16920 (define_split
16921   [(set (match_operand 0 "register_operand" "")
16922         (match_operator 3 "binary_fp_operator"
16923            [(match_operand 1 "register_operand" "")
16924             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16925   "reload_completed
16926    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16927    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16928   [(const_int 0)]
16929 {
16930   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16931   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16932   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16933                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16934                                           GET_MODE (operands[3]),
16935                                           operands[1],
16936                                           operands[4])));
16937   ix86_free_from_memory (GET_MODE (operands[2]));
16938   DONE;
16939 })
16940 \f
16941 ;; FPU special functions.
16942
16943 ;; This pattern implements a no-op XFmode truncation for
16944 ;; all fancy i386 XFmode math functions.
16945
16946 (define_insn "truncxf<mode>2_i387_noop_unspec"
16947   [(set (match_operand:MODEF 0 "register_operand" "=f")
16948         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16949         UNSPEC_TRUNC_NOOP))]
16950   "TARGET_USE_FANCY_MATH_387"
16951   "* return output_387_reg_move (insn, operands);"
16952   [(set_attr "type" "fmov")
16953    (set_attr "mode" "<MODE>")])
16954
16955 (define_insn "sqrtxf2"
16956   [(set (match_operand:XF 0 "register_operand" "=f")
16957         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16958   "TARGET_USE_FANCY_MATH_387"
16959   "fsqrt"
16960   [(set_attr "type" "fpspc")
16961    (set_attr "mode" "XF")
16962    (set_attr "athlon_decode" "direct")
16963    (set_attr "amdfam10_decode" "direct")])
16964
16965 (define_insn "sqrt_extend<mode>xf2_i387"
16966   [(set (match_operand:XF 0 "register_operand" "=f")
16967         (sqrt:XF
16968           (float_extend:XF
16969             (match_operand:MODEF 1 "register_operand" "0"))))]
16970   "TARGET_USE_FANCY_MATH_387"
16971   "fsqrt"
16972   [(set_attr "type" "fpspc")
16973    (set_attr "mode" "XF")
16974    (set_attr "athlon_decode" "direct")
16975    (set_attr "amdfam10_decode" "direct")])
16976
16977 (define_insn "*rsqrtsf2_sse"
16978   [(set (match_operand:SF 0 "register_operand" "=x")
16979         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16980                    UNSPEC_RSQRT))]
16981   "TARGET_SSE_MATH"
16982   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16983   [(set_attr "type" "sse")
16984    (set_attr "atom_sse_attr" "rcp")
16985    (set_attr "prefix" "maybe_vex")
16986    (set_attr "mode" "SF")])
16987
16988 (define_expand "rsqrtsf2"
16989   [(set (match_operand:SF 0 "register_operand" "")
16990         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16991                    UNSPEC_RSQRT))]
16992   "TARGET_SSE_MATH"
16993 {
16994   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16995   DONE;
16996 })
16997
16998 (define_insn "*sqrt<mode>2_sse"
16999   [(set (match_operand:MODEF 0 "register_operand" "=x")
17000         (sqrt:MODEF
17001           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
17002   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17003   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
17004   [(set_attr "type" "sse")
17005    (set_attr "atom_sse_attr" "sqrt")
17006    (set_attr "prefix" "maybe_vex")
17007    (set_attr "mode" "<MODE>")
17008    (set_attr "athlon_decode" "*")
17009    (set_attr "amdfam10_decode" "*")])
17010
17011 (define_expand "sqrt<mode>2"
17012   [(set (match_operand:MODEF 0 "register_operand" "")
17013         (sqrt:MODEF
17014           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
17015   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
17016    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17017 {
17018   if (<MODE>mode == SFmode
17019       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
17020       && flag_finite_math_only && !flag_trapping_math
17021       && flag_unsafe_math_optimizations)
17022     {
17023       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
17024       DONE;
17025     }
17026
17027   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
17028     {
17029       rtx op0 = gen_reg_rtx (XFmode);
17030       rtx op1 = force_reg (<MODE>mode, operands[1]);
17031
17032       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
17033       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17034       DONE;
17035    }
17036 })
17037
17038 (define_insn "fpremxf4_i387"
17039   [(set (match_operand:XF 0 "register_operand" "=f")
17040         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17041                     (match_operand:XF 3 "register_operand" "1")]
17042                    UNSPEC_FPREM_F))
17043    (set (match_operand:XF 1 "register_operand" "=u")
17044         (unspec:XF [(match_dup 2) (match_dup 3)]
17045                    UNSPEC_FPREM_U))
17046    (set (reg:CCFP FPSR_REG)
17047         (unspec:CCFP [(match_dup 2) (match_dup 3)]
17048                      UNSPEC_C2_FLAG))]
17049   "TARGET_USE_FANCY_MATH_387"
17050   "fprem"
17051   [(set_attr "type" "fpspc")
17052    (set_attr "mode" "XF")])
17053
17054 (define_expand "fmodxf3"
17055   [(use (match_operand:XF 0 "register_operand" ""))
17056    (use (match_operand:XF 1 "general_operand" ""))
17057    (use (match_operand:XF 2 "general_operand" ""))]
17058   "TARGET_USE_FANCY_MATH_387"
17059 {
17060   rtx label = gen_label_rtx ();
17061
17062   rtx op1 = gen_reg_rtx (XFmode);
17063   rtx op2 = gen_reg_rtx (XFmode);
17064
17065   emit_move_insn (op2, operands[2]);
17066   emit_move_insn (op1, operands[1]);
17067
17068   emit_label (label);
17069   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17070   ix86_emit_fp_unordered_jump (label);
17071   LABEL_NUSES (label) = 1;
17072
17073   emit_move_insn (operands[0], op1);
17074   DONE;
17075 })
17076
17077 (define_expand "fmod<mode>3"
17078   [(use (match_operand:MODEF 0 "register_operand" ""))
17079    (use (match_operand:MODEF 1 "general_operand" ""))
17080    (use (match_operand:MODEF 2 "general_operand" ""))]
17081   "TARGET_USE_FANCY_MATH_387"
17082 {
17083   rtx label = gen_label_rtx ();
17084
17085   rtx op1 = gen_reg_rtx (XFmode);
17086   rtx op2 = gen_reg_rtx (XFmode);
17087
17088   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17089   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17090
17091   emit_label (label);
17092   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17093   ix86_emit_fp_unordered_jump (label);
17094   LABEL_NUSES (label) = 1;
17095
17096   /* Truncate the result properly for strict SSE math.  */
17097   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17098       && !TARGET_MIX_SSE_I387)
17099     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17100   else
17101     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17102
17103   DONE;
17104 })
17105
17106 (define_insn "fprem1xf4_i387"
17107   [(set (match_operand:XF 0 "register_operand" "=f")
17108         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17109                     (match_operand:XF 3 "register_operand" "1")]
17110                    UNSPEC_FPREM1_F))
17111    (set (match_operand:XF 1 "register_operand" "=u")
17112         (unspec:XF [(match_dup 2) (match_dup 3)]
17113                    UNSPEC_FPREM1_U))
17114    (set (reg:CCFP FPSR_REG)
17115         (unspec:CCFP [(match_dup 2) (match_dup 3)]
17116                      UNSPEC_C2_FLAG))]
17117   "TARGET_USE_FANCY_MATH_387"
17118   "fprem1"
17119   [(set_attr "type" "fpspc")
17120    (set_attr "mode" "XF")])
17121
17122 (define_expand "remainderxf3"
17123   [(use (match_operand:XF 0 "register_operand" ""))
17124    (use (match_operand:XF 1 "general_operand" ""))
17125    (use (match_operand:XF 2 "general_operand" ""))]
17126   "TARGET_USE_FANCY_MATH_387"
17127 {
17128   rtx label = gen_label_rtx ();
17129
17130   rtx op1 = gen_reg_rtx (XFmode);
17131   rtx op2 = gen_reg_rtx (XFmode);
17132
17133   emit_move_insn (op2, operands[2]);
17134   emit_move_insn (op1, operands[1]);
17135
17136   emit_label (label);
17137   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17138   ix86_emit_fp_unordered_jump (label);
17139   LABEL_NUSES (label) = 1;
17140
17141   emit_move_insn (operands[0], op1);
17142   DONE;
17143 })
17144
17145 (define_expand "remainder<mode>3"
17146   [(use (match_operand:MODEF 0 "register_operand" ""))
17147    (use (match_operand:MODEF 1 "general_operand" ""))
17148    (use (match_operand:MODEF 2 "general_operand" ""))]
17149   "TARGET_USE_FANCY_MATH_387"
17150 {
17151   rtx label = gen_label_rtx ();
17152
17153   rtx op1 = gen_reg_rtx (XFmode);
17154   rtx op2 = gen_reg_rtx (XFmode);
17155
17156   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17157   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17158
17159   emit_label (label);
17160
17161   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17162   ix86_emit_fp_unordered_jump (label);
17163   LABEL_NUSES (label) = 1;
17164
17165   /* Truncate the result properly for strict SSE math.  */
17166   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17167       && !TARGET_MIX_SSE_I387)
17168     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17169   else
17170     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17171
17172   DONE;
17173 })
17174
17175 (define_insn "*sinxf2_i387"
17176   [(set (match_operand:XF 0 "register_operand" "=f")
17177         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17178   "TARGET_USE_FANCY_MATH_387
17179    && flag_unsafe_math_optimizations"
17180   "fsin"
17181   [(set_attr "type" "fpspc")
17182    (set_attr "mode" "XF")])
17183
17184 (define_insn "*sin_extend<mode>xf2_i387"
17185   [(set (match_operand:XF 0 "register_operand" "=f")
17186         (unspec:XF [(float_extend:XF
17187                       (match_operand:MODEF 1 "register_operand" "0"))]
17188                    UNSPEC_SIN))]
17189   "TARGET_USE_FANCY_MATH_387
17190    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17191        || TARGET_MIX_SSE_I387)
17192    && flag_unsafe_math_optimizations"
17193   "fsin"
17194   [(set_attr "type" "fpspc")
17195    (set_attr "mode" "XF")])
17196
17197 (define_insn "*cosxf2_i387"
17198   [(set (match_operand:XF 0 "register_operand" "=f")
17199         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17200   "TARGET_USE_FANCY_MATH_387
17201    && flag_unsafe_math_optimizations"
17202   "fcos"
17203   [(set_attr "type" "fpspc")
17204    (set_attr "mode" "XF")])
17205
17206 (define_insn "*cos_extend<mode>xf2_i387"
17207   [(set (match_operand:XF 0 "register_operand" "=f")
17208         (unspec:XF [(float_extend:XF
17209                       (match_operand:MODEF 1 "register_operand" "0"))]
17210                    UNSPEC_COS))]
17211   "TARGET_USE_FANCY_MATH_387
17212    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17213        || TARGET_MIX_SSE_I387)
17214    && flag_unsafe_math_optimizations"
17215   "fcos"
17216   [(set_attr "type" "fpspc")
17217    (set_attr "mode" "XF")])
17218
17219 ;; When sincos pattern is defined, sin and cos builtin functions will be
17220 ;; expanded to sincos pattern with one of its outputs left unused.
17221 ;; CSE pass will figure out if two sincos patterns can be combined,
17222 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17223 ;; depending on the unused output.
17224
17225 (define_insn "sincosxf3"
17226   [(set (match_operand:XF 0 "register_operand" "=f")
17227         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17228                    UNSPEC_SINCOS_COS))
17229    (set (match_operand:XF 1 "register_operand" "=u")
17230         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17231   "TARGET_USE_FANCY_MATH_387
17232    && flag_unsafe_math_optimizations"
17233   "fsincos"
17234   [(set_attr "type" "fpspc")
17235    (set_attr "mode" "XF")])
17236
17237 (define_split
17238   [(set (match_operand:XF 0 "register_operand" "")
17239         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17240                    UNSPEC_SINCOS_COS))
17241    (set (match_operand:XF 1 "register_operand" "")
17242         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17243   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17244    && !(reload_completed || reload_in_progress)"
17245   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17246   "")
17247
17248 (define_split
17249   [(set (match_operand:XF 0 "register_operand" "")
17250         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17251                    UNSPEC_SINCOS_COS))
17252    (set (match_operand:XF 1 "register_operand" "")
17253         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17254   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17255    && !(reload_completed || reload_in_progress)"
17256   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17257   "")
17258
17259 (define_insn "sincos_extend<mode>xf3_i387"
17260   [(set (match_operand:XF 0 "register_operand" "=f")
17261         (unspec:XF [(float_extend:XF
17262                       (match_operand:MODEF 2 "register_operand" "0"))]
17263                    UNSPEC_SINCOS_COS))
17264    (set (match_operand:XF 1 "register_operand" "=u")
17265         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17266   "TARGET_USE_FANCY_MATH_387
17267    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17268        || TARGET_MIX_SSE_I387)
17269    && flag_unsafe_math_optimizations"
17270   "fsincos"
17271   [(set_attr "type" "fpspc")
17272    (set_attr "mode" "XF")])
17273
17274 (define_split
17275   [(set (match_operand:XF 0 "register_operand" "")
17276         (unspec:XF [(float_extend:XF
17277                       (match_operand:MODEF 2 "register_operand" ""))]
17278                    UNSPEC_SINCOS_COS))
17279    (set (match_operand:XF 1 "register_operand" "")
17280         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17281   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17282    && !(reload_completed || reload_in_progress)"
17283   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17284   "")
17285
17286 (define_split
17287   [(set (match_operand:XF 0 "register_operand" "")
17288         (unspec:XF [(float_extend:XF
17289                       (match_operand:MODEF 2 "register_operand" ""))]
17290                    UNSPEC_SINCOS_COS))
17291    (set (match_operand:XF 1 "register_operand" "")
17292         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17293   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17294    && !(reload_completed || reload_in_progress)"
17295   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17296   "")
17297
17298 (define_expand "sincos<mode>3"
17299   [(use (match_operand:MODEF 0 "register_operand" ""))
17300    (use (match_operand:MODEF 1 "register_operand" ""))
17301    (use (match_operand:MODEF 2 "register_operand" ""))]
17302   "TARGET_USE_FANCY_MATH_387
17303    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17304        || TARGET_MIX_SSE_I387)
17305    && flag_unsafe_math_optimizations"
17306 {
17307   rtx op0 = gen_reg_rtx (XFmode);
17308   rtx op1 = gen_reg_rtx (XFmode);
17309
17310   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17311   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17312   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17313   DONE;
17314 })
17315
17316 (define_insn "fptanxf4_i387"
17317   [(set (match_operand:XF 0 "register_operand" "=f")
17318         (match_operand:XF 3 "const_double_operand" "F"))
17319    (set (match_operand:XF 1 "register_operand" "=u")
17320         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17321                    UNSPEC_TAN))]
17322   "TARGET_USE_FANCY_MATH_387
17323    && flag_unsafe_math_optimizations
17324    && standard_80387_constant_p (operands[3]) == 2"
17325   "fptan"
17326   [(set_attr "type" "fpspc")
17327    (set_attr "mode" "XF")])
17328
17329 (define_insn "fptan_extend<mode>xf4_i387"
17330   [(set (match_operand:MODEF 0 "register_operand" "=f")
17331         (match_operand:MODEF 3 "const_double_operand" "F"))
17332    (set (match_operand:XF 1 "register_operand" "=u")
17333         (unspec:XF [(float_extend:XF
17334                       (match_operand:MODEF 2 "register_operand" "0"))]
17335                    UNSPEC_TAN))]
17336   "TARGET_USE_FANCY_MATH_387
17337    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17338        || TARGET_MIX_SSE_I387)
17339    && flag_unsafe_math_optimizations
17340    && standard_80387_constant_p (operands[3]) == 2"
17341   "fptan"
17342   [(set_attr "type" "fpspc")
17343    (set_attr "mode" "XF")])
17344
17345 (define_expand "tanxf2"
17346   [(use (match_operand:XF 0 "register_operand" ""))
17347    (use (match_operand:XF 1 "register_operand" ""))]
17348   "TARGET_USE_FANCY_MATH_387
17349    && flag_unsafe_math_optimizations"
17350 {
17351   rtx one = gen_reg_rtx (XFmode);
17352   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17353
17354   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17355   DONE;
17356 })
17357
17358 (define_expand "tan<mode>2"
17359   [(use (match_operand:MODEF 0 "register_operand" ""))
17360    (use (match_operand:MODEF 1 "register_operand" ""))]
17361   "TARGET_USE_FANCY_MATH_387
17362    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17363        || TARGET_MIX_SSE_I387)
17364    && flag_unsafe_math_optimizations"
17365 {
17366   rtx op0 = gen_reg_rtx (XFmode);
17367
17368   rtx one = gen_reg_rtx (<MODE>mode);
17369   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17370
17371   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17372                                              operands[1], op2));
17373   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17374   DONE;
17375 })
17376
17377 (define_insn "*fpatanxf3_i387"
17378   [(set (match_operand:XF 0 "register_operand" "=f")
17379         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17380                     (match_operand:XF 2 "register_operand" "u")]
17381                    UNSPEC_FPATAN))
17382    (clobber (match_scratch:XF 3 "=2"))]
17383   "TARGET_USE_FANCY_MATH_387
17384    && flag_unsafe_math_optimizations"
17385   "fpatan"
17386   [(set_attr "type" "fpspc")
17387    (set_attr "mode" "XF")])
17388
17389 (define_insn "fpatan_extend<mode>xf3_i387"
17390   [(set (match_operand:XF 0 "register_operand" "=f")
17391         (unspec:XF [(float_extend:XF
17392                       (match_operand:MODEF 1 "register_operand" "0"))
17393                     (float_extend:XF
17394                       (match_operand:MODEF 2 "register_operand" "u"))]
17395                    UNSPEC_FPATAN))
17396    (clobber (match_scratch:XF 3 "=2"))]
17397   "TARGET_USE_FANCY_MATH_387
17398    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17399        || TARGET_MIX_SSE_I387)
17400    && flag_unsafe_math_optimizations"
17401   "fpatan"
17402   [(set_attr "type" "fpspc")
17403    (set_attr "mode" "XF")])
17404
17405 (define_expand "atan2xf3"
17406   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17407                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17408                                (match_operand:XF 1 "register_operand" "")]
17409                               UNSPEC_FPATAN))
17410               (clobber (match_scratch:XF 3 ""))])]
17411   "TARGET_USE_FANCY_MATH_387
17412    && flag_unsafe_math_optimizations"
17413   "")
17414
17415 (define_expand "atan2<mode>3"
17416   [(use (match_operand:MODEF 0 "register_operand" ""))
17417    (use (match_operand:MODEF 1 "register_operand" ""))
17418    (use (match_operand:MODEF 2 "register_operand" ""))]
17419   "TARGET_USE_FANCY_MATH_387
17420    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17421        || TARGET_MIX_SSE_I387)
17422    && flag_unsafe_math_optimizations"
17423 {
17424   rtx op0 = gen_reg_rtx (XFmode);
17425
17426   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17427   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17428   DONE;
17429 })
17430
17431 (define_expand "atanxf2"
17432   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17433                    (unspec:XF [(match_dup 2)
17434                                (match_operand:XF 1 "register_operand" "")]
17435                               UNSPEC_FPATAN))
17436               (clobber (match_scratch:XF 3 ""))])]
17437   "TARGET_USE_FANCY_MATH_387
17438    && flag_unsafe_math_optimizations"
17439 {
17440   operands[2] = gen_reg_rtx (XFmode);
17441   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17442 })
17443
17444 (define_expand "atan<mode>2"
17445   [(use (match_operand:MODEF 0 "register_operand" ""))
17446    (use (match_operand:MODEF 1 "register_operand" ""))]
17447   "TARGET_USE_FANCY_MATH_387
17448    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17449        || TARGET_MIX_SSE_I387)
17450    && flag_unsafe_math_optimizations"
17451 {
17452   rtx op0 = gen_reg_rtx (XFmode);
17453
17454   rtx op2 = gen_reg_rtx (<MODE>mode);
17455   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17456
17457   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17458   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17459   DONE;
17460 })
17461
17462 (define_expand "asinxf2"
17463   [(set (match_dup 2)
17464         (mult:XF (match_operand:XF 1 "register_operand" "")
17465                  (match_dup 1)))
17466    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17467    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17468    (parallel [(set (match_operand:XF 0 "register_operand" "")
17469                    (unspec:XF [(match_dup 5) (match_dup 1)]
17470                               UNSPEC_FPATAN))
17471               (clobber (match_scratch:XF 6 ""))])]
17472   "TARGET_USE_FANCY_MATH_387
17473    && flag_unsafe_math_optimizations"
17474 {
17475   int i;
17476
17477   if (optimize_insn_for_size_p ())
17478     FAIL;
17479
17480   for (i = 2; i < 6; i++)
17481     operands[i] = gen_reg_rtx (XFmode);
17482
17483   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17484 })
17485
17486 (define_expand "asin<mode>2"
17487   [(use (match_operand:MODEF 0 "register_operand" ""))
17488    (use (match_operand:MODEF 1 "general_operand" ""))]
17489  "TARGET_USE_FANCY_MATH_387
17490    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17491        || TARGET_MIX_SSE_I387)
17492    && flag_unsafe_math_optimizations"
17493 {
17494   rtx op0 = gen_reg_rtx (XFmode);
17495   rtx op1 = gen_reg_rtx (XFmode);
17496
17497   if (optimize_insn_for_size_p ())
17498     FAIL;
17499
17500   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17501   emit_insn (gen_asinxf2 (op0, op1));
17502   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17503   DONE;
17504 })
17505
17506 (define_expand "acosxf2"
17507   [(set (match_dup 2)
17508         (mult:XF (match_operand:XF 1 "register_operand" "")
17509                  (match_dup 1)))
17510    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17511    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17512    (parallel [(set (match_operand:XF 0 "register_operand" "")
17513                    (unspec:XF [(match_dup 1) (match_dup 5)]
17514                               UNSPEC_FPATAN))
17515               (clobber (match_scratch:XF 6 ""))])]
17516   "TARGET_USE_FANCY_MATH_387
17517    && flag_unsafe_math_optimizations"
17518 {
17519   int i;
17520
17521   if (optimize_insn_for_size_p ())
17522     FAIL;
17523
17524   for (i = 2; i < 6; i++)
17525     operands[i] = gen_reg_rtx (XFmode);
17526
17527   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17528 })
17529
17530 (define_expand "acos<mode>2"
17531   [(use (match_operand:MODEF 0 "register_operand" ""))
17532    (use (match_operand:MODEF 1 "general_operand" ""))]
17533  "TARGET_USE_FANCY_MATH_387
17534    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17535        || TARGET_MIX_SSE_I387)
17536    && flag_unsafe_math_optimizations"
17537 {
17538   rtx op0 = gen_reg_rtx (XFmode);
17539   rtx op1 = gen_reg_rtx (XFmode);
17540
17541   if (optimize_insn_for_size_p ())
17542     FAIL;
17543
17544   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17545   emit_insn (gen_acosxf2 (op0, op1));
17546   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17547   DONE;
17548 })
17549
17550 (define_insn "fyl2xxf3_i387"
17551   [(set (match_operand:XF 0 "register_operand" "=f")
17552         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17553                     (match_operand:XF 2 "register_operand" "u")]
17554                    UNSPEC_FYL2X))
17555    (clobber (match_scratch:XF 3 "=2"))]
17556   "TARGET_USE_FANCY_MATH_387
17557    && flag_unsafe_math_optimizations"
17558   "fyl2x"
17559   [(set_attr "type" "fpspc")
17560    (set_attr "mode" "XF")])
17561
17562 (define_insn "fyl2x_extend<mode>xf3_i387"
17563   [(set (match_operand:XF 0 "register_operand" "=f")
17564         (unspec:XF [(float_extend:XF
17565                       (match_operand:MODEF 1 "register_operand" "0"))
17566                     (match_operand:XF 2 "register_operand" "u")]
17567                    UNSPEC_FYL2X))
17568    (clobber (match_scratch:XF 3 "=2"))]
17569   "TARGET_USE_FANCY_MATH_387
17570    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17571        || TARGET_MIX_SSE_I387)
17572    && flag_unsafe_math_optimizations"
17573   "fyl2x"
17574   [(set_attr "type" "fpspc")
17575    (set_attr "mode" "XF")])
17576
17577 (define_expand "logxf2"
17578   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17579                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17580                                (match_dup 2)] UNSPEC_FYL2X))
17581               (clobber (match_scratch:XF 3 ""))])]
17582   "TARGET_USE_FANCY_MATH_387
17583    && flag_unsafe_math_optimizations"
17584 {
17585   operands[2] = gen_reg_rtx (XFmode);
17586   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17587 })
17588
17589 (define_expand "log<mode>2"
17590   [(use (match_operand:MODEF 0 "register_operand" ""))
17591    (use (match_operand:MODEF 1 "register_operand" ""))]
17592   "TARGET_USE_FANCY_MATH_387
17593    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17594        || TARGET_MIX_SSE_I387)
17595    && flag_unsafe_math_optimizations"
17596 {
17597   rtx op0 = gen_reg_rtx (XFmode);
17598
17599   rtx op2 = gen_reg_rtx (XFmode);
17600   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17601
17602   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17603   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17604   DONE;
17605 })
17606
17607 (define_expand "log10xf2"
17608   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17609                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17610                                (match_dup 2)] UNSPEC_FYL2X))
17611               (clobber (match_scratch:XF 3 ""))])]
17612   "TARGET_USE_FANCY_MATH_387
17613    && flag_unsafe_math_optimizations"
17614 {
17615   operands[2] = gen_reg_rtx (XFmode);
17616   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17617 })
17618
17619 (define_expand "log10<mode>2"
17620   [(use (match_operand:MODEF 0 "register_operand" ""))
17621    (use (match_operand:MODEF 1 "register_operand" ""))]
17622   "TARGET_USE_FANCY_MATH_387
17623    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17624        || TARGET_MIX_SSE_I387)
17625    && flag_unsafe_math_optimizations"
17626 {
17627   rtx op0 = gen_reg_rtx (XFmode);
17628
17629   rtx op2 = gen_reg_rtx (XFmode);
17630   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17631
17632   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17633   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17634   DONE;
17635 })
17636
17637 (define_expand "log2xf2"
17638   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17639                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17640                                (match_dup 2)] UNSPEC_FYL2X))
17641               (clobber (match_scratch:XF 3 ""))])]
17642   "TARGET_USE_FANCY_MATH_387
17643    && flag_unsafe_math_optimizations"
17644 {
17645   operands[2] = gen_reg_rtx (XFmode);
17646   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17647 })
17648
17649 (define_expand "log2<mode>2"
17650   [(use (match_operand:MODEF 0 "register_operand" ""))
17651    (use (match_operand:MODEF 1 "register_operand" ""))]
17652   "TARGET_USE_FANCY_MATH_387
17653    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17654        || TARGET_MIX_SSE_I387)
17655    && flag_unsafe_math_optimizations"
17656 {
17657   rtx op0 = gen_reg_rtx (XFmode);
17658
17659   rtx op2 = gen_reg_rtx (XFmode);
17660   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17661
17662   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17663   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17664   DONE;
17665 })
17666
17667 (define_insn "fyl2xp1xf3_i387"
17668   [(set (match_operand:XF 0 "register_operand" "=f")
17669         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17670                     (match_operand:XF 2 "register_operand" "u")]
17671                    UNSPEC_FYL2XP1))
17672    (clobber (match_scratch:XF 3 "=2"))]
17673   "TARGET_USE_FANCY_MATH_387
17674    && flag_unsafe_math_optimizations"
17675   "fyl2xp1"
17676   [(set_attr "type" "fpspc")
17677    (set_attr "mode" "XF")])
17678
17679 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17680   [(set (match_operand:XF 0 "register_operand" "=f")
17681         (unspec:XF [(float_extend:XF
17682                       (match_operand:MODEF 1 "register_operand" "0"))
17683                     (match_operand:XF 2 "register_operand" "u")]
17684                    UNSPEC_FYL2XP1))
17685    (clobber (match_scratch:XF 3 "=2"))]
17686   "TARGET_USE_FANCY_MATH_387
17687    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17688        || TARGET_MIX_SSE_I387)
17689    && flag_unsafe_math_optimizations"
17690   "fyl2xp1"
17691   [(set_attr "type" "fpspc")
17692    (set_attr "mode" "XF")])
17693
17694 (define_expand "log1pxf2"
17695   [(use (match_operand:XF 0 "register_operand" ""))
17696    (use (match_operand:XF 1 "register_operand" ""))]
17697   "TARGET_USE_FANCY_MATH_387
17698    && flag_unsafe_math_optimizations"
17699 {
17700   if (optimize_insn_for_size_p ())
17701     FAIL;
17702
17703   ix86_emit_i387_log1p (operands[0], operands[1]);
17704   DONE;
17705 })
17706
17707 (define_expand "log1p<mode>2"
17708   [(use (match_operand:MODEF 0 "register_operand" ""))
17709    (use (match_operand:MODEF 1 "register_operand" ""))]
17710   "TARGET_USE_FANCY_MATH_387
17711    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17712        || TARGET_MIX_SSE_I387)
17713    && flag_unsafe_math_optimizations"
17714 {
17715   rtx op0;
17716
17717   if (optimize_insn_for_size_p ())
17718     FAIL;
17719
17720   op0 = gen_reg_rtx (XFmode);
17721
17722   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17723
17724   ix86_emit_i387_log1p (op0, operands[1]);
17725   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17726   DONE;
17727 })
17728
17729 (define_insn "fxtractxf3_i387"
17730   [(set (match_operand:XF 0 "register_operand" "=f")
17731         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17732                    UNSPEC_XTRACT_FRACT))
17733    (set (match_operand:XF 1 "register_operand" "=u")
17734         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17735   "TARGET_USE_FANCY_MATH_387
17736    && flag_unsafe_math_optimizations"
17737   "fxtract"
17738   [(set_attr "type" "fpspc")
17739    (set_attr "mode" "XF")])
17740
17741 (define_insn "fxtract_extend<mode>xf3_i387"
17742   [(set (match_operand:XF 0 "register_operand" "=f")
17743         (unspec:XF [(float_extend:XF
17744                       (match_operand:MODEF 2 "register_operand" "0"))]
17745                    UNSPEC_XTRACT_FRACT))
17746    (set (match_operand:XF 1 "register_operand" "=u")
17747         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17748   "TARGET_USE_FANCY_MATH_387
17749    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17750        || TARGET_MIX_SSE_I387)
17751    && flag_unsafe_math_optimizations"
17752   "fxtract"
17753   [(set_attr "type" "fpspc")
17754    (set_attr "mode" "XF")])
17755
17756 (define_expand "logbxf2"
17757   [(parallel [(set (match_dup 2)
17758                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17759                               UNSPEC_XTRACT_FRACT))
17760               (set (match_operand:XF 0 "register_operand" "")
17761                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17762   "TARGET_USE_FANCY_MATH_387
17763    && flag_unsafe_math_optimizations"
17764 {
17765   operands[2] = gen_reg_rtx (XFmode);
17766 })
17767
17768 (define_expand "logb<mode>2"
17769   [(use (match_operand:MODEF 0 "register_operand" ""))
17770    (use (match_operand:MODEF 1 "register_operand" ""))]
17771   "TARGET_USE_FANCY_MATH_387
17772    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17773        || TARGET_MIX_SSE_I387)
17774    && flag_unsafe_math_optimizations"
17775 {
17776   rtx op0 = gen_reg_rtx (XFmode);
17777   rtx op1 = gen_reg_rtx (XFmode);
17778
17779   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17780   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17781   DONE;
17782 })
17783
17784 (define_expand "ilogbxf2"
17785   [(use (match_operand:SI 0 "register_operand" ""))
17786    (use (match_operand:XF 1 "register_operand" ""))]
17787   "TARGET_USE_FANCY_MATH_387
17788    && flag_unsafe_math_optimizations"
17789 {
17790   rtx op0, op1;
17791
17792   if (optimize_insn_for_size_p ())
17793     FAIL;
17794
17795   op0 = gen_reg_rtx (XFmode);
17796   op1 = gen_reg_rtx (XFmode);
17797
17798   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17799   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17800   DONE;
17801 })
17802
17803 (define_expand "ilogb<mode>2"
17804   [(use (match_operand:SI 0 "register_operand" ""))
17805    (use (match_operand:MODEF 1 "register_operand" ""))]
17806   "TARGET_USE_FANCY_MATH_387
17807    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17808        || TARGET_MIX_SSE_I387)
17809    && flag_unsafe_math_optimizations"
17810 {
17811   rtx op0, op1;
17812
17813   if (optimize_insn_for_size_p ())
17814     FAIL;
17815
17816   op0 = gen_reg_rtx (XFmode);
17817   op1 = gen_reg_rtx (XFmode);
17818
17819   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17820   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17821   DONE;
17822 })
17823
17824 (define_insn "*f2xm1xf2_i387"
17825   [(set (match_operand:XF 0 "register_operand" "=f")
17826         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17827                    UNSPEC_F2XM1))]
17828   "TARGET_USE_FANCY_MATH_387
17829    && flag_unsafe_math_optimizations"
17830   "f2xm1"
17831   [(set_attr "type" "fpspc")
17832    (set_attr "mode" "XF")])
17833
17834 (define_insn "*fscalexf4_i387"
17835   [(set (match_operand:XF 0 "register_operand" "=f")
17836         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17837                     (match_operand:XF 3 "register_operand" "1")]
17838                    UNSPEC_FSCALE_FRACT))
17839    (set (match_operand:XF 1 "register_operand" "=u")
17840         (unspec:XF [(match_dup 2) (match_dup 3)]
17841                    UNSPEC_FSCALE_EXP))]
17842   "TARGET_USE_FANCY_MATH_387
17843    && flag_unsafe_math_optimizations"
17844   "fscale"
17845   [(set_attr "type" "fpspc")
17846    (set_attr "mode" "XF")])
17847
17848 (define_expand "expNcorexf3"
17849   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17850                                (match_operand:XF 2 "register_operand" "")))
17851    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17852    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17853    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17854    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17855    (parallel [(set (match_operand:XF 0 "register_operand" "")
17856                    (unspec:XF [(match_dup 8) (match_dup 4)]
17857                               UNSPEC_FSCALE_FRACT))
17858               (set (match_dup 9)
17859                    (unspec:XF [(match_dup 8) (match_dup 4)]
17860                               UNSPEC_FSCALE_EXP))])]
17861   "TARGET_USE_FANCY_MATH_387
17862    && flag_unsafe_math_optimizations"
17863 {
17864   int i;
17865
17866   if (optimize_insn_for_size_p ())
17867     FAIL;
17868
17869   for (i = 3; i < 10; i++)
17870     operands[i] = gen_reg_rtx (XFmode);
17871
17872   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17873 })
17874
17875 (define_expand "expxf2"
17876   [(use (match_operand:XF 0 "register_operand" ""))
17877    (use (match_operand:XF 1 "register_operand" ""))]
17878   "TARGET_USE_FANCY_MATH_387
17879    && flag_unsafe_math_optimizations"
17880 {
17881   rtx op2;
17882
17883   if (optimize_insn_for_size_p ())
17884     FAIL;
17885
17886   op2 = gen_reg_rtx (XFmode);
17887   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17888
17889   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17890   DONE;
17891 })
17892
17893 (define_expand "exp<mode>2"
17894   [(use (match_operand:MODEF 0 "register_operand" ""))
17895    (use (match_operand:MODEF 1 "general_operand" ""))]
17896  "TARGET_USE_FANCY_MATH_387
17897    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17898        || TARGET_MIX_SSE_I387)
17899    && flag_unsafe_math_optimizations"
17900 {
17901   rtx op0, op1;
17902
17903   if (optimize_insn_for_size_p ())
17904     FAIL;
17905
17906   op0 = gen_reg_rtx (XFmode);
17907   op1 = gen_reg_rtx (XFmode);
17908
17909   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17910   emit_insn (gen_expxf2 (op0, op1));
17911   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17912   DONE;
17913 })
17914
17915 (define_expand "exp10xf2"
17916   [(use (match_operand:XF 0 "register_operand" ""))
17917    (use (match_operand:XF 1 "register_operand" ""))]
17918   "TARGET_USE_FANCY_MATH_387
17919    && flag_unsafe_math_optimizations"
17920 {
17921   rtx op2;
17922
17923   if (optimize_insn_for_size_p ())
17924     FAIL;
17925
17926   op2 = gen_reg_rtx (XFmode);
17927   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17928
17929   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17930   DONE;
17931 })
17932
17933 (define_expand "exp10<mode>2"
17934   [(use (match_operand:MODEF 0 "register_operand" ""))
17935    (use (match_operand:MODEF 1 "general_operand" ""))]
17936  "TARGET_USE_FANCY_MATH_387
17937    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17938        || TARGET_MIX_SSE_I387)
17939    && flag_unsafe_math_optimizations"
17940 {
17941   rtx op0, op1;
17942
17943   if (optimize_insn_for_size_p ())
17944     FAIL;
17945
17946   op0 = gen_reg_rtx (XFmode);
17947   op1 = gen_reg_rtx (XFmode);
17948
17949   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17950   emit_insn (gen_exp10xf2 (op0, op1));
17951   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17952   DONE;
17953 })
17954
17955 (define_expand "exp2xf2"
17956   [(use (match_operand:XF 0 "register_operand" ""))
17957    (use (match_operand:XF 1 "register_operand" ""))]
17958   "TARGET_USE_FANCY_MATH_387
17959    && flag_unsafe_math_optimizations"
17960 {
17961   rtx op2;
17962
17963   if (optimize_insn_for_size_p ())
17964     FAIL;
17965
17966   op2 = gen_reg_rtx (XFmode);
17967   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17968
17969   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17970   DONE;
17971 })
17972
17973 (define_expand "exp2<mode>2"
17974   [(use (match_operand:MODEF 0 "register_operand" ""))
17975    (use (match_operand:MODEF 1 "general_operand" ""))]
17976  "TARGET_USE_FANCY_MATH_387
17977    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17978        || TARGET_MIX_SSE_I387)
17979    && flag_unsafe_math_optimizations"
17980 {
17981   rtx op0, op1;
17982
17983   if (optimize_insn_for_size_p ())
17984     FAIL;
17985
17986   op0 = gen_reg_rtx (XFmode);
17987   op1 = gen_reg_rtx (XFmode);
17988
17989   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17990   emit_insn (gen_exp2xf2 (op0, op1));
17991   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17992   DONE;
17993 })
17994
17995 (define_expand "expm1xf2"
17996   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17997                                (match_dup 2)))
17998    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17999    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18000    (set (match_dup 9) (float_extend:XF (match_dup 13)))
18001    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18002    (parallel [(set (match_dup 7)
18003                    (unspec:XF [(match_dup 6) (match_dup 4)]
18004                               UNSPEC_FSCALE_FRACT))
18005               (set (match_dup 8)
18006                    (unspec:XF [(match_dup 6) (match_dup 4)]
18007                               UNSPEC_FSCALE_EXP))])
18008    (parallel [(set (match_dup 10)
18009                    (unspec:XF [(match_dup 9) (match_dup 8)]
18010                               UNSPEC_FSCALE_FRACT))
18011               (set (match_dup 11)
18012                    (unspec:XF [(match_dup 9) (match_dup 8)]
18013                               UNSPEC_FSCALE_EXP))])
18014    (set (match_dup 12) (minus:XF (match_dup 10)
18015                                  (float_extend:XF (match_dup 13))))
18016    (set (match_operand:XF 0 "register_operand" "")
18017         (plus:XF (match_dup 12) (match_dup 7)))]
18018   "TARGET_USE_FANCY_MATH_387
18019    && flag_unsafe_math_optimizations"
18020 {
18021   int i;
18022
18023   if (optimize_insn_for_size_p ())
18024     FAIL;
18025
18026   for (i = 2; i < 13; i++)
18027     operands[i] = gen_reg_rtx (XFmode);
18028
18029   operands[13]
18030     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
18031
18032   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
18033 })
18034
18035 (define_expand "expm1<mode>2"
18036   [(use (match_operand:MODEF 0 "register_operand" ""))
18037    (use (match_operand:MODEF 1 "general_operand" ""))]
18038  "TARGET_USE_FANCY_MATH_387
18039    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18040        || TARGET_MIX_SSE_I387)
18041    && flag_unsafe_math_optimizations"
18042 {
18043   rtx op0, op1;
18044
18045   if (optimize_insn_for_size_p ())
18046     FAIL;
18047
18048   op0 = gen_reg_rtx (XFmode);
18049   op1 = gen_reg_rtx (XFmode);
18050
18051   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18052   emit_insn (gen_expm1xf2 (op0, op1));
18053   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18054   DONE;
18055 })
18056
18057 (define_expand "ldexpxf3"
18058   [(set (match_dup 3)
18059         (float:XF (match_operand:SI 2 "register_operand" "")))
18060    (parallel [(set (match_operand:XF 0 " register_operand" "")
18061                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18062                                (match_dup 3)]
18063                               UNSPEC_FSCALE_FRACT))
18064               (set (match_dup 4)
18065                    (unspec:XF [(match_dup 1) (match_dup 3)]
18066                               UNSPEC_FSCALE_EXP))])]
18067   "TARGET_USE_FANCY_MATH_387
18068    && flag_unsafe_math_optimizations"
18069 {
18070   if (optimize_insn_for_size_p ())
18071     FAIL;
18072
18073   operands[3] = gen_reg_rtx (XFmode);
18074   operands[4] = gen_reg_rtx (XFmode);
18075 })
18076
18077 (define_expand "ldexp<mode>3"
18078   [(use (match_operand:MODEF 0 "register_operand" ""))
18079    (use (match_operand:MODEF 1 "general_operand" ""))
18080    (use (match_operand:SI 2 "register_operand" ""))]
18081  "TARGET_USE_FANCY_MATH_387
18082    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18083        || TARGET_MIX_SSE_I387)
18084    && flag_unsafe_math_optimizations"
18085 {
18086   rtx op0, op1;
18087
18088   if (optimize_insn_for_size_p ())
18089     FAIL;
18090
18091   op0 = gen_reg_rtx (XFmode);
18092   op1 = gen_reg_rtx (XFmode);
18093
18094   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18095   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
18096   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18097   DONE;
18098 })
18099
18100 (define_expand "scalbxf3"
18101   [(parallel [(set (match_operand:XF 0 " register_operand" "")
18102                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18103                                (match_operand:XF 2 "register_operand" "")]
18104                               UNSPEC_FSCALE_FRACT))
18105               (set (match_dup 3)
18106                    (unspec:XF [(match_dup 1) (match_dup 2)]
18107                               UNSPEC_FSCALE_EXP))])]
18108   "TARGET_USE_FANCY_MATH_387
18109    && flag_unsafe_math_optimizations"
18110 {
18111   if (optimize_insn_for_size_p ())
18112     FAIL;
18113
18114   operands[3] = gen_reg_rtx (XFmode);
18115 })
18116
18117 (define_expand "scalb<mode>3"
18118   [(use (match_operand:MODEF 0 "register_operand" ""))
18119    (use (match_operand:MODEF 1 "general_operand" ""))
18120    (use (match_operand:MODEF 2 "register_operand" ""))]
18121  "TARGET_USE_FANCY_MATH_387
18122    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18123        || TARGET_MIX_SSE_I387)
18124    && flag_unsafe_math_optimizations"
18125 {
18126   rtx op0, op1, op2;
18127
18128   if (optimize_insn_for_size_p ())
18129     FAIL;
18130
18131   op0 = gen_reg_rtx (XFmode);
18132   op1 = gen_reg_rtx (XFmode);
18133   op2 = gen_reg_rtx (XFmode);
18134
18135   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18136   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18137   emit_insn (gen_scalbxf3 (op0, op1, op2));
18138   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18139   DONE;
18140 })
18141 \f
18142
18143 (define_insn "sse4_1_round<mode>2"
18144   [(set (match_operand:MODEF 0 "register_operand" "=x")
18145         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18146                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
18147                       UNSPEC_ROUND))]
18148   "TARGET_ROUND"
18149   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
18150   [(set_attr "type" "ssecvt")
18151    (set_attr "prefix_extra" "1")
18152    (set_attr "prefix" "maybe_vex")
18153    (set_attr "mode" "<MODE>")])
18154
18155 (define_insn "rintxf2"
18156   [(set (match_operand:XF 0 "register_operand" "=f")
18157         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18158                    UNSPEC_FRNDINT))]
18159   "TARGET_USE_FANCY_MATH_387
18160    && flag_unsafe_math_optimizations"
18161   "frndint"
18162   [(set_attr "type" "fpspc")
18163    (set_attr "mode" "XF")])
18164
18165 (define_expand "rint<mode>2"
18166   [(use (match_operand:MODEF 0 "register_operand" ""))
18167    (use (match_operand:MODEF 1 "register_operand" ""))]
18168   "(TARGET_USE_FANCY_MATH_387
18169     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18170         || TARGET_MIX_SSE_I387)
18171     && flag_unsafe_math_optimizations)
18172    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18173        && !flag_trapping_math)"
18174 {
18175   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18176       && !flag_trapping_math)
18177     {
18178       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18179         FAIL;
18180       if (TARGET_ROUND)
18181         emit_insn (gen_sse4_1_round<mode>2
18182                    (operands[0], operands[1], GEN_INT (0x04)));
18183       else
18184         ix86_expand_rint (operand0, operand1);
18185     }
18186   else
18187     {
18188       rtx op0 = gen_reg_rtx (XFmode);
18189       rtx op1 = gen_reg_rtx (XFmode);
18190
18191       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18192       emit_insn (gen_rintxf2 (op0, op1));
18193
18194       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18195     }
18196   DONE;
18197 })
18198
18199 (define_expand "round<mode>2"
18200   [(match_operand:MODEF 0 "register_operand" "")
18201    (match_operand:MODEF 1 "nonimmediate_operand" "")]
18202   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18203    && !flag_trapping_math && !flag_rounding_math"
18204 {
18205   if (optimize_insn_for_size_p ())
18206     FAIL;
18207   if (TARGET_64BIT || (<MODE>mode != DFmode))
18208     ix86_expand_round (operand0, operand1);
18209   else
18210     ix86_expand_rounddf_32 (operand0, operand1);
18211   DONE;
18212 })
18213
18214 (define_insn_and_split "*fistdi2_1"
18215   [(set (match_operand:DI 0 "nonimmediate_operand" "")
18216         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18217                    UNSPEC_FIST))]
18218   "TARGET_USE_FANCY_MATH_387
18219    && !(reload_completed || reload_in_progress)"
18220   "#"
18221   "&& 1"
18222   [(const_int 0)]
18223 {
18224   if (memory_operand (operands[0], VOIDmode))
18225     emit_insn (gen_fistdi2 (operands[0], operands[1]));
18226   else
18227     {
18228       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18229       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18230                                          operands[2]));
18231     }
18232   DONE;
18233 }
18234   [(set_attr "type" "fpspc")
18235    (set_attr "mode" "DI")])
18236
18237 (define_insn "fistdi2"
18238   [(set (match_operand:DI 0 "memory_operand" "=m")
18239         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18240                    UNSPEC_FIST))
18241    (clobber (match_scratch:XF 2 "=&1f"))]
18242   "TARGET_USE_FANCY_MATH_387"
18243   "* return output_fix_trunc (insn, operands, 0);"
18244   [(set_attr "type" "fpspc")
18245    (set_attr "mode" "DI")])
18246
18247 (define_insn "fistdi2_with_temp"
18248   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18249         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18250                    UNSPEC_FIST))
18251    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18252    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18253   "TARGET_USE_FANCY_MATH_387"
18254   "#"
18255   [(set_attr "type" "fpspc")
18256    (set_attr "mode" "DI")])
18257
18258 (define_split
18259   [(set (match_operand:DI 0 "register_operand" "")
18260         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18261                    UNSPEC_FIST))
18262    (clobber (match_operand:DI 2 "memory_operand" ""))
18263    (clobber (match_scratch 3 ""))]
18264   "reload_completed"
18265   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18266               (clobber (match_dup 3))])
18267    (set (match_dup 0) (match_dup 2))]
18268   "")
18269
18270 (define_split
18271   [(set (match_operand:DI 0 "memory_operand" "")
18272         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18273                    UNSPEC_FIST))
18274    (clobber (match_operand:DI 2 "memory_operand" ""))
18275    (clobber (match_scratch 3 ""))]
18276   "reload_completed"
18277   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18278               (clobber (match_dup 3))])]
18279   "")
18280
18281 (define_insn_and_split "*fist<mode>2_1"
18282   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18283         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18284                            UNSPEC_FIST))]
18285   "TARGET_USE_FANCY_MATH_387
18286    && !(reload_completed || reload_in_progress)"
18287   "#"
18288   "&& 1"
18289   [(const_int 0)]
18290 {
18291   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18292   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18293                                         operands[2]));
18294   DONE;
18295 }
18296   [(set_attr "type" "fpspc")
18297    (set_attr "mode" "<MODE>")])
18298
18299 (define_insn "fist<mode>2"
18300   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18301         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18302                            UNSPEC_FIST))]
18303   "TARGET_USE_FANCY_MATH_387"
18304   "* return output_fix_trunc (insn, operands, 0);"
18305   [(set_attr "type" "fpspc")
18306    (set_attr "mode" "<MODE>")])
18307
18308 (define_insn "fist<mode>2_with_temp"
18309   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18310         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18311                            UNSPEC_FIST))
18312    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18313   "TARGET_USE_FANCY_MATH_387"
18314   "#"
18315   [(set_attr "type" "fpspc")
18316    (set_attr "mode" "<MODE>")])
18317
18318 (define_split
18319   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18320         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18321                            UNSPEC_FIST))
18322    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18323   "reload_completed"
18324   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18325    (set (match_dup 0) (match_dup 2))]
18326   "")
18327
18328 (define_split
18329   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18330         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18331                            UNSPEC_FIST))
18332    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18333   "reload_completed"
18334   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18335   "")
18336
18337 (define_expand "lrintxf<mode>2"
18338   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18339      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18340                       UNSPEC_FIST))]
18341   "TARGET_USE_FANCY_MATH_387"
18342   "")
18343
18344 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18345   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18346      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18347                         UNSPEC_FIX_NOTRUNC))]
18348   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18349    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18350   "")
18351
18352 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18353   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18354    (match_operand:MODEF 1 "register_operand" "")]
18355   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18356    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18357    && !flag_trapping_math && !flag_rounding_math"
18358 {
18359   if (optimize_insn_for_size_p ())
18360     FAIL;
18361   ix86_expand_lround (operand0, operand1);
18362   DONE;
18363 })
18364
18365 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18366 (define_insn_and_split "frndintxf2_floor"
18367   [(set (match_operand:XF 0 "register_operand" "")
18368         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18369          UNSPEC_FRNDINT_FLOOR))
18370    (clobber (reg:CC FLAGS_REG))]
18371   "TARGET_USE_FANCY_MATH_387
18372    && flag_unsafe_math_optimizations
18373    && !(reload_completed || reload_in_progress)"
18374   "#"
18375   "&& 1"
18376   [(const_int 0)]
18377 {
18378   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18379
18380   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18381   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18382
18383   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18384                                         operands[2], operands[3]));
18385   DONE;
18386 }
18387   [(set_attr "type" "frndint")
18388    (set_attr "i387_cw" "floor")
18389    (set_attr "mode" "XF")])
18390
18391 (define_insn "frndintxf2_floor_i387"
18392   [(set (match_operand:XF 0 "register_operand" "=f")
18393         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18394          UNSPEC_FRNDINT_FLOOR))
18395    (use (match_operand:HI 2 "memory_operand" "m"))
18396    (use (match_operand:HI 3 "memory_operand" "m"))]
18397   "TARGET_USE_FANCY_MATH_387
18398    && flag_unsafe_math_optimizations"
18399   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18400   [(set_attr "type" "frndint")
18401    (set_attr "i387_cw" "floor")
18402    (set_attr "mode" "XF")])
18403
18404 (define_expand "floorxf2"
18405   [(use (match_operand:XF 0 "register_operand" ""))
18406    (use (match_operand:XF 1 "register_operand" ""))]
18407   "TARGET_USE_FANCY_MATH_387
18408    && flag_unsafe_math_optimizations"
18409 {
18410   if (optimize_insn_for_size_p ())
18411     FAIL;
18412   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18413   DONE;
18414 })
18415
18416 (define_expand "floor<mode>2"
18417   [(use (match_operand:MODEF 0 "register_operand" ""))
18418    (use (match_operand:MODEF 1 "register_operand" ""))]
18419   "(TARGET_USE_FANCY_MATH_387
18420     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18421         || TARGET_MIX_SSE_I387)
18422     && flag_unsafe_math_optimizations)
18423    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18424        && !flag_trapping_math)"
18425 {
18426   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18427       && !flag_trapping_math
18428       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18429     {
18430       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18431         FAIL;
18432       if (TARGET_ROUND)
18433         emit_insn (gen_sse4_1_round<mode>2
18434                    (operands[0], operands[1], GEN_INT (0x01)));
18435       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18436         ix86_expand_floorceil (operand0, operand1, true);
18437       else
18438         ix86_expand_floorceildf_32 (operand0, operand1, true);
18439     }
18440   else
18441     {
18442       rtx op0, op1;
18443
18444       if (optimize_insn_for_size_p ())
18445         FAIL;
18446
18447       op0 = gen_reg_rtx (XFmode);
18448       op1 = gen_reg_rtx (XFmode);
18449       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18450       emit_insn (gen_frndintxf2_floor (op0, op1));
18451
18452       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18453     }
18454   DONE;
18455 })
18456
18457 (define_insn_and_split "*fist<mode>2_floor_1"
18458   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18459         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18460          UNSPEC_FIST_FLOOR))
18461    (clobber (reg:CC FLAGS_REG))]
18462   "TARGET_USE_FANCY_MATH_387
18463    && flag_unsafe_math_optimizations
18464    && !(reload_completed || reload_in_progress)"
18465   "#"
18466   "&& 1"
18467   [(const_int 0)]
18468 {
18469   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18470
18471   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18472   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18473   if (memory_operand (operands[0], VOIDmode))
18474     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18475                                       operands[2], operands[3]));
18476   else
18477     {
18478       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18479       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18480                                                   operands[2], operands[3],
18481                                                   operands[4]));
18482     }
18483   DONE;
18484 }
18485   [(set_attr "type" "fistp")
18486    (set_attr "i387_cw" "floor")
18487    (set_attr "mode" "<MODE>")])
18488
18489 (define_insn "fistdi2_floor"
18490   [(set (match_operand:DI 0 "memory_operand" "=m")
18491         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18492          UNSPEC_FIST_FLOOR))
18493    (use (match_operand:HI 2 "memory_operand" "m"))
18494    (use (match_operand:HI 3 "memory_operand" "m"))
18495    (clobber (match_scratch:XF 4 "=&1f"))]
18496   "TARGET_USE_FANCY_MATH_387
18497    && flag_unsafe_math_optimizations"
18498   "* return output_fix_trunc (insn, operands, 0);"
18499   [(set_attr "type" "fistp")
18500    (set_attr "i387_cw" "floor")
18501    (set_attr "mode" "DI")])
18502
18503 (define_insn "fistdi2_floor_with_temp"
18504   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18505         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18506          UNSPEC_FIST_FLOOR))
18507    (use (match_operand:HI 2 "memory_operand" "m,m"))
18508    (use (match_operand:HI 3 "memory_operand" "m,m"))
18509    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18510    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18511   "TARGET_USE_FANCY_MATH_387
18512    && flag_unsafe_math_optimizations"
18513   "#"
18514   [(set_attr "type" "fistp")
18515    (set_attr "i387_cw" "floor")
18516    (set_attr "mode" "DI")])
18517
18518 (define_split
18519   [(set (match_operand:DI 0 "register_operand" "")
18520         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18521          UNSPEC_FIST_FLOOR))
18522    (use (match_operand:HI 2 "memory_operand" ""))
18523    (use (match_operand:HI 3 "memory_operand" ""))
18524    (clobber (match_operand:DI 4 "memory_operand" ""))
18525    (clobber (match_scratch 5 ""))]
18526   "reload_completed"
18527   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18528               (use (match_dup 2))
18529               (use (match_dup 3))
18530               (clobber (match_dup 5))])
18531    (set (match_dup 0) (match_dup 4))]
18532   "")
18533
18534 (define_split
18535   [(set (match_operand:DI 0 "memory_operand" "")
18536         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18537          UNSPEC_FIST_FLOOR))
18538    (use (match_operand:HI 2 "memory_operand" ""))
18539    (use (match_operand:HI 3 "memory_operand" ""))
18540    (clobber (match_operand:DI 4 "memory_operand" ""))
18541    (clobber (match_scratch 5 ""))]
18542   "reload_completed"
18543   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18544               (use (match_dup 2))
18545               (use (match_dup 3))
18546               (clobber (match_dup 5))])]
18547   "")
18548
18549 (define_insn "fist<mode>2_floor"
18550   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18551         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18552          UNSPEC_FIST_FLOOR))
18553    (use (match_operand:HI 2 "memory_operand" "m"))
18554    (use (match_operand:HI 3 "memory_operand" "m"))]
18555   "TARGET_USE_FANCY_MATH_387
18556    && flag_unsafe_math_optimizations"
18557   "* return output_fix_trunc (insn, operands, 0);"
18558   [(set_attr "type" "fistp")
18559    (set_attr "i387_cw" "floor")
18560    (set_attr "mode" "<MODE>")])
18561
18562 (define_insn "fist<mode>2_floor_with_temp"
18563   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18564         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18565          UNSPEC_FIST_FLOOR))
18566    (use (match_operand:HI 2 "memory_operand" "m,m"))
18567    (use (match_operand:HI 3 "memory_operand" "m,m"))
18568    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18569   "TARGET_USE_FANCY_MATH_387
18570    && flag_unsafe_math_optimizations"
18571   "#"
18572   [(set_attr "type" "fistp")
18573    (set_attr "i387_cw" "floor")
18574    (set_attr "mode" "<MODE>")])
18575
18576 (define_split
18577   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18578         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18579          UNSPEC_FIST_FLOOR))
18580    (use (match_operand:HI 2 "memory_operand" ""))
18581    (use (match_operand:HI 3 "memory_operand" ""))
18582    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18583   "reload_completed"
18584   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18585                                   UNSPEC_FIST_FLOOR))
18586               (use (match_dup 2))
18587               (use (match_dup 3))])
18588    (set (match_dup 0) (match_dup 4))]
18589   "")
18590
18591 (define_split
18592   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18593         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18594          UNSPEC_FIST_FLOOR))
18595    (use (match_operand:HI 2 "memory_operand" ""))
18596    (use (match_operand:HI 3 "memory_operand" ""))
18597    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18598   "reload_completed"
18599   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18600                                   UNSPEC_FIST_FLOOR))
18601               (use (match_dup 2))
18602               (use (match_dup 3))])]
18603   "")
18604
18605 (define_expand "lfloorxf<mode>2"
18606   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18607                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18608                     UNSPEC_FIST_FLOOR))
18609               (clobber (reg:CC FLAGS_REG))])]
18610   "TARGET_USE_FANCY_MATH_387
18611    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18612    && flag_unsafe_math_optimizations"
18613   "")
18614
18615 (define_expand "lfloor<mode>di2"
18616   [(match_operand:DI 0 "nonimmediate_operand" "")
18617    (match_operand:MODEF 1 "register_operand" "")]
18618   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18619    && !flag_trapping_math"
18620 {
18621   if (optimize_insn_for_size_p ())
18622     FAIL;
18623   ix86_expand_lfloorceil (operand0, operand1, true);
18624   DONE;
18625 })
18626
18627 (define_expand "lfloor<mode>si2"
18628   [(match_operand:SI 0 "nonimmediate_operand" "")
18629    (match_operand:MODEF 1 "register_operand" "")]
18630   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18631    && !flag_trapping_math"
18632 {
18633   if (optimize_insn_for_size_p () && TARGET_64BIT)
18634     FAIL;
18635   ix86_expand_lfloorceil (operand0, operand1, true);
18636   DONE;
18637 })
18638
18639 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18640 (define_insn_and_split "frndintxf2_ceil"
18641   [(set (match_operand:XF 0 "register_operand" "")
18642         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18643          UNSPEC_FRNDINT_CEIL))
18644    (clobber (reg:CC FLAGS_REG))]
18645   "TARGET_USE_FANCY_MATH_387
18646    && flag_unsafe_math_optimizations
18647    && !(reload_completed || reload_in_progress)"
18648   "#"
18649   "&& 1"
18650   [(const_int 0)]
18651 {
18652   ix86_optimize_mode_switching[I387_CEIL] = 1;
18653
18654   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18655   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18656
18657   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18658                                        operands[2], operands[3]));
18659   DONE;
18660 }
18661   [(set_attr "type" "frndint")
18662    (set_attr "i387_cw" "ceil")
18663    (set_attr "mode" "XF")])
18664
18665 (define_insn "frndintxf2_ceil_i387"
18666   [(set (match_operand:XF 0 "register_operand" "=f")
18667         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18668          UNSPEC_FRNDINT_CEIL))
18669    (use (match_operand:HI 2 "memory_operand" "m"))
18670    (use (match_operand:HI 3 "memory_operand" "m"))]
18671   "TARGET_USE_FANCY_MATH_387
18672    && flag_unsafe_math_optimizations"
18673   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18674   [(set_attr "type" "frndint")
18675    (set_attr "i387_cw" "ceil")
18676    (set_attr "mode" "XF")])
18677
18678 (define_expand "ceilxf2"
18679   [(use (match_operand:XF 0 "register_operand" ""))
18680    (use (match_operand:XF 1 "register_operand" ""))]
18681   "TARGET_USE_FANCY_MATH_387
18682    && flag_unsafe_math_optimizations"
18683 {
18684   if (optimize_insn_for_size_p ())
18685     FAIL;
18686   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18687   DONE;
18688 })
18689
18690 (define_expand "ceil<mode>2"
18691   [(use (match_operand:MODEF 0 "register_operand" ""))
18692    (use (match_operand:MODEF 1 "register_operand" ""))]
18693   "(TARGET_USE_FANCY_MATH_387
18694     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18695         || TARGET_MIX_SSE_I387)
18696     && flag_unsafe_math_optimizations)
18697    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18698        && !flag_trapping_math)"
18699 {
18700   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18701       && !flag_trapping_math
18702       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18703     {
18704       if (TARGET_ROUND)
18705         emit_insn (gen_sse4_1_round<mode>2
18706                    (operands[0], operands[1], GEN_INT (0x02)));
18707       else if (optimize_insn_for_size_p ())
18708         FAIL;
18709       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18710         ix86_expand_floorceil (operand0, operand1, false);
18711       else
18712         ix86_expand_floorceildf_32 (operand0, operand1, false);
18713     }
18714   else
18715     {
18716       rtx op0, op1;
18717
18718       if (optimize_insn_for_size_p ())
18719         FAIL;
18720
18721       op0 = gen_reg_rtx (XFmode);
18722       op1 = gen_reg_rtx (XFmode);
18723       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18724       emit_insn (gen_frndintxf2_ceil (op0, op1));
18725
18726       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18727     }
18728   DONE;
18729 })
18730
18731 (define_insn_and_split "*fist<mode>2_ceil_1"
18732   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18733         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18734          UNSPEC_FIST_CEIL))
18735    (clobber (reg:CC FLAGS_REG))]
18736   "TARGET_USE_FANCY_MATH_387
18737    && flag_unsafe_math_optimizations
18738    && !(reload_completed || reload_in_progress)"
18739   "#"
18740   "&& 1"
18741   [(const_int 0)]
18742 {
18743   ix86_optimize_mode_switching[I387_CEIL] = 1;
18744
18745   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18746   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18747   if (memory_operand (operands[0], VOIDmode))
18748     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18749                                      operands[2], operands[3]));
18750   else
18751     {
18752       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18753       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18754                                                  operands[2], operands[3],
18755                                                  operands[4]));
18756     }
18757   DONE;
18758 }
18759   [(set_attr "type" "fistp")
18760    (set_attr "i387_cw" "ceil")
18761    (set_attr "mode" "<MODE>")])
18762
18763 (define_insn "fistdi2_ceil"
18764   [(set (match_operand:DI 0 "memory_operand" "=m")
18765         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18766          UNSPEC_FIST_CEIL))
18767    (use (match_operand:HI 2 "memory_operand" "m"))
18768    (use (match_operand:HI 3 "memory_operand" "m"))
18769    (clobber (match_scratch:XF 4 "=&1f"))]
18770   "TARGET_USE_FANCY_MATH_387
18771    && flag_unsafe_math_optimizations"
18772   "* return output_fix_trunc (insn, operands, 0);"
18773   [(set_attr "type" "fistp")
18774    (set_attr "i387_cw" "ceil")
18775    (set_attr "mode" "DI")])
18776
18777 (define_insn "fistdi2_ceil_with_temp"
18778   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18779         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18780          UNSPEC_FIST_CEIL))
18781    (use (match_operand:HI 2 "memory_operand" "m,m"))
18782    (use (match_operand:HI 3 "memory_operand" "m,m"))
18783    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18784    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18785   "TARGET_USE_FANCY_MATH_387
18786    && flag_unsafe_math_optimizations"
18787   "#"
18788   [(set_attr "type" "fistp")
18789    (set_attr "i387_cw" "ceil")
18790    (set_attr "mode" "DI")])
18791
18792 (define_split
18793   [(set (match_operand:DI 0 "register_operand" "")
18794         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18795          UNSPEC_FIST_CEIL))
18796    (use (match_operand:HI 2 "memory_operand" ""))
18797    (use (match_operand:HI 3 "memory_operand" ""))
18798    (clobber (match_operand:DI 4 "memory_operand" ""))
18799    (clobber (match_scratch 5 ""))]
18800   "reload_completed"
18801   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18802               (use (match_dup 2))
18803               (use (match_dup 3))
18804               (clobber (match_dup 5))])
18805    (set (match_dup 0) (match_dup 4))]
18806   "")
18807
18808 (define_split
18809   [(set (match_operand:DI 0 "memory_operand" "")
18810         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18811          UNSPEC_FIST_CEIL))
18812    (use (match_operand:HI 2 "memory_operand" ""))
18813    (use (match_operand:HI 3 "memory_operand" ""))
18814    (clobber (match_operand:DI 4 "memory_operand" ""))
18815    (clobber (match_scratch 5 ""))]
18816   "reload_completed"
18817   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18818               (use (match_dup 2))
18819               (use (match_dup 3))
18820               (clobber (match_dup 5))])]
18821   "")
18822
18823 (define_insn "fist<mode>2_ceil"
18824   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18825         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18826          UNSPEC_FIST_CEIL))
18827    (use (match_operand:HI 2 "memory_operand" "m"))
18828    (use (match_operand:HI 3 "memory_operand" "m"))]
18829   "TARGET_USE_FANCY_MATH_387
18830    && flag_unsafe_math_optimizations"
18831   "* return output_fix_trunc (insn, operands, 0);"
18832   [(set_attr "type" "fistp")
18833    (set_attr "i387_cw" "ceil")
18834    (set_attr "mode" "<MODE>")])
18835
18836 (define_insn "fist<mode>2_ceil_with_temp"
18837   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18838         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18839          UNSPEC_FIST_CEIL))
18840    (use (match_operand:HI 2 "memory_operand" "m,m"))
18841    (use (match_operand:HI 3 "memory_operand" "m,m"))
18842    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18843   "TARGET_USE_FANCY_MATH_387
18844    && flag_unsafe_math_optimizations"
18845   "#"
18846   [(set_attr "type" "fistp")
18847    (set_attr "i387_cw" "ceil")
18848    (set_attr "mode" "<MODE>")])
18849
18850 (define_split
18851   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18852         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18853          UNSPEC_FIST_CEIL))
18854    (use (match_operand:HI 2 "memory_operand" ""))
18855    (use (match_operand:HI 3 "memory_operand" ""))
18856    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18857   "reload_completed"
18858   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18859                                   UNSPEC_FIST_CEIL))
18860               (use (match_dup 2))
18861               (use (match_dup 3))])
18862    (set (match_dup 0) (match_dup 4))]
18863   "")
18864
18865 (define_split
18866   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18867         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18868          UNSPEC_FIST_CEIL))
18869    (use (match_operand:HI 2 "memory_operand" ""))
18870    (use (match_operand:HI 3 "memory_operand" ""))
18871    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18872   "reload_completed"
18873   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18874                                   UNSPEC_FIST_CEIL))
18875               (use (match_dup 2))
18876               (use (match_dup 3))])]
18877   "")
18878
18879 (define_expand "lceilxf<mode>2"
18880   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18881                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18882                     UNSPEC_FIST_CEIL))
18883               (clobber (reg:CC FLAGS_REG))])]
18884   "TARGET_USE_FANCY_MATH_387
18885    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18886    && flag_unsafe_math_optimizations"
18887   "")
18888
18889 (define_expand "lceil<mode>di2"
18890   [(match_operand:DI 0 "nonimmediate_operand" "")
18891    (match_operand:MODEF 1 "register_operand" "")]
18892   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18893    && !flag_trapping_math"
18894 {
18895   ix86_expand_lfloorceil (operand0, operand1, false);
18896   DONE;
18897 })
18898
18899 (define_expand "lceil<mode>si2"
18900   [(match_operand:SI 0 "nonimmediate_operand" "")
18901    (match_operand:MODEF 1 "register_operand" "")]
18902   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18903    && !flag_trapping_math"
18904 {
18905   ix86_expand_lfloorceil (operand0, operand1, false);
18906   DONE;
18907 })
18908
18909 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18910 (define_insn_and_split "frndintxf2_trunc"
18911   [(set (match_operand:XF 0 "register_operand" "")
18912         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18913          UNSPEC_FRNDINT_TRUNC))
18914    (clobber (reg:CC FLAGS_REG))]
18915   "TARGET_USE_FANCY_MATH_387
18916    && flag_unsafe_math_optimizations
18917    && !(reload_completed || reload_in_progress)"
18918   "#"
18919   "&& 1"
18920   [(const_int 0)]
18921 {
18922   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18923
18924   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18925   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18926
18927   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18928                                         operands[2], operands[3]));
18929   DONE;
18930 }
18931   [(set_attr "type" "frndint")
18932    (set_attr "i387_cw" "trunc")
18933    (set_attr "mode" "XF")])
18934
18935 (define_insn "frndintxf2_trunc_i387"
18936   [(set (match_operand:XF 0 "register_operand" "=f")
18937         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18938          UNSPEC_FRNDINT_TRUNC))
18939    (use (match_operand:HI 2 "memory_operand" "m"))
18940    (use (match_operand:HI 3 "memory_operand" "m"))]
18941   "TARGET_USE_FANCY_MATH_387
18942    && flag_unsafe_math_optimizations"
18943   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18944   [(set_attr "type" "frndint")
18945    (set_attr "i387_cw" "trunc")
18946    (set_attr "mode" "XF")])
18947
18948 (define_expand "btruncxf2"
18949   [(use (match_operand:XF 0 "register_operand" ""))
18950    (use (match_operand:XF 1 "register_operand" ""))]
18951   "TARGET_USE_FANCY_MATH_387
18952    && flag_unsafe_math_optimizations"
18953 {
18954   if (optimize_insn_for_size_p ())
18955     FAIL;
18956   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18957   DONE;
18958 })
18959
18960 (define_expand "btrunc<mode>2"
18961   [(use (match_operand:MODEF 0 "register_operand" ""))
18962    (use (match_operand:MODEF 1 "register_operand" ""))]
18963   "(TARGET_USE_FANCY_MATH_387
18964     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18965         || TARGET_MIX_SSE_I387)
18966     && flag_unsafe_math_optimizations)
18967    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18968        && !flag_trapping_math)"
18969 {
18970   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18971       && !flag_trapping_math
18972       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18973     {
18974       if (TARGET_ROUND)
18975         emit_insn (gen_sse4_1_round<mode>2
18976                    (operands[0], operands[1], GEN_INT (0x03)));
18977       else if (optimize_insn_for_size_p ())
18978         FAIL;
18979       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18980         ix86_expand_trunc (operand0, operand1);
18981       else
18982         ix86_expand_truncdf_32 (operand0, operand1);
18983     }
18984   else
18985     {
18986       rtx op0, op1;
18987
18988       if (optimize_insn_for_size_p ())
18989         FAIL;
18990
18991       op0 = gen_reg_rtx (XFmode);
18992       op1 = gen_reg_rtx (XFmode);
18993       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18994       emit_insn (gen_frndintxf2_trunc (op0, op1));
18995
18996       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18997     }
18998   DONE;
18999 })
19000
19001 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19002 (define_insn_and_split "frndintxf2_mask_pm"
19003   [(set (match_operand:XF 0 "register_operand" "")
19004         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19005          UNSPEC_FRNDINT_MASK_PM))
19006    (clobber (reg:CC FLAGS_REG))]
19007   "TARGET_USE_FANCY_MATH_387
19008    && flag_unsafe_math_optimizations
19009    && !(reload_completed || reload_in_progress)"
19010   "#"
19011   "&& 1"
19012   [(const_int 0)]
19013 {
19014   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
19015
19016   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19017   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
19018
19019   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
19020                                           operands[2], operands[3]));
19021   DONE;
19022 }
19023   [(set_attr "type" "frndint")
19024    (set_attr "i387_cw" "mask_pm")
19025    (set_attr "mode" "XF")])
19026
19027 (define_insn "frndintxf2_mask_pm_i387"
19028   [(set (match_operand:XF 0 "register_operand" "=f")
19029         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19030          UNSPEC_FRNDINT_MASK_PM))
19031    (use (match_operand:HI 2 "memory_operand" "m"))
19032    (use (match_operand:HI 3 "memory_operand" "m"))]
19033   "TARGET_USE_FANCY_MATH_387
19034    && flag_unsafe_math_optimizations"
19035   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
19036   [(set_attr "type" "frndint")
19037    (set_attr "i387_cw" "mask_pm")
19038    (set_attr "mode" "XF")])
19039
19040 (define_expand "nearbyintxf2"
19041   [(use (match_operand:XF 0 "register_operand" ""))
19042    (use (match_operand:XF 1 "register_operand" ""))]
19043   "TARGET_USE_FANCY_MATH_387
19044    && flag_unsafe_math_optimizations"
19045 {
19046   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
19047
19048   DONE;
19049 })
19050
19051 (define_expand "nearbyint<mode>2"
19052   [(use (match_operand:MODEF 0 "register_operand" ""))
19053    (use (match_operand:MODEF 1 "register_operand" ""))]
19054   "TARGET_USE_FANCY_MATH_387
19055    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19056        || TARGET_MIX_SSE_I387)
19057    && flag_unsafe_math_optimizations"
19058 {
19059   rtx op0 = gen_reg_rtx (XFmode);
19060   rtx op1 = gen_reg_rtx (XFmode);
19061
19062   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19063   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
19064
19065   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19066   DONE;
19067 })
19068
19069 (define_insn "fxam<mode>2_i387"
19070   [(set (match_operand:HI 0 "register_operand" "=a")
19071         (unspec:HI
19072           [(match_operand:X87MODEF 1 "register_operand" "f")]
19073           UNSPEC_FXAM))]
19074   "TARGET_USE_FANCY_MATH_387"
19075   "fxam\n\tfnstsw\t%0"
19076   [(set_attr "type" "multi")
19077    (set_attr "unit" "i387")
19078    (set_attr "mode" "<MODE>")])
19079
19080 (define_insn_and_split "fxam<mode>2_i387_with_temp"
19081   [(set (match_operand:HI 0 "register_operand" "")
19082         (unspec:HI
19083           [(match_operand:MODEF 1 "memory_operand" "")]
19084           UNSPEC_FXAM_MEM))]
19085   "TARGET_USE_FANCY_MATH_387
19086    && !(reload_completed || reload_in_progress)"
19087   "#"
19088   "&& 1"
19089   [(set (match_dup 2)(match_dup 1))
19090    (set (match_dup 0)
19091         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
19092 {
19093   operands[2] = gen_reg_rtx (<MODE>mode);
19094
19095   MEM_VOLATILE_P (operands[1]) = 1;
19096 }
19097   [(set_attr "type" "multi")
19098    (set_attr "unit" "i387")
19099    (set_attr "mode" "<MODE>")])
19100
19101 (define_expand "isinfxf2"
19102   [(use (match_operand:SI 0 "register_operand" ""))
19103    (use (match_operand:XF 1 "register_operand" ""))]
19104   "TARGET_USE_FANCY_MATH_387
19105    && TARGET_C99_FUNCTIONS"
19106 {
19107   rtx mask = GEN_INT (0x45);
19108   rtx val = GEN_INT (0x05);
19109
19110   rtx cond;
19111
19112   rtx scratch = gen_reg_rtx (HImode);
19113   rtx res = gen_reg_rtx (QImode);
19114
19115   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
19116
19117   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19118   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19119   cond = gen_rtx_fmt_ee (EQ, QImode,
19120                          gen_rtx_REG (CCmode, FLAGS_REG),
19121                          const0_rtx);
19122   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19123   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19124   DONE;
19125 })
19126
19127 (define_expand "isinf<mode>2"
19128   [(use (match_operand:SI 0 "register_operand" ""))
19129    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
19130   "TARGET_USE_FANCY_MATH_387
19131    && TARGET_C99_FUNCTIONS
19132    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19133 {
19134   rtx mask = GEN_INT (0x45);
19135   rtx val = GEN_INT (0x05);
19136
19137   rtx cond;
19138
19139   rtx scratch = gen_reg_rtx (HImode);
19140   rtx res = gen_reg_rtx (QImode);
19141
19142   /* Remove excess precision by forcing value through memory. */
19143   if (memory_operand (operands[1], VOIDmode))
19144     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19145   else
19146     {
19147       enum ix86_stack_slot slot = (virtuals_instantiated
19148                                    ? SLOT_TEMP
19149                                    : SLOT_VIRTUAL);
19150       rtx temp = assign_386_stack_local (<MODE>mode, slot);
19151
19152       emit_move_insn (temp, operands[1]);
19153       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19154     }
19155
19156   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19157   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19158   cond = gen_rtx_fmt_ee (EQ, QImode,
19159                          gen_rtx_REG (CCmode, FLAGS_REG),
19160                          const0_rtx);
19161   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19162   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19163   DONE;
19164 })
19165
19166 (define_expand "signbit<mode>2"
19167   [(use (match_operand:SI 0 "register_operand" ""))
19168    (use (match_operand:X87MODEF 1 "register_operand" ""))]
19169   "TARGET_USE_FANCY_MATH_387
19170    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19171 {
19172   rtx mask = GEN_INT (0x0200);
19173
19174   rtx scratch = gen_reg_rtx (HImode);
19175
19176   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19177   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19178   DONE;
19179 })
19180 \f
19181 ;; Block operation instructions
19182
19183 (define_insn "cld"
19184   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19185   ""
19186   "cld"
19187   [(set_attr "length" "1")
19188    (set_attr "length_immediate" "0")
19189    (set_attr "modrm" "0")])
19190
19191 (define_expand "movmemsi"
19192   [(use (match_operand:BLK 0 "memory_operand" ""))
19193    (use (match_operand:BLK 1 "memory_operand" ""))
19194    (use (match_operand:SI 2 "nonmemory_operand" ""))
19195    (use (match_operand:SI 3 "const_int_operand" ""))
19196    (use (match_operand:SI 4 "const_int_operand" ""))
19197    (use (match_operand:SI 5 "const_int_operand" ""))]
19198   ""
19199 {
19200  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19201                          operands[4], operands[5]))
19202    DONE;
19203  else
19204    FAIL;
19205 })
19206
19207 (define_expand "movmemdi"
19208   [(use (match_operand:BLK 0 "memory_operand" ""))
19209    (use (match_operand:BLK 1 "memory_operand" ""))
19210    (use (match_operand:DI 2 "nonmemory_operand" ""))
19211    (use (match_operand:DI 3 "const_int_operand" ""))
19212    (use (match_operand:SI 4 "const_int_operand" ""))
19213    (use (match_operand:SI 5 "const_int_operand" ""))]
19214   "TARGET_64BIT"
19215 {
19216  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19217                          operands[4], operands[5]))
19218    DONE;
19219  else
19220    FAIL;
19221 })
19222
19223 ;; Most CPUs don't like single string operations
19224 ;; Handle this case here to simplify previous expander.
19225
19226 (define_expand "strmov"
19227   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19228    (set (match_operand 1 "memory_operand" "") (match_dup 4))
19229    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19230               (clobber (reg:CC FLAGS_REG))])
19231    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19232               (clobber (reg:CC FLAGS_REG))])]
19233   ""
19234 {
19235   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19236
19237   /* If .md ever supports :P for Pmode, these can be directly
19238      in the pattern above.  */
19239   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19240   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19241
19242   /* Can't use this if the user has appropriated esi or edi.  */
19243   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19244       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19245     {
19246       emit_insn (gen_strmov_singleop (operands[0], operands[1],
19247                                       operands[2], operands[3],
19248                                       operands[5], operands[6]));
19249       DONE;
19250     }
19251
19252   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19253 })
19254
19255 (define_expand "strmov_singleop"
19256   [(parallel [(set (match_operand 1 "memory_operand" "")
19257                    (match_operand 3 "memory_operand" ""))
19258               (set (match_operand 0 "register_operand" "")
19259                    (match_operand 4 "" ""))
19260               (set (match_operand 2 "register_operand" "")
19261                    (match_operand 5 "" ""))])]
19262   ""
19263   "ix86_current_function_needs_cld = 1;")
19264
19265 (define_insn "*strmovdi_rex_1"
19266   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19267         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19268    (set (match_operand:DI 0 "register_operand" "=D")
19269         (plus:DI (match_dup 2)
19270                  (const_int 8)))
19271    (set (match_operand:DI 1 "register_operand" "=S")
19272         (plus:DI (match_dup 3)
19273                  (const_int 8)))]
19274   "TARGET_64BIT"
19275   "movsq"
19276   [(set_attr "type" "str")
19277    (set_attr "mode" "DI")
19278    (set_attr "memory" "both")])
19279
19280 (define_insn "*strmovsi_1"
19281   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19282         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19283    (set (match_operand:SI 0 "register_operand" "=D")
19284         (plus:SI (match_dup 2)
19285                  (const_int 4)))
19286    (set (match_operand:SI 1 "register_operand" "=S")
19287         (plus:SI (match_dup 3)
19288                  (const_int 4)))]
19289   "!TARGET_64BIT"
19290   "movs{l|d}"
19291   [(set_attr "type" "str")
19292    (set_attr "mode" "SI")
19293    (set_attr "memory" "both")])
19294
19295 (define_insn "*strmovsi_rex_1"
19296   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19297         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19298    (set (match_operand:DI 0 "register_operand" "=D")
19299         (plus:DI (match_dup 2)
19300                  (const_int 4)))
19301    (set (match_operand:DI 1 "register_operand" "=S")
19302         (plus:DI (match_dup 3)
19303                  (const_int 4)))]
19304   "TARGET_64BIT"
19305   "movs{l|d}"
19306   [(set_attr "type" "str")
19307    (set_attr "mode" "SI")
19308    (set_attr "memory" "both")])
19309
19310 (define_insn "*strmovhi_1"
19311   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19312         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19313    (set (match_operand:SI 0 "register_operand" "=D")
19314         (plus:SI (match_dup 2)
19315                  (const_int 2)))
19316    (set (match_operand:SI 1 "register_operand" "=S")
19317         (plus:SI (match_dup 3)
19318                  (const_int 2)))]
19319   "!TARGET_64BIT"
19320   "movsw"
19321   [(set_attr "type" "str")
19322    (set_attr "memory" "both")
19323    (set_attr "mode" "HI")])
19324
19325 (define_insn "*strmovhi_rex_1"
19326   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19327         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19328    (set (match_operand:DI 0 "register_operand" "=D")
19329         (plus:DI (match_dup 2)
19330                  (const_int 2)))
19331    (set (match_operand:DI 1 "register_operand" "=S")
19332         (plus:DI (match_dup 3)
19333                  (const_int 2)))]
19334   "TARGET_64BIT"
19335   "movsw"
19336   [(set_attr "type" "str")
19337    (set_attr "memory" "both")
19338    (set_attr "mode" "HI")])
19339
19340 (define_insn "*strmovqi_1"
19341   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19342         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19343    (set (match_operand:SI 0 "register_operand" "=D")
19344         (plus:SI (match_dup 2)
19345                  (const_int 1)))
19346    (set (match_operand:SI 1 "register_operand" "=S")
19347         (plus:SI (match_dup 3)
19348                  (const_int 1)))]
19349   "!TARGET_64BIT"
19350   "movsb"
19351   [(set_attr "type" "str")
19352    (set_attr "memory" "both")
19353    (set_attr "mode" "QI")])
19354
19355 (define_insn "*strmovqi_rex_1"
19356   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19357         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19358    (set (match_operand:DI 0 "register_operand" "=D")
19359         (plus:DI (match_dup 2)
19360                  (const_int 1)))
19361    (set (match_operand:DI 1 "register_operand" "=S")
19362         (plus:DI (match_dup 3)
19363                  (const_int 1)))]
19364   "TARGET_64BIT"
19365   "movsb"
19366   [(set_attr "type" "str")
19367    (set_attr "memory" "both")
19368    (set_attr "mode" "QI")])
19369
19370 (define_expand "rep_mov"
19371   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19372               (set (match_operand 0 "register_operand" "")
19373                    (match_operand 5 "" ""))
19374               (set (match_operand 2 "register_operand" "")
19375                    (match_operand 6 "" ""))
19376               (set (match_operand 1 "memory_operand" "")
19377                    (match_operand 3 "memory_operand" ""))
19378               (use (match_dup 4))])]
19379   ""
19380   "ix86_current_function_needs_cld = 1;")
19381
19382 (define_insn "*rep_movdi_rex64"
19383   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19384    (set (match_operand:DI 0 "register_operand" "=D")
19385         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19386                             (const_int 3))
19387                  (match_operand:DI 3 "register_operand" "0")))
19388    (set (match_operand:DI 1 "register_operand" "=S")
19389         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19390                  (match_operand:DI 4 "register_operand" "1")))
19391    (set (mem:BLK (match_dup 3))
19392         (mem:BLK (match_dup 4)))
19393    (use (match_dup 5))]
19394   "TARGET_64BIT"
19395   "rep movsq"
19396   [(set_attr "type" "str")
19397    (set_attr "prefix_rep" "1")
19398    (set_attr "memory" "both")
19399    (set_attr "mode" "DI")])
19400
19401 (define_insn "*rep_movsi"
19402   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19403    (set (match_operand:SI 0 "register_operand" "=D")
19404         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19405                             (const_int 2))
19406                  (match_operand:SI 3 "register_operand" "0")))
19407    (set (match_operand:SI 1 "register_operand" "=S")
19408         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19409                  (match_operand:SI 4 "register_operand" "1")))
19410    (set (mem:BLK (match_dup 3))
19411         (mem:BLK (match_dup 4)))
19412    (use (match_dup 5))]
19413   "!TARGET_64BIT"
19414   "rep movs{l|d}"
19415   [(set_attr "type" "str")
19416    (set_attr "prefix_rep" "1")
19417    (set_attr "memory" "both")
19418    (set_attr "mode" "SI")])
19419
19420 (define_insn "*rep_movsi_rex64"
19421   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19422    (set (match_operand:DI 0 "register_operand" "=D")
19423         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19424                             (const_int 2))
19425                  (match_operand:DI 3 "register_operand" "0")))
19426    (set (match_operand:DI 1 "register_operand" "=S")
19427         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19428                  (match_operand:DI 4 "register_operand" "1")))
19429    (set (mem:BLK (match_dup 3))
19430         (mem:BLK (match_dup 4)))
19431    (use (match_dup 5))]
19432   "TARGET_64BIT"
19433   "rep movs{l|d}"
19434   [(set_attr "type" "str")
19435    (set_attr "prefix_rep" "1")
19436    (set_attr "memory" "both")
19437    (set_attr "mode" "SI")])
19438
19439 (define_insn "*rep_movqi"
19440   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19441    (set (match_operand:SI 0 "register_operand" "=D")
19442         (plus:SI (match_operand:SI 3 "register_operand" "0")
19443                  (match_operand:SI 5 "register_operand" "2")))
19444    (set (match_operand:SI 1 "register_operand" "=S")
19445         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19446    (set (mem:BLK (match_dup 3))
19447         (mem:BLK (match_dup 4)))
19448    (use (match_dup 5))]
19449   "!TARGET_64BIT"
19450   "rep movsb"
19451   [(set_attr "type" "str")
19452    (set_attr "prefix_rep" "1")
19453    (set_attr "memory" "both")
19454    (set_attr "mode" "SI")])
19455
19456 (define_insn "*rep_movqi_rex64"
19457   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19458    (set (match_operand:DI 0 "register_operand" "=D")
19459         (plus:DI (match_operand:DI 3 "register_operand" "0")
19460                  (match_operand:DI 5 "register_operand" "2")))
19461    (set (match_operand:DI 1 "register_operand" "=S")
19462         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19463    (set (mem:BLK (match_dup 3))
19464         (mem:BLK (match_dup 4)))
19465    (use (match_dup 5))]
19466   "TARGET_64BIT"
19467   "rep movsb"
19468   [(set_attr "type" "str")
19469    (set_attr "prefix_rep" "1")
19470    (set_attr "memory" "both")
19471    (set_attr "mode" "SI")])
19472
19473 (define_expand "setmemsi"
19474    [(use (match_operand:BLK 0 "memory_operand" ""))
19475     (use (match_operand:SI 1 "nonmemory_operand" ""))
19476     (use (match_operand 2 "const_int_operand" ""))
19477     (use (match_operand 3 "const_int_operand" ""))
19478     (use (match_operand:SI 4 "const_int_operand" ""))
19479     (use (match_operand:SI 5 "const_int_operand" ""))]
19480   ""
19481 {
19482  if (ix86_expand_setmem (operands[0], operands[1],
19483                          operands[2], operands[3],
19484                          operands[4], operands[5]))
19485    DONE;
19486  else
19487    FAIL;
19488 })
19489
19490 (define_expand "setmemdi"
19491    [(use (match_operand:BLK 0 "memory_operand" ""))
19492     (use (match_operand:DI 1 "nonmemory_operand" ""))
19493     (use (match_operand 2 "const_int_operand" ""))
19494     (use (match_operand 3 "const_int_operand" ""))
19495     (use (match_operand 4 "const_int_operand" ""))
19496     (use (match_operand 5 "const_int_operand" ""))]
19497   "TARGET_64BIT"
19498 {
19499  if (ix86_expand_setmem (operands[0], operands[1],
19500                          operands[2], operands[3],
19501                          operands[4], operands[5]))
19502    DONE;
19503  else
19504    FAIL;
19505 })
19506
19507 ;; Most CPUs don't like single string operations
19508 ;; Handle this case here to simplify previous expander.
19509
19510 (define_expand "strset"
19511   [(set (match_operand 1 "memory_operand" "")
19512         (match_operand 2 "register_operand" ""))
19513    (parallel [(set (match_operand 0 "register_operand" "")
19514                    (match_dup 3))
19515               (clobber (reg:CC FLAGS_REG))])]
19516   ""
19517 {
19518   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19519     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19520
19521   /* If .md ever supports :P for Pmode, this can be directly
19522      in the pattern above.  */
19523   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19524                               GEN_INT (GET_MODE_SIZE (GET_MODE
19525                                                       (operands[2]))));
19526   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19527     {
19528       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19529                                       operands[3]));
19530       DONE;
19531     }
19532 })
19533
19534 (define_expand "strset_singleop"
19535   [(parallel [(set (match_operand 1 "memory_operand" "")
19536                    (match_operand 2 "register_operand" ""))
19537               (set (match_operand 0 "register_operand" "")
19538                    (match_operand 3 "" ""))])]
19539   ""
19540   "ix86_current_function_needs_cld = 1;")
19541
19542 (define_insn "*strsetdi_rex_1"
19543   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19544         (match_operand:DI 2 "register_operand" "a"))
19545    (set (match_operand:DI 0 "register_operand" "=D")
19546         (plus:DI (match_dup 1)
19547                  (const_int 8)))]
19548   "TARGET_64BIT"
19549   "stosq"
19550   [(set_attr "type" "str")
19551    (set_attr "memory" "store")
19552    (set_attr "mode" "DI")])
19553
19554 (define_insn "*strsetsi_1"
19555   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19556         (match_operand:SI 2 "register_operand" "a"))
19557    (set (match_operand:SI 0 "register_operand" "=D")
19558         (plus:SI (match_dup 1)
19559                  (const_int 4)))]
19560   "!TARGET_64BIT"
19561   "stos{l|d}"
19562   [(set_attr "type" "str")
19563    (set_attr "memory" "store")
19564    (set_attr "mode" "SI")])
19565
19566 (define_insn "*strsetsi_rex_1"
19567   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19568         (match_operand:SI 2 "register_operand" "a"))
19569    (set (match_operand:DI 0 "register_operand" "=D")
19570         (plus:DI (match_dup 1)
19571                  (const_int 4)))]
19572   "TARGET_64BIT"
19573   "stos{l|d}"
19574   [(set_attr "type" "str")
19575    (set_attr "memory" "store")
19576    (set_attr "mode" "SI")])
19577
19578 (define_insn "*strsethi_1"
19579   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19580         (match_operand:HI 2 "register_operand" "a"))
19581    (set (match_operand:SI 0 "register_operand" "=D")
19582         (plus:SI (match_dup 1)
19583                  (const_int 2)))]
19584   "!TARGET_64BIT"
19585   "stosw"
19586   [(set_attr "type" "str")
19587    (set_attr "memory" "store")
19588    (set_attr "mode" "HI")])
19589
19590 (define_insn "*strsethi_rex_1"
19591   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19592         (match_operand:HI 2 "register_operand" "a"))
19593    (set (match_operand:DI 0 "register_operand" "=D")
19594         (plus:DI (match_dup 1)
19595                  (const_int 2)))]
19596   "TARGET_64BIT"
19597   "stosw"
19598   [(set_attr "type" "str")
19599    (set_attr "memory" "store")
19600    (set_attr "mode" "HI")])
19601
19602 (define_insn "*strsetqi_1"
19603   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19604         (match_operand:QI 2 "register_operand" "a"))
19605    (set (match_operand:SI 0 "register_operand" "=D")
19606         (plus:SI (match_dup 1)
19607                  (const_int 1)))]
19608   "!TARGET_64BIT"
19609   "stosb"
19610   [(set_attr "type" "str")
19611    (set_attr "memory" "store")
19612    (set_attr "mode" "QI")])
19613
19614 (define_insn "*strsetqi_rex_1"
19615   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19616         (match_operand:QI 2 "register_operand" "a"))
19617    (set (match_operand:DI 0 "register_operand" "=D")
19618         (plus:DI (match_dup 1)
19619                  (const_int 1)))]
19620   "TARGET_64BIT"
19621   "stosb"
19622   [(set_attr "type" "str")
19623    (set_attr "memory" "store")
19624    (set_attr "mode" "QI")])
19625
19626 (define_expand "rep_stos"
19627   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19628               (set (match_operand 0 "register_operand" "")
19629                    (match_operand 4 "" ""))
19630               (set (match_operand 2 "memory_operand" "") (const_int 0))
19631               (use (match_operand 3 "register_operand" ""))
19632               (use (match_dup 1))])]
19633   ""
19634   "ix86_current_function_needs_cld = 1;")
19635
19636 (define_insn "*rep_stosdi_rex64"
19637   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19638    (set (match_operand:DI 0 "register_operand" "=D")
19639         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19640                             (const_int 3))
19641                  (match_operand:DI 3 "register_operand" "0")))
19642    (set (mem:BLK (match_dup 3))
19643         (const_int 0))
19644    (use (match_operand:DI 2 "register_operand" "a"))
19645    (use (match_dup 4))]
19646   "TARGET_64BIT"
19647   "rep stosq"
19648   [(set_attr "type" "str")
19649    (set_attr "prefix_rep" "1")
19650    (set_attr "memory" "store")
19651    (set_attr "mode" "DI")])
19652
19653 (define_insn "*rep_stossi"
19654   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19655    (set (match_operand:SI 0 "register_operand" "=D")
19656         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19657                             (const_int 2))
19658                  (match_operand:SI 3 "register_operand" "0")))
19659    (set (mem:BLK (match_dup 3))
19660         (const_int 0))
19661    (use (match_operand:SI 2 "register_operand" "a"))
19662    (use (match_dup 4))]
19663   "!TARGET_64BIT"
19664   "rep stos{l|d}"
19665   [(set_attr "type" "str")
19666    (set_attr "prefix_rep" "1")
19667    (set_attr "memory" "store")
19668    (set_attr "mode" "SI")])
19669
19670 (define_insn "*rep_stossi_rex64"
19671   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19672    (set (match_operand:DI 0 "register_operand" "=D")
19673         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19674                             (const_int 2))
19675                  (match_operand:DI 3 "register_operand" "0")))
19676    (set (mem:BLK (match_dup 3))
19677         (const_int 0))
19678    (use (match_operand:SI 2 "register_operand" "a"))
19679    (use (match_dup 4))]
19680   "TARGET_64BIT"
19681   "rep stos{l|d}"
19682   [(set_attr "type" "str")
19683    (set_attr "prefix_rep" "1")
19684    (set_attr "memory" "store")
19685    (set_attr "mode" "SI")])
19686
19687 (define_insn "*rep_stosqi"
19688   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19689    (set (match_operand:SI 0 "register_operand" "=D")
19690         (plus:SI (match_operand:SI 3 "register_operand" "0")
19691                  (match_operand:SI 4 "register_operand" "1")))
19692    (set (mem:BLK (match_dup 3))
19693         (const_int 0))
19694    (use (match_operand:QI 2 "register_operand" "a"))
19695    (use (match_dup 4))]
19696   "!TARGET_64BIT"
19697   "rep stosb"
19698   [(set_attr "type" "str")
19699    (set_attr "prefix_rep" "1")
19700    (set_attr "memory" "store")
19701    (set_attr "mode" "QI")])
19702
19703 (define_insn "*rep_stosqi_rex64"
19704   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19705    (set (match_operand:DI 0 "register_operand" "=D")
19706         (plus:DI (match_operand:DI 3 "register_operand" "0")
19707                  (match_operand:DI 4 "register_operand" "1")))
19708    (set (mem:BLK (match_dup 3))
19709         (const_int 0))
19710    (use (match_operand:QI 2 "register_operand" "a"))
19711    (use (match_dup 4))]
19712   "TARGET_64BIT"
19713   "rep stosb"
19714   [(set_attr "type" "str")
19715    (set_attr "prefix_rep" "1")
19716    (set_attr "memory" "store")
19717    (set_attr "mode" "QI")])
19718
19719 (define_expand "cmpstrnsi"
19720   [(set (match_operand:SI 0 "register_operand" "")
19721         (compare:SI (match_operand:BLK 1 "general_operand" "")
19722                     (match_operand:BLK 2 "general_operand" "")))
19723    (use (match_operand 3 "general_operand" ""))
19724    (use (match_operand 4 "immediate_operand" ""))]
19725   ""
19726 {
19727   rtx addr1, addr2, out, outlow, count, countreg, align;
19728
19729   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19730     FAIL;
19731
19732   /* Can't use this if the user has appropriated esi or edi.  */
19733   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19734     FAIL;
19735
19736   out = operands[0];
19737   if (!REG_P (out))
19738     out = gen_reg_rtx (SImode);
19739
19740   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19741   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19742   if (addr1 != XEXP (operands[1], 0))
19743     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19744   if (addr2 != XEXP (operands[2], 0))
19745     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19746
19747   count = operands[3];
19748   countreg = ix86_zero_extend_to_Pmode (count);
19749
19750   /* %%% Iff we are testing strict equality, we can use known alignment
19751      to good advantage.  This may be possible with combine, particularly
19752      once cc0 is dead.  */
19753   align = operands[4];
19754
19755   if (CONST_INT_P (count))
19756     {
19757       if (INTVAL (count) == 0)
19758         {
19759           emit_move_insn (operands[0], const0_rtx);
19760           DONE;
19761         }
19762       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19763                                      operands[1], operands[2]));
19764     }
19765   else
19766     {
19767       if (TARGET_64BIT)
19768         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19769       else
19770         emit_insn (gen_cmpsi_1 (countreg, countreg));
19771       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19772                                   operands[1], operands[2]));
19773     }
19774
19775   outlow = gen_lowpart (QImode, out);
19776   emit_insn (gen_cmpintqi (outlow));
19777   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19778
19779   if (operands[0] != out)
19780     emit_move_insn (operands[0], out);
19781
19782   DONE;
19783 })
19784
19785 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19786
19787 (define_expand "cmpintqi"
19788   [(set (match_dup 1)
19789         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19790    (set (match_dup 2)
19791         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19792    (parallel [(set (match_operand:QI 0 "register_operand" "")
19793                    (minus:QI (match_dup 1)
19794                              (match_dup 2)))
19795               (clobber (reg:CC FLAGS_REG))])]
19796   ""
19797   "operands[1] = gen_reg_rtx (QImode);
19798    operands[2] = gen_reg_rtx (QImode);")
19799
19800 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19801 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19802
19803 (define_expand "cmpstrnqi_nz_1"
19804   [(parallel [(set (reg:CC FLAGS_REG)
19805                    (compare:CC (match_operand 4 "memory_operand" "")
19806                                (match_operand 5 "memory_operand" "")))
19807               (use (match_operand 2 "register_operand" ""))
19808               (use (match_operand:SI 3 "immediate_operand" ""))
19809               (clobber (match_operand 0 "register_operand" ""))
19810               (clobber (match_operand 1 "register_operand" ""))
19811               (clobber (match_dup 2))])]
19812   ""
19813   "ix86_current_function_needs_cld = 1;")
19814
19815 (define_insn "*cmpstrnqi_nz_1"
19816   [(set (reg:CC FLAGS_REG)
19817         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19818                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19819    (use (match_operand:SI 6 "register_operand" "2"))
19820    (use (match_operand:SI 3 "immediate_operand" "i"))
19821    (clobber (match_operand:SI 0 "register_operand" "=S"))
19822    (clobber (match_operand:SI 1 "register_operand" "=D"))
19823    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19824   "!TARGET_64BIT"
19825   "repz cmpsb"
19826   [(set_attr "type" "str")
19827    (set_attr "mode" "QI")
19828    (set_attr "prefix_rep" "1")])
19829
19830 (define_insn "*cmpstrnqi_nz_rex_1"
19831   [(set (reg:CC FLAGS_REG)
19832         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19833                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19834    (use (match_operand:DI 6 "register_operand" "2"))
19835    (use (match_operand:SI 3 "immediate_operand" "i"))
19836    (clobber (match_operand:DI 0 "register_operand" "=S"))
19837    (clobber (match_operand:DI 1 "register_operand" "=D"))
19838    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19839   "TARGET_64BIT"
19840   "repz cmpsb"
19841   [(set_attr "type" "str")
19842    (set_attr "mode" "QI")
19843    (set_attr "prefix_rep" "1")])
19844
19845 ;; The same, but the count is not known to not be zero.
19846
19847 (define_expand "cmpstrnqi_1"
19848   [(parallel [(set (reg:CC FLAGS_REG)
19849                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19850                                      (const_int 0))
19851                   (compare:CC (match_operand 4 "memory_operand" "")
19852                               (match_operand 5 "memory_operand" ""))
19853                   (const_int 0)))
19854               (use (match_operand:SI 3 "immediate_operand" ""))
19855               (use (reg:CC FLAGS_REG))
19856               (clobber (match_operand 0 "register_operand" ""))
19857               (clobber (match_operand 1 "register_operand" ""))
19858               (clobber (match_dup 2))])]
19859   ""
19860   "ix86_current_function_needs_cld = 1;")
19861
19862 (define_insn "*cmpstrnqi_1"
19863   [(set (reg:CC FLAGS_REG)
19864         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19865                              (const_int 0))
19866           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19867                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19868           (const_int 0)))
19869    (use (match_operand:SI 3 "immediate_operand" "i"))
19870    (use (reg:CC FLAGS_REG))
19871    (clobber (match_operand:SI 0 "register_operand" "=S"))
19872    (clobber (match_operand:SI 1 "register_operand" "=D"))
19873    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19874   "!TARGET_64BIT"
19875   "repz cmpsb"
19876   [(set_attr "type" "str")
19877    (set_attr "mode" "QI")
19878    (set_attr "prefix_rep" "1")])
19879
19880 (define_insn "*cmpstrnqi_rex_1"
19881   [(set (reg:CC FLAGS_REG)
19882         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19883                              (const_int 0))
19884           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19885                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19886           (const_int 0)))
19887    (use (match_operand:SI 3 "immediate_operand" "i"))
19888    (use (reg:CC FLAGS_REG))
19889    (clobber (match_operand:DI 0 "register_operand" "=S"))
19890    (clobber (match_operand:DI 1 "register_operand" "=D"))
19891    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19892   "TARGET_64BIT"
19893   "repz cmpsb"
19894   [(set_attr "type" "str")
19895    (set_attr "mode" "QI")
19896    (set_attr "prefix_rep" "1")])
19897
19898 (define_expand "strlensi"
19899   [(set (match_operand:SI 0 "register_operand" "")
19900         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19901                     (match_operand:QI 2 "immediate_operand" "")
19902                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19903   ""
19904 {
19905  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19906    DONE;
19907  else
19908    FAIL;
19909 })
19910
19911 (define_expand "strlendi"
19912   [(set (match_operand:DI 0 "register_operand" "")
19913         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19914                     (match_operand:QI 2 "immediate_operand" "")
19915                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19916   ""
19917 {
19918  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19919    DONE;
19920  else
19921    FAIL;
19922 })
19923
19924 (define_expand "strlenqi_1"
19925   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19926               (clobber (match_operand 1 "register_operand" ""))
19927               (clobber (reg:CC FLAGS_REG))])]
19928   ""
19929   "ix86_current_function_needs_cld = 1;")
19930
19931 (define_insn "*strlenqi_1"
19932   [(set (match_operand:SI 0 "register_operand" "=&c")
19933         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19934                     (match_operand:QI 2 "register_operand" "a")
19935                     (match_operand:SI 3 "immediate_operand" "i")
19936                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19937    (clobber (match_operand:SI 1 "register_operand" "=D"))
19938    (clobber (reg:CC FLAGS_REG))]
19939   "!TARGET_64BIT"
19940   "repnz scasb"
19941   [(set_attr "type" "str")
19942    (set_attr "mode" "QI")
19943    (set_attr "prefix_rep" "1")])
19944
19945 (define_insn "*strlenqi_rex_1"
19946   [(set (match_operand:DI 0 "register_operand" "=&c")
19947         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19948                     (match_operand:QI 2 "register_operand" "a")
19949                     (match_operand:DI 3 "immediate_operand" "i")
19950                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19951    (clobber (match_operand:DI 1 "register_operand" "=D"))
19952    (clobber (reg:CC FLAGS_REG))]
19953   "TARGET_64BIT"
19954   "repnz scasb"
19955   [(set_attr "type" "str")
19956    (set_attr "mode" "QI")
19957    (set_attr "prefix_rep" "1")])
19958
19959 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19960 ;; handled in combine, but it is not currently up to the task.
19961 ;; When used for their truth value, the cmpstrn* expanders generate
19962 ;; code like this:
19963 ;;
19964 ;;   repz cmpsb
19965 ;;   seta       %al
19966 ;;   setb       %dl
19967 ;;   cmpb       %al, %dl
19968 ;;   jcc        label
19969 ;;
19970 ;; The intermediate three instructions are unnecessary.
19971
19972 ;; This one handles cmpstrn*_nz_1...
19973 (define_peephole2
19974   [(parallel[
19975      (set (reg:CC FLAGS_REG)
19976           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19977                       (mem:BLK (match_operand 5 "register_operand" ""))))
19978      (use (match_operand 6 "register_operand" ""))
19979      (use (match_operand:SI 3 "immediate_operand" ""))
19980      (clobber (match_operand 0 "register_operand" ""))
19981      (clobber (match_operand 1 "register_operand" ""))
19982      (clobber (match_operand 2 "register_operand" ""))])
19983    (set (match_operand:QI 7 "register_operand" "")
19984         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19985    (set (match_operand:QI 8 "register_operand" "")
19986         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19987    (set (reg FLAGS_REG)
19988         (compare (match_dup 7) (match_dup 8)))
19989   ]
19990   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19991   [(parallel[
19992      (set (reg:CC FLAGS_REG)
19993           (compare:CC (mem:BLK (match_dup 4))
19994                       (mem:BLK (match_dup 5))))
19995      (use (match_dup 6))
19996      (use (match_dup 3))
19997      (clobber (match_dup 0))
19998      (clobber (match_dup 1))
19999      (clobber (match_dup 2))])]
20000   "")
20001
20002 ;; ...and this one handles cmpstrn*_1.
20003 (define_peephole2
20004   [(parallel[
20005      (set (reg:CC FLAGS_REG)
20006           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
20007                                (const_int 0))
20008             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20009                         (mem:BLK (match_operand 5 "register_operand" "")))
20010             (const_int 0)))
20011      (use (match_operand:SI 3 "immediate_operand" ""))
20012      (use (reg:CC FLAGS_REG))
20013      (clobber (match_operand 0 "register_operand" ""))
20014      (clobber (match_operand 1 "register_operand" ""))
20015      (clobber (match_operand 2 "register_operand" ""))])
20016    (set (match_operand:QI 7 "register_operand" "")
20017         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20018    (set (match_operand:QI 8 "register_operand" "")
20019         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20020    (set (reg FLAGS_REG)
20021         (compare (match_dup 7) (match_dup 8)))
20022   ]
20023   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20024   [(parallel[
20025      (set (reg:CC FLAGS_REG)
20026           (if_then_else:CC (ne (match_dup 6)
20027                                (const_int 0))
20028             (compare:CC (mem:BLK (match_dup 4))
20029                         (mem:BLK (match_dup 5)))
20030             (const_int 0)))
20031      (use (match_dup 3))
20032      (use (reg:CC FLAGS_REG))
20033      (clobber (match_dup 0))
20034      (clobber (match_dup 1))
20035      (clobber (match_dup 2))])]
20036   "")
20037
20038
20039 \f
20040 ;; Conditional move instructions.
20041
20042 (define_expand "movdicc"
20043   [(set (match_operand:DI 0 "register_operand" "")
20044         (if_then_else:DI (match_operand 1 "comparison_operator" "")
20045                          (match_operand:DI 2 "general_operand" "")
20046                          (match_operand:DI 3 "general_operand" "")))]
20047   "TARGET_64BIT"
20048   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20049
20050 (define_insn "x86_movdicc_0_m1_rex64"
20051   [(set (match_operand:DI 0 "register_operand" "=r")
20052         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
20053           (const_int -1)
20054           (const_int 0)))
20055    (clobber (reg:CC FLAGS_REG))]
20056   "TARGET_64BIT"
20057   "sbb{q}\t%0, %0"
20058   ; Since we don't have the proper number of operands for an alu insn,
20059   ; fill in all the blanks.
20060   [(set_attr "type" "alu")
20061    (set_attr "use_carry" "1")
20062    (set_attr "pent_pair" "pu")
20063    (set_attr "memory" "none")
20064    (set_attr "imm_disp" "false")
20065    (set_attr "mode" "DI")
20066    (set_attr "length_immediate" "0")])
20067
20068 (define_insn "*x86_movdicc_0_m1_se"
20069   [(set (match_operand:DI 0 "register_operand" "=r")
20070         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
20071                          (const_int 1)
20072                          (const_int 0)))
20073    (clobber (reg:CC FLAGS_REG))]
20074   ""
20075   "sbb{q}\t%0, %0"
20076   [(set_attr "type" "alu")
20077    (set_attr "use_carry" "1")
20078    (set_attr "pent_pair" "pu")
20079    (set_attr "memory" "none")
20080    (set_attr "imm_disp" "false")
20081    (set_attr "mode" "DI")
20082    (set_attr "length_immediate" "0")])
20083
20084 (define_insn "*movdicc_c_rex64"
20085   [(set (match_operand:DI 0 "register_operand" "=r,r")
20086         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
20087                                 [(reg FLAGS_REG) (const_int 0)])
20088                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
20089                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
20090   "TARGET_64BIT && TARGET_CMOVE
20091    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20092   "@
20093    cmov%O2%C1\t{%2, %0|%0, %2}
20094    cmov%O2%c1\t{%3, %0|%0, %3}"
20095   [(set_attr "type" "icmov")
20096    (set_attr "mode" "DI")])
20097
20098 (define_expand "movsicc"
20099   [(set (match_operand:SI 0 "register_operand" "")
20100         (if_then_else:SI (match_operand 1 "comparison_operator" "")
20101                          (match_operand:SI 2 "general_operand" "")
20102                          (match_operand:SI 3 "general_operand" "")))]
20103   ""
20104   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20105
20106 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
20107 ;; the register first winds up with `sbbl $0,reg', which is also weird.
20108 ;; So just document what we're doing explicitly.
20109
20110 (define_insn "x86_movsicc_0_m1"
20111   [(set (match_operand:SI 0 "register_operand" "=r")
20112         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
20113           (const_int -1)
20114           (const_int 0)))
20115    (clobber (reg:CC FLAGS_REG))]
20116   ""
20117   "sbb{l}\t%0, %0"
20118   ; Since we don't have the proper number of operands for an alu insn,
20119   ; fill in all the blanks.
20120   [(set_attr "type" "alu")
20121    (set_attr "use_carry" "1")
20122    (set_attr "pent_pair" "pu")
20123    (set_attr "memory" "none")
20124    (set_attr "imm_disp" "false")
20125    (set_attr "mode" "SI")
20126    (set_attr "length_immediate" "0")])
20127
20128 (define_insn "*x86_movsicc_0_m1_se"
20129   [(set (match_operand:SI 0 "register_operand" "=r")
20130         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
20131                          (const_int 1)
20132                          (const_int 0)))
20133    (clobber (reg:CC FLAGS_REG))]
20134   ""
20135   "sbb{l}\t%0, %0"
20136   [(set_attr "type" "alu")
20137    (set_attr "use_carry" "1")
20138    (set_attr "pent_pair" "pu")
20139    (set_attr "memory" "none")
20140    (set_attr "imm_disp" "false")
20141    (set_attr "mode" "SI")
20142    (set_attr "length_immediate" "0")])
20143
20144 (define_insn "*movsicc_noc"
20145   [(set (match_operand:SI 0 "register_operand" "=r,r")
20146         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
20147                                 [(reg FLAGS_REG) (const_int 0)])
20148                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20149                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
20150   "TARGET_CMOVE
20151    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20152   "@
20153    cmov%O2%C1\t{%2, %0|%0, %2}
20154    cmov%O2%c1\t{%3, %0|%0, %3}"
20155   [(set_attr "type" "icmov")
20156    (set_attr "mode" "SI")])
20157
20158 (define_expand "movhicc"
20159   [(set (match_operand:HI 0 "register_operand" "")
20160         (if_then_else:HI (match_operand 1 "comparison_operator" "")
20161                          (match_operand:HI 2 "general_operand" "")
20162                          (match_operand:HI 3 "general_operand" "")))]
20163   "TARGET_HIMODE_MATH"
20164   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20165
20166 (define_insn "*movhicc_noc"
20167   [(set (match_operand:HI 0 "register_operand" "=r,r")
20168         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
20169                                 [(reg FLAGS_REG) (const_int 0)])
20170                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20171                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20172   "TARGET_CMOVE
20173    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20174   "@
20175    cmov%O2%C1\t{%2, %0|%0, %2}
20176    cmov%O2%c1\t{%3, %0|%0, %3}"
20177   [(set_attr "type" "icmov")
20178    (set_attr "mode" "HI")])
20179
20180 (define_expand "movqicc"
20181   [(set (match_operand:QI 0 "register_operand" "")
20182         (if_then_else:QI (match_operand 1 "comparison_operator" "")
20183                          (match_operand:QI 2 "general_operand" "")
20184                          (match_operand:QI 3 "general_operand" "")))]
20185   "TARGET_QIMODE_MATH"
20186   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20187
20188 (define_insn_and_split "*movqicc_noc"
20189   [(set (match_operand:QI 0 "register_operand" "=r,r")
20190         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20191                                 [(match_operand 4 "flags_reg_operand" "")
20192                                  (const_int 0)])
20193                       (match_operand:QI 2 "register_operand" "r,0")
20194                       (match_operand:QI 3 "register_operand" "0,r")))]
20195   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20196   "#"
20197   "&& reload_completed"
20198   [(set (match_dup 0)
20199         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20200                       (match_dup 2)
20201                       (match_dup 3)))]
20202   "operands[0] = gen_lowpart (SImode, operands[0]);
20203    operands[2] = gen_lowpart (SImode, operands[2]);
20204    operands[3] = gen_lowpart (SImode, operands[3]);"
20205   [(set_attr "type" "icmov")
20206    (set_attr "mode" "SI")])
20207
20208 (define_expand "mov<mode>cc"
20209   [(set (match_operand:X87MODEF 0 "register_operand" "")
20210         (if_then_else:X87MODEF
20211           (match_operand 1 "comparison_operator" "")
20212           (match_operand:X87MODEF 2 "register_operand" "")
20213           (match_operand:X87MODEF 3 "register_operand" "")))]
20214   "(TARGET_80387 && TARGET_CMOVE)
20215    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20216   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20217
20218 (define_insn "*movsfcc_1_387"
20219   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20220         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20221                                 [(reg FLAGS_REG) (const_int 0)])
20222                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20223                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20224   "TARGET_80387 && TARGET_CMOVE
20225    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20226   "@
20227    fcmov%F1\t{%2, %0|%0, %2}
20228    fcmov%f1\t{%3, %0|%0, %3}
20229    cmov%O2%C1\t{%2, %0|%0, %2}
20230    cmov%O2%c1\t{%3, %0|%0, %3}"
20231   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20232    (set_attr "mode" "SF,SF,SI,SI")])
20233
20234 (define_insn "*movdfcc_1"
20235   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20236         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20237                                 [(reg FLAGS_REG) (const_int 0)])
20238                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20239                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20240   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20241    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20242   "@
20243    fcmov%F1\t{%2, %0|%0, %2}
20244    fcmov%f1\t{%3, %0|%0, %3}
20245    #
20246    #"
20247   [(set_attr "type" "fcmov,fcmov,multi,multi")
20248    (set_attr "mode" "DF")])
20249
20250 (define_insn "*movdfcc_1_rex64"
20251   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20252         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20253                                 [(reg FLAGS_REG) (const_int 0)])
20254                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20255                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20256   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20257    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20258   "@
20259    fcmov%F1\t{%2, %0|%0, %2}
20260    fcmov%f1\t{%3, %0|%0, %3}
20261    cmov%O2%C1\t{%2, %0|%0, %2}
20262    cmov%O2%c1\t{%3, %0|%0, %3}"
20263   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20264    (set_attr "mode" "DF")])
20265
20266 (define_split
20267   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20268         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20269                                 [(match_operand 4 "flags_reg_operand" "")
20270                                  (const_int 0)])
20271                       (match_operand:DF 2 "nonimmediate_operand" "")
20272                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20273   "!TARGET_64BIT && reload_completed"
20274   [(set (match_dup 2)
20275         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20276                       (match_dup 5)
20277                       (match_dup 6)))
20278    (set (match_dup 3)
20279         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20280                       (match_dup 7)
20281                       (match_dup 8)))]
20282   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20283    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20284
20285 (define_insn "*movxfcc_1"
20286   [(set (match_operand:XF 0 "register_operand" "=f,f")
20287         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20288                                 [(reg FLAGS_REG) (const_int 0)])
20289                       (match_operand:XF 2 "register_operand" "f,0")
20290                       (match_operand:XF 3 "register_operand" "0,f")))]
20291   "TARGET_80387 && TARGET_CMOVE"
20292   "@
20293    fcmov%F1\t{%2, %0|%0, %2}
20294    fcmov%f1\t{%3, %0|%0, %3}"
20295   [(set_attr "type" "fcmov")
20296    (set_attr "mode" "XF")])
20297
20298 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20299 ;; the scalar versions to have only XMM registers as operands.
20300
20301 ;; SSE5 conditional move
20302 (define_insn "*sse5_pcmov_<mode>"
20303   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20304         (if_then_else:MODEF
20305           (match_operand:MODEF 1 "register_operand" "x,0")
20306           (match_operand:MODEF 2 "register_operand" "0,x")
20307           (match_operand:MODEF 3 "register_operand" "x,x")))]
20308   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20309   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20310   [(set_attr "type" "sse4arg")])
20311
20312 ;; These versions of the min/max patterns are intentionally ignorant of
20313 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20314 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20315 ;; are undefined in this condition, we're certain this is correct.
20316
20317 (define_insn "*avx_<code><mode>3"
20318   [(set (match_operand:MODEF 0 "register_operand" "=x")
20319         (smaxmin:MODEF
20320           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20321           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20322   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20323   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20324   [(set_attr "type" "sseadd")
20325    (set_attr "prefix" "vex")
20326    (set_attr "mode" "<MODE>")])
20327
20328 (define_insn "<code><mode>3"
20329   [(set (match_operand:MODEF 0 "register_operand" "=x")
20330         (smaxmin:MODEF
20331           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20332           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20333   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20334   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20335   [(set_attr "type" "sseadd")
20336    (set_attr "mode" "<MODE>")])
20337
20338 ;; These versions of the min/max patterns implement exactly the operations
20339 ;;   min = (op1 < op2 ? op1 : op2)
20340 ;;   max = (!(op1 < op2) ? op1 : op2)
20341 ;; Their operands are not commutative, and thus they may be used in the
20342 ;; presence of -0.0 and NaN.
20343
20344 (define_insn "*avx_ieee_smin<mode>3"
20345   [(set (match_operand:MODEF 0 "register_operand" "=x")
20346         (unspec:MODEF
20347           [(match_operand:MODEF 1 "register_operand" "x")
20348            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20349          UNSPEC_IEEE_MIN))]
20350   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20351   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20352   [(set_attr "type" "sseadd")
20353    (set_attr "prefix" "vex")
20354    (set_attr "mode" "<MODE>")])
20355
20356 (define_insn "*ieee_smin<mode>3"
20357   [(set (match_operand:MODEF 0 "register_operand" "=x")
20358         (unspec:MODEF
20359           [(match_operand:MODEF 1 "register_operand" "0")
20360            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20361          UNSPEC_IEEE_MIN))]
20362   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20363   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20364   [(set_attr "type" "sseadd")
20365    (set_attr "mode" "<MODE>")])
20366
20367 (define_insn "*avx_ieee_smax<mode>3"
20368   [(set (match_operand:MODEF 0 "register_operand" "=x")
20369         (unspec:MODEF
20370           [(match_operand:MODEF 1 "register_operand" "0")
20371            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20372          UNSPEC_IEEE_MAX))]
20373   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20374   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20375   [(set_attr "type" "sseadd")
20376    (set_attr "prefix" "vex")
20377    (set_attr "mode" "<MODE>")])
20378
20379 (define_insn "*ieee_smax<mode>3"
20380   [(set (match_operand:MODEF 0 "register_operand" "=x")
20381         (unspec:MODEF
20382           [(match_operand:MODEF 1 "register_operand" "0")
20383            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20384          UNSPEC_IEEE_MAX))]
20385   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20386   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20387   [(set_attr "type" "sseadd")
20388    (set_attr "mode" "<MODE>")])
20389
20390 ;; Make two stack loads independent:
20391 ;;   fld aa              fld aa
20392 ;;   fld %st(0)     ->   fld bb
20393 ;;   fmul bb             fmul %st(1), %st
20394 ;;
20395 ;; Actually we only match the last two instructions for simplicity.
20396 (define_peephole2
20397   [(set (match_operand 0 "fp_register_operand" "")
20398         (match_operand 1 "fp_register_operand" ""))
20399    (set (match_dup 0)
20400         (match_operator 2 "binary_fp_operator"
20401            [(match_dup 0)
20402             (match_operand 3 "memory_operand" "")]))]
20403   "REGNO (operands[0]) != REGNO (operands[1])"
20404   [(set (match_dup 0) (match_dup 3))
20405    (set (match_dup 0) (match_dup 4))]
20406
20407   ;; The % modifier is not operational anymore in peephole2's, so we have to
20408   ;; swap the operands manually in the case of addition and multiplication.
20409   "if (COMMUTATIVE_ARITH_P (operands[2]))
20410      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20411                                  operands[0], operands[1]);
20412    else
20413      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20414                                  operands[1], operands[0]);")
20415
20416 ;; Conditional addition patterns
20417 (define_expand "add<mode>cc"
20418   [(match_operand:SWI 0 "register_operand" "")
20419    (match_operand 1 "comparison_operator" "")
20420    (match_operand:SWI 2 "register_operand" "")
20421    (match_operand:SWI 3 "const_int_operand" "")]
20422   ""
20423   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20424
20425 \f
20426 ;; Misc patterns (?)
20427
20428 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20429 ;; Otherwise there will be nothing to keep
20430 ;;
20431 ;; [(set (reg ebp) (reg esp))]
20432 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20433 ;;  (clobber (eflags)]
20434 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20435 ;;
20436 ;; in proper program order.
20437 (define_insn "pro_epilogue_adjust_stack_1"
20438   [(set (match_operand:SI 0 "register_operand" "=r,r")
20439         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20440                  (match_operand:SI 2 "immediate_operand" "i,i")))
20441    (clobber (reg:CC FLAGS_REG))
20442    (clobber (mem:BLK (scratch)))]
20443   "!TARGET_64BIT"
20444 {
20445   switch (get_attr_type (insn))
20446     {
20447     case TYPE_IMOV:
20448       return "mov{l}\t{%1, %0|%0, %1}";
20449
20450     case TYPE_ALU:
20451       if (CONST_INT_P (operands[2])
20452           && (INTVAL (operands[2]) == 128
20453               || (INTVAL (operands[2]) < 0
20454                   && INTVAL (operands[2]) != -128)))
20455         {
20456           operands[2] = GEN_INT (-INTVAL (operands[2]));
20457           return "sub{l}\t{%2, %0|%0, %2}";
20458         }
20459       return "add{l}\t{%2, %0|%0, %2}";
20460
20461     case TYPE_LEA:
20462       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20463       return "lea{l}\t{%a2, %0|%0, %a2}";
20464
20465     default:
20466       gcc_unreachable ();
20467     }
20468 }
20469   [(set (attr "type")
20470         (cond [(and (eq_attr "alternative" "0") 
20471                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20472                  (const_string "alu")
20473                (match_operand:SI 2 "const0_operand" "")
20474                  (const_string "imov")
20475               ]
20476               (const_string "lea")))
20477    (set_attr "mode" "SI")])
20478
20479 (define_insn "pro_epilogue_adjust_stack_rex64"
20480   [(set (match_operand:DI 0 "register_operand" "=r,r")
20481         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20482                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20483    (clobber (reg:CC FLAGS_REG))
20484    (clobber (mem:BLK (scratch)))]
20485   "TARGET_64BIT"
20486 {
20487   switch (get_attr_type (insn))
20488     {
20489     case TYPE_IMOV:
20490       return "mov{q}\t{%1, %0|%0, %1}";
20491
20492     case TYPE_ALU:
20493       if (CONST_INT_P (operands[2])
20494           /* Avoid overflows.  */
20495           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20496           && (INTVAL (operands[2]) == 128
20497               || (INTVAL (operands[2]) < 0
20498                   && INTVAL (operands[2]) != -128)))
20499         {
20500           operands[2] = GEN_INT (-INTVAL (operands[2]));
20501           return "sub{q}\t{%2, %0|%0, %2}";
20502         }
20503       return "add{q}\t{%2, %0|%0, %2}";
20504
20505     case TYPE_LEA:
20506       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20507       return "lea{q}\t{%a2, %0|%0, %a2}";
20508
20509     default:
20510       gcc_unreachable ();
20511     }
20512 }
20513   [(set (attr "type")
20514         (cond [(and (eq_attr "alternative" "0")
20515                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20516                  (const_string "alu")
20517                (match_operand:DI 2 "const0_operand" "")
20518                  (const_string "imov")
20519               ]
20520               (const_string "lea")))
20521    (set_attr "mode" "DI")])
20522
20523 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20524   [(set (match_operand:DI 0 "register_operand" "=r,r")
20525         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20526                  (match_operand:DI 3 "immediate_operand" "i,i")))
20527    (use (match_operand:DI 2 "register_operand" "r,r"))
20528    (clobber (reg:CC FLAGS_REG))
20529    (clobber (mem:BLK (scratch)))]
20530   "TARGET_64BIT"
20531 {
20532   switch (get_attr_type (insn))
20533     {
20534     case TYPE_ALU:
20535       return "add{q}\t{%2, %0|%0, %2}";
20536
20537     case TYPE_LEA:
20538       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20539       return "lea{q}\t{%a2, %0|%0, %a2}";
20540
20541     default:
20542       gcc_unreachable ();
20543     }
20544 }
20545   [(set_attr "type" "alu,lea")
20546    (set_attr "mode" "DI")])
20547
20548 (define_insn "allocate_stack_worker_32"
20549   [(set (match_operand:SI 0 "register_operand" "=a")
20550         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20551                             UNSPECV_STACK_PROBE))
20552    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20553    (clobber (reg:CC FLAGS_REG))]
20554   "!TARGET_64BIT && TARGET_STACK_PROBE"
20555   "call\t___chkstk"
20556   [(set_attr "type" "multi")
20557    (set_attr "length" "5")])
20558
20559 (define_insn "allocate_stack_worker_64"
20560   [(set (match_operand:DI 0 "register_operand" "=a")
20561         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20562                             UNSPECV_STACK_PROBE))
20563    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20564    (clobber (reg:DI R10_REG))
20565    (clobber (reg:DI R11_REG))
20566    (clobber (reg:CC FLAGS_REG))]
20567   "TARGET_64BIT && TARGET_STACK_PROBE"
20568   "call\t___chkstk"
20569   [(set_attr "type" "multi")
20570    (set_attr "length" "5")])
20571
20572 (define_expand "allocate_stack"
20573   [(match_operand 0 "register_operand" "")
20574    (match_operand 1 "general_operand" "")]
20575   "TARGET_STACK_PROBE"
20576 {
20577   rtx x;
20578
20579 #ifndef CHECK_STACK_LIMIT
20580 #define CHECK_STACK_LIMIT 0
20581 #endif
20582
20583   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20584       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20585     {
20586       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20587                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20588       if (x != stack_pointer_rtx)
20589         emit_move_insn (stack_pointer_rtx, x);
20590     }
20591   else
20592     {
20593       x = copy_to_mode_reg (Pmode, operands[1]);
20594       if (TARGET_64BIT)
20595         x = gen_allocate_stack_worker_64 (x, x);
20596       else
20597         x = gen_allocate_stack_worker_32 (x, x);
20598       emit_insn (x);
20599     }
20600
20601   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20602   DONE;
20603 })
20604
20605 (define_expand "builtin_setjmp_receiver"
20606   [(label_ref (match_operand 0 "" ""))]
20607   "!TARGET_64BIT && flag_pic"
20608 {
20609 #if TARGET_MACHO
20610   if (TARGET_MACHO)
20611     {
20612       rtx xops[3];
20613       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20614       rtx label_rtx = gen_label_rtx ();
20615       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20616       xops[0] = xops[1] = picreg;
20617       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20618       ix86_expand_binary_operator (MINUS, SImode, xops);
20619     }
20620   else
20621 #endif
20622     emit_insn (gen_set_got (pic_offset_table_rtx));
20623   DONE;
20624 })
20625 \f
20626 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20627
20628 (define_split
20629   [(set (match_operand 0 "register_operand" "")
20630         (match_operator 3 "promotable_binary_operator"
20631            [(match_operand 1 "register_operand" "")
20632             (match_operand 2 "aligned_operand" "")]))
20633    (clobber (reg:CC FLAGS_REG))]
20634   "! TARGET_PARTIAL_REG_STALL && reload_completed
20635    && ((GET_MODE (operands[0]) == HImode
20636         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20637             /* ??? next two lines just !satisfies_constraint_K (...) */
20638             || !CONST_INT_P (operands[2])
20639             || satisfies_constraint_K (operands[2])))
20640        || (GET_MODE (operands[0]) == QImode
20641            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20642   [(parallel [(set (match_dup 0)
20643                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20644               (clobber (reg:CC FLAGS_REG))])]
20645   "operands[0] = gen_lowpart (SImode, operands[0]);
20646    operands[1] = gen_lowpart (SImode, operands[1]);
20647    if (GET_CODE (operands[3]) != ASHIFT)
20648      operands[2] = gen_lowpart (SImode, operands[2]);
20649    PUT_MODE (operands[3], SImode);")
20650
20651 ; Promote the QImode tests, as i386 has encoding of the AND
20652 ; instruction with 32-bit sign-extended immediate and thus the
20653 ; instruction size is unchanged, except in the %eax case for
20654 ; which it is increased by one byte, hence the ! optimize_size.
20655 (define_split
20656   [(set (match_operand 0 "flags_reg_operand" "")
20657         (match_operator 2 "compare_operator"
20658           [(and (match_operand 3 "aligned_operand" "")
20659                 (match_operand 4 "const_int_operand" ""))
20660            (const_int 0)]))
20661    (set (match_operand 1 "register_operand" "")
20662         (and (match_dup 3) (match_dup 4)))]
20663   "! TARGET_PARTIAL_REG_STALL && reload_completed
20664    && optimize_insn_for_speed_p ()
20665    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20666        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20667    /* Ensure that the operand will remain sign-extended immediate.  */
20668    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20669   [(parallel [(set (match_dup 0)
20670                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20671                                     (const_int 0)]))
20672               (set (match_dup 1)
20673                    (and:SI (match_dup 3) (match_dup 4)))])]
20674 {
20675   operands[4]
20676     = gen_int_mode (INTVAL (operands[4])
20677                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20678   operands[1] = gen_lowpart (SImode, operands[1]);
20679   operands[3] = gen_lowpart (SImode, operands[3]);
20680 })
20681
20682 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20683 ; the TEST instruction with 32-bit sign-extended immediate and thus
20684 ; the instruction size would at least double, which is not what we
20685 ; want even with ! optimize_size.
20686 (define_split
20687   [(set (match_operand 0 "flags_reg_operand" "")
20688         (match_operator 1 "compare_operator"
20689           [(and (match_operand:HI 2 "aligned_operand" "")
20690                 (match_operand:HI 3 "const_int_operand" ""))
20691            (const_int 0)]))]
20692   "! TARGET_PARTIAL_REG_STALL && reload_completed
20693    && ! TARGET_FAST_PREFIX
20694    && optimize_insn_for_speed_p ()
20695    /* Ensure that the operand will remain sign-extended immediate.  */
20696    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20697   [(set (match_dup 0)
20698         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20699                          (const_int 0)]))]
20700 {
20701   operands[3]
20702     = gen_int_mode (INTVAL (operands[3])
20703                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20704   operands[2] = gen_lowpart (SImode, operands[2]);
20705 })
20706
20707 (define_split
20708   [(set (match_operand 0 "register_operand" "")
20709         (neg (match_operand 1 "register_operand" "")))
20710    (clobber (reg:CC FLAGS_REG))]
20711   "! TARGET_PARTIAL_REG_STALL && reload_completed
20712    && (GET_MODE (operands[0]) == HImode
20713        || (GET_MODE (operands[0]) == QImode
20714            && (TARGET_PROMOTE_QImode
20715                || optimize_insn_for_size_p ())))"
20716   [(parallel [(set (match_dup 0)
20717                    (neg:SI (match_dup 1)))
20718               (clobber (reg:CC FLAGS_REG))])]
20719   "operands[0] = gen_lowpart (SImode, operands[0]);
20720    operands[1] = gen_lowpart (SImode, operands[1]);")
20721
20722 (define_split
20723   [(set (match_operand 0 "register_operand" "")
20724         (not (match_operand 1 "register_operand" "")))]
20725   "! TARGET_PARTIAL_REG_STALL && reload_completed
20726    && (GET_MODE (operands[0]) == HImode
20727        || (GET_MODE (operands[0]) == QImode
20728            && (TARGET_PROMOTE_QImode
20729                || optimize_insn_for_size_p ())))"
20730   [(set (match_dup 0)
20731         (not:SI (match_dup 1)))]
20732   "operands[0] = gen_lowpart (SImode, operands[0]);
20733    operands[1] = gen_lowpart (SImode, operands[1]);")
20734
20735 (define_split
20736   [(set (match_operand 0 "register_operand" "")
20737         (if_then_else (match_operator 1 "comparison_operator"
20738                                 [(reg FLAGS_REG) (const_int 0)])
20739                       (match_operand 2 "register_operand" "")
20740                       (match_operand 3 "register_operand" "")))]
20741   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20742    && (GET_MODE (operands[0]) == HImode
20743        || (GET_MODE (operands[0]) == QImode
20744            && (TARGET_PROMOTE_QImode
20745                || optimize_insn_for_size_p ())))"
20746   [(set (match_dup 0)
20747         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20748   "operands[0] = gen_lowpart (SImode, operands[0]);
20749    operands[2] = gen_lowpart (SImode, operands[2]);
20750    operands[3] = gen_lowpart (SImode, operands[3]);")
20751
20752 \f
20753 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20754 ;; transform a complex memory operation into two memory to register operations.
20755
20756 ;; Don't push memory operands
20757 (define_peephole2
20758   [(set (match_operand:SI 0 "push_operand" "")
20759         (match_operand:SI 1 "memory_operand" ""))
20760    (match_scratch:SI 2 "r")]
20761   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20762    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20763   [(set (match_dup 2) (match_dup 1))
20764    (set (match_dup 0) (match_dup 2))]
20765   "")
20766
20767 (define_peephole2
20768   [(set (match_operand:DI 0 "push_operand" "")
20769         (match_operand:DI 1 "memory_operand" ""))
20770    (match_scratch:DI 2 "r")]
20771   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20772    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20773   [(set (match_dup 2) (match_dup 1))
20774    (set (match_dup 0) (match_dup 2))]
20775   "")
20776
20777 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20778 ;; SImode pushes.
20779 (define_peephole2
20780   [(set (match_operand:SF 0 "push_operand" "")
20781         (match_operand:SF 1 "memory_operand" ""))
20782    (match_scratch:SF 2 "r")]
20783   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20784    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20785   [(set (match_dup 2) (match_dup 1))
20786    (set (match_dup 0) (match_dup 2))]
20787   "")
20788
20789 (define_peephole2
20790   [(set (match_operand:HI 0 "push_operand" "")
20791         (match_operand:HI 1 "memory_operand" ""))
20792    (match_scratch:HI 2 "r")]
20793   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20794    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20795   [(set (match_dup 2) (match_dup 1))
20796    (set (match_dup 0) (match_dup 2))]
20797   "")
20798
20799 (define_peephole2
20800   [(set (match_operand:QI 0 "push_operand" "")
20801         (match_operand:QI 1 "memory_operand" ""))
20802    (match_scratch:QI 2 "q")]
20803   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20804    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20805   [(set (match_dup 2) (match_dup 1))
20806    (set (match_dup 0) (match_dup 2))]
20807   "")
20808
20809 ;; Don't move an immediate directly to memory when the instruction
20810 ;; gets too big.
20811 (define_peephole2
20812   [(match_scratch:SI 1 "r")
20813    (set (match_operand:SI 0 "memory_operand" "")
20814         (const_int 0))]
20815   "optimize_insn_for_speed_p ()
20816    && ! TARGET_USE_MOV0
20817    && TARGET_SPLIT_LONG_MOVES
20818    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20819    && peep2_regno_dead_p (0, FLAGS_REG)"
20820   [(parallel [(set (match_dup 1) (const_int 0))
20821               (clobber (reg:CC FLAGS_REG))])
20822    (set (match_dup 0) (match_dup 1))]
20823   "")
20824
20825 (define_peephole2
20826   [(match_scratch:HI 1 "r")
20827    (set (match_operand:HI 0 "memory_operand" "")
20828         (const_int 0))]
20829   "optimize_insn_for_speed_p ()
20830    && ! TARGET_USE_MOV0
20831    && TARGET_SPLIT_LONG_MOVES
20832    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20833    && peep2_regno_dead_p (0, FLAGS_REG)"
20834   [(parallel [(set (match_dup 2) (const_int 0))
20835               (clobber (reg:CC FLAGS_REG))])
20836    (set (match_dup 0) (match_dup 1))]
20837   "operands[2] = gen_lowpart (SImode, operands[1]);")
20838
20839 (define_peephole2
20840   [(match_scratch:QI 1 "q")
20841    (set (match_operand:QI 0 "memory_operand" "")
20842         (const_int 0))]
20843   "optimize_insn_for_speed_p ()
20844    && ! TARGET_USE_MOV0
20845    && TARGET_SPLIT_LONG_MOVES
20846    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20847    && peep2_regno_dead_p (0, FLAGS_REG)"
20848   [(parallel [(set (match_dup 2) (const_int 0))
20849               (clobber (reg:CC FLAGS_REG))])
20850    (set (match_dup 0) (match_dup 1))]
20851   "operands[2] = gen_lowpart (SImode, operands[1]);")
20852
20853 (define_peephole2
20854   [(match_scratch:SI 2 "r")
20855    (set (match_operand:SI 0 "memory_operand" "")
20856         (match_operand:SI 1 "immediate_operand" ""))]
20857   "optimize_insn_for_speed_p ()
20858    && TARGET_SPLIT_LONG_MOVES
20859    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20860   [(set (match_dup 2) (match_dup 1))
20861    (set (match_dup 0) (match_dup 2))]
20862   "")
20863
20864 (define_peephole2
20865   [(match_scratch:HI 2 "r")
20866    (set (match_operand:HI 0 "memory_operand" "")
20867         (match_operand:HI 1 "immediate_operand" ""))]
20868   "optimize_insn_for_speed_p ()
20869    && TARGET_SPLIT_LONG_MOVES
20870    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20871   [(set (match_dup 2) (match_dup 1))
20872    (set (match_dup 0) (match_dup 2))]
20873   "")
20874
20875 (define_peephole2
20876   [(match_scratch:QI 2 "q")
20877    (set (match_operand:QI 0 "memory_operand" "")
20878         (match_operand:QI 1 "immediate_operand" ""))]
20879   "optimize_insn_for_speed_p ()
20880    && TARGET_SPLIT_LONG_MOVES
20881    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20882   [(set (match_dup 2) (match_dup 1))
20883    (set (match_dup 0) (match_dup 2))]
20884   "")
20885
20886 ;; Don't compare memory with zero, load and use a test instead.
20887 (define_peephole2
20888   [(set (match_operand 0 "flags_reg_operand" "")
20889         (match_operator 1 "compare_operator"
20890           [(match_operand:SI 2 "memory_operand" "")
20891            (const_int 0)]))
20892    (match_scratch:SI 3 "r")]
20893   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20894   [(set (match_dup 3) (match_dup 2))
20895    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20896   "")
20897
20898 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20899 ;; Don't split NOTs with a displacement operand, because resulting XOR
20900 ;; will not be pairable anyway.
20901 ;;
20902 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20903 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20904 ;; so this split helps here as well.
20905 ;;
20906 ;; Note: Can't do this as a regular split because we can't get proper
20907 ;; lifetime information then.
20908
20909 (define_peephole2
20910   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20911         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20912   "optimize_insn_for_speed_p ()
20913    && ((TARGET_NOT_UNPAIRABLE
20914         && (!MEM_P (operands[0])
20915             || !memory_displacement_operand (operands[0], SImode)))
20916        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20917    && peep2_regno_dead_p (0, FLAGS_REG)"
20918   [(parallel [(set (match_dup 0)
20919                    (xor:SI (match_dup 1) (const_int -1)))
20920               (clobber (reg:CC FLAGS_REG))])]
20921   "")
20922
20923 (define_peephole2
20924   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20925         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20926   "optimize_insn_for_speed_p ()
20927    && ((TARGET_NOT_UNPAIRABLE
20928         && (!MEM_P (operands[0])
20929             || !memory_displacement_operand (operands[0], HImode)))
20930        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20931    && peep2_regno_dead_p (0, FLAGS_REG)"
20932   [(parallel [(set (match_dup 0)
20933                    (xor:HI (match_dup 1) (const_int -1)))
20934               (clobber (reg:CC FLAGS_REG))])]
20935   "")
20936
20937 (define_peephole2
20938   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20939         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20940   "optimize_insn_for_speed_p ()
20941    && ((TARGET_NOT_UNPAIRABLE
20942         && (!MEM_P (operands[0])
20943             || !memory_displacement_operand (operands[0], QImode)))
20944        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20945    && peep2_regno_dead_p (0, FLAGS_REG)"
20946   [(parallel [(set (match_dup 0)
20947                    (xor:QI (match_dup 1) (const_int -1)))
20948               (clobber (reg:CC FLAGS_REG))])]
20949   "")
20950
20951 ;; Non pairable "test imm, reg" instructions can be translated to
20952 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20953 ;; byte opcode instead of two, have a short form for byte operands),
20954 ;; so do it for other CPUs as well.  Given that the value was dead,
20955 ;; this should not create any new dependencies.  Pass on the sub-word
20956 ;; versions if we're concerned about partial register stalls.
20957
20958 (define_peephole2
20959   [(set (match_operand 0 "flags_reg_operand" "")
20960         (match_operator 1 "compare_operator"
20961           [(and:SI (match_operand:SI 2 "register_operand" "")
20962                    (match_operand:SI 3 "immediate_operand" ""))
20963            (const_int 0)]))]
20964   "ix86_match_ccmode (insn, CCNOmode)
20965    && (true_regnum (operands[2]) != AX_REG
20966        || satisfies_constraint_K (operands[3]))
20967    && peep2_reg_dead_p (1, operands[2])"
20968   [(parallel
20969      [(set (match_dup 0)
20970            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20971                             (const_int 0)]))
20972       (set (match_dup 2)
20973            (and:SI (match_dup 2) (match_dup 3)))])]
20974   "")
20975
20976 ;; We don't need to handle HImode case, because it will be promoted to SImode
20977 ;; on ! TARGET_PARTIAL_REG_STALL
20978
20979 (define_peephole2
20980   [(set (match_operand 0 "flags_reg_operand" "")
20981         (match_operator 1 "compare_operator"
20982           [(and:QI (match_operand:QI 2 "register_operand" "")
20983                    (match_operand:QI 3 "immediate_operand" ""))
20984            (const_int 0)]))]
20985   "! TARGET_PARTIAL_REG_STALL
20986    && ix86_match_ccmode (insn, CCNOmode)
20987    && true_regnum (operands[2]) != AX_REG
20988    && peep2_reg_dead_p (1, operands[2])"
20989   [(parallel
20990      [(set (match_dup 0)
20991            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20992                             (const_int 0)]))
20993       (set (match_dup 2)
20994            (and:QI (match_dup 2) (match_dup 3)))])]
20995   "")
20996
20997 (define_peephole2
20998   [(set (match_operand 0 "flags_reg_operand" "")
20999         (match_operator 1 "compare_operator"
21000           [(and:SI
21001              (zero_extract:SI
21002                (match_operand 2 "ext_register_operand" "")
21003                (const_int 8)
21004                (const_int 8))
21005              (match_operand 3 "const_int_operand" ""))
21006            (const_int 0)]))]
21007   "! TARGET_PARTIAL_REG_STALL
21008    && ix86_match_ccmode (insn, CCNOmode)
21009    && true_regnum (operands[2]) != AX_REG
21010    && peep2_reg_dead_p (1, operands[2])"
21011   [(parallel [(set (match_dup 0)
21012                    (match_op_dup 1
21013                      [(and:SI
21014                         (zero_extract:SI
21015                           (match_dup 2)
21016                           (const_int 8)
21017                           (const_int 8))
21018                         (match_dup 3))
21019                       (const_int 0)]))
21020               (set (zero_extract:SI (match_dup 2)
21021                                     (const_int 8)
21022                                     (const_int 8))
21023                    (and:SI
21024                      (zero_extract:SI
21025                        (match_dup 2)
21026                        (const_int 8)
21027                        (const_int 8))
21028                      (match_dup 3)))])]
21029   "")
21030
21031 ;; Don't do logical operations with memory inputs.
21032 (define_peephole2
21033   [(match_scratch:SI 2 "r")
21034    (parallel [(set (match_operand:SI 0 "register_operand" "")
21035                    (match_operator:SI 3 "arith_or_logical_operator"
21036                      [(match_dup 0)
21037                       (match_operand:SI 1 "memory_operand" "")]))
21038               (clobber (reg:CC FLAGS_REG))])]
21039   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21040   [(set (match_dup 2) (match_dup 1))
21041    (parallel [(set (match_dup 0)
21042                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
21043               (clobber (reg:CC FLAGS_REG))])]
21044   "")
21045
21046 (define_peephole2
21047   [(match_scratch:SI 2 "r")
21048    (parallel [(set (match_operand:SI 0 "register_operand" "")
21049                    (match_operator:SI 3 "arith_or_logical_operator"
21050                      [(match_operand:SI 1 "memory_operand" "")
21051                       (match_dup 0)]))
21052               (clobber (reg:CC FLAGS_REG))])]
21053   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21054   [(set (match_dup 2) (match_dup 1))
21055    (parallel [(set (match_dup 0)
21056                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
21057               (clobber (reg:CC FLAGS_REG))])]
21058   "")
21059
21060 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
21061 ;; refers to the destination of the load!
21062
21063 (define_peephole2
21064   [(set (match_operand:SI 0 "register_operand" "")
21065         (match_operand:SI 1 "register_operand" ""))
21066    (parallel [(set (match_dup 0)
21067                    (match_operator:SI 3 "commutative_operator"
21068                      [(match_dup 0)
21069                       (match_operand:SI 2 "memory_operand" "")]))
21070               (clobber (reg:CC FLAGS_REG))])]
21071   "REGNO (operands[0]) != REGNO (operands[1])
21072    && GENERAL_REGNO_P (REGNO (operands[0]))
21073    && GENERAL_REGNO_P (REGNO (operands[1]))"
21074   [(set (match_dup 0) (match_dup 4))
21075    (parallel [(set (match_dup 0)
21076                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
21077               (clobber (reg:CC FLAGS_REG))])]
21078   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
21079
21080 (define_peephole2
21081   [(set (match_operand 0 "register_operand" "")
21082         (match_operand 1 "register_operand" ""))
21083    (set (match_dup 0)
21084                    (match_operator 3 "commutative_operator"
21085                      [(match_dup 0)
21086                       (match_operand 2 "memory_operand" "")]))]
21087   "REGNO (operands[0]) != REGNO (operands[1])
21088    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
21089        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
21090   [(set (match_dup 0) (match_dup 2))
21091    (set (match_dup 0)
21092         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
21093   "")
21094
21095 ; Don't do logical operations with memory outputs
21096 ;
21097 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
21098 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
21099 ; the same decoder scheduling characteristics as the original.
21100
21101 (define_peephole2
21102   [(match_scratch:SI 2 "r")
21103    (parallel [(set (match_operand:SI 0 "memory_operand" "")
21104                    (match_operator:SI 3 "arith_or_logical_operator"
21105                      [(match_dup 0)
21106                       (match_operand:SI 1 "nonmemory_operand" "")]))
21107               (clobber (reg:CC FLAGS_REG))])]
21108   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21109   [(set (match_dup 2) (match_dup 0))
21110    (parallel [(set (match_dup 2)
21111                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
21112               (clobber (reg:CC FLAGS_REG))])
21113    (set (match_dup 0) (match_dup 2))]
21114   "")
21115
21116 (define_peephole2
21117   [(match_scratch:SI 2 "r")
21118    (parallel [(set (match_operand:SI 0 "memory_operand" "")
21119                    (match_operator:SI 3 "arith_or_logical_operator"
21120                      [(match_operand:SI 1 "nonmemory_operand" "")
21121                       (match_dup 0)]))
21122               (clobber (reg:CC FLAGS_REG))])]
21123   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21124   [(set (match_dup 2) (match_dup 0))
21125    (parallel [(set (match_dup 2)
21126                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21127               (clobber (reg:CC FLAGS_REG))])
21128    (set (match_dup 0) (match_dup 2))]
21129   "")
21130
21131 ;; Attempt to always use XOR for zeroing registers.
21132 (define_peephole2
21133   [(set (match_operand 0 "register_operand" "")
21134         (match_operand 1 "const0_operand" ""))]
21135   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
21136    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21137    && GENERAL_REG_P (operands[0])
21138    && peep2_regno_dead_p (0, FLAGS_REG)"
21139   [(parallel [(set (match_dup 0) (const_int 0))
21140               (clobber (reg:CC FLAGS_REG))])]
21141 {
21142   operands[0] = gen_lowpart (word_mode, operands[0]);
21143 })
21144
21145 (define_peephole2
21146   [(set (strict_low_part (match_operand 0 "register_operand" ""))
21147         (const_int 0))]
21148   "(GET_MODE (operands[0]) == QImode
21149     || GET_MODE (operands[0]) == HImode)
21150    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21151    && peep2_regno_dead_p (0, FLAGS_REG)"
21152   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
21153               (clobber (reg:CC FLAGS_REG))])])
21154
21155 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21156 (define_peephole2
21157   [(set (match_operand 0 "register_operand" "")
21158         (const_int -1))]
21159   "(GET_MODE (operands[0]) == HImode
21160     || GET_MODE (operands[0]) == SImode
21161     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
21162    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
21163    && peep2_regno_dead_p (0, FLAGS_REG)"
21164   [(parallel [(set (match_dup 0) (const_int -1))
21165               (clobber (reg:CC FLAGS_REG))])]
21166   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21167                               operands[0]);")
21168
21169 ;; Attempt to convert simple leas to adds. These can be created by
21170 ;; move expanders.
21171 (define_peephole2
21172   [(set (match_operand:SI 0 "register_operand" "")
21173         (plus:SI (match_dup 0)
21174                  (match_operand:SI 1 "nonmemory_operand" "")))]
21175   "peep2_regno_dead_p (0, FLAGS_REG)"
21176   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21177               (clobber (reg:CC FLAGS_REG))])]
21178   "")
21179
21180 (define_peephole2
21181   [(set (match_operand:SI 0 "register_operand" "")
21182         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21183                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21184   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21185   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21186               (clobber (reg:CC FLAGS_REG))])]
21187   "operands[2] = gen_lowpart (SImode, operands[2]);")
21188
21189 (define_peephole2
21190   [(set (match_operand:DI 0 "register_operand" "")
21191         (plus:DI (match_dup 0)
21192                  (match_operand:DI 1 "x86_64_general_operand" "")))]
21193   "peep2_regno_dead_p (0, FLAGS_REG)"
21194   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21195               (clobber (reg:CC FLAGS_REG))])]
21196   "")
21197
21198 (define_peephole2
21199   [(set (match_operand:SI 0 "register_operand" "")
21200         (mult:SI (match_dup 0)
21201                  (match_operand:SI 1 "const_int_operand" "")))]
21202   "exact_log2 (INTVAL (operands[1])) >= 0
21203    && peep2_regno_dead_p (0, FLAGS_REG)"
21204   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21205               (clobber (reg:CC FLAGS_REG))])]
21206   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21207
21208 (define_peephole2
21209   [(set (match_operand:DI 0 "register_operand" "")
21210         (mult:DI (match_dup 0)
21211                  (match_operand:DI 1 "const_int_operand" "")))]
21212   "exact_log2 (INTVAL (operands[1])) >= 0
21213    && peep2_regno_dead_p (0, FLAGS_REG)"
21214   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21215               (clobber (reg:CC FLAGS_REG))])]
21216   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21217
21218 (define_peephole2
21219   [(set (match_operand:SI 0 "register_operand" "")
21220         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21221                    (match_operand:DI 2 "const_int_operand" "")) 0))]
21222   "exact_log2 (INTVAL (operands[2])) >= 0
21223    && REGNO (operands[0]) == REGNO (operands[1])
21224    && peep2_regno_dead_p (0, FLAGS_REG)"
21225   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21226               (clobber (reg:CC FLAGS_REG))])]
21227   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21228
21229 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
21230 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
21231 ;; many CPUs it is also faster, since special hardware to avoid esp
21232 ;; dependencies is present.
21233
21234 ;; While some of these conversions may be done using splitters, we use peepholes
21235 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21236
21237 ;; Convert prologue esp subtractions to push.
21238 ;; We need register to push.  In order to keep verify_flow_info happy we have
21239 ;; two choices
21240 ;; - use scratch and clobber it in order to avoid dependencies
21241 ;; - use already live register
21242 ;; We can't use the second way right now, since there is no reliable way how to
21243 ;; verify that given register is live.  First choice will also most likely in
21244 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
21245 ;; call clobbered registers are dead.  We may want to use base pointer as an
21246 ;; alternative when no register is available later.
21247
21248 (define_peephole2
21249   [(match_scratch:SI 0 "r")
21250    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21251               (clobber (reg:CC FLAGS_REG))
21252               (clobber (mem:BLK (scratch)))])]
21253   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21254   [(clobber (match_dup 0))
21255    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21256               (clobber (mem:BLK (scratch)))])])
21257
21258 (define_peephole2
21259   [(match_scratch:SI 0 "r")
21260    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21261               (clobber (reg:CC FLAGS_REG))
21262               (clobber (mem:BLK (scratch)))])]
21263   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21264   [(clobber (match_dup 0))
21265    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21266    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21267               (clobber (mem:BLK (scratch)))])])
21268
21269 ;; Convert esp subtractions to push.
21270 (define_peephole2
21271   [(match_scratch:SI 0 "r")
21272    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21273               (clobber (reg:CC FLAGS_REG))])]
21274   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21275   [(clobber (match_dup 0))
21276    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21277
21278 (define_peephole2
21279   [(match_scratch:SI 0 "r")
21280    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21281               (clobber (reg:CC FLAGS_REG))])]
21282   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21283   [(clobber (match_dup 0))
21284    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21285    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21286
21287 ;; Convert epilogue deallocator to pop.
21288 (define_peephole2
21289   [(match_scratch:SI 0 "r")
21290    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21291               (clobber (reg:CC FLAGS_REG))
21292               (clobber (mem:BLK (scratch)))])]
21293   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21294   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21295               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21296               (clobber (mem:BLK (scratch)))])]
21297   "")
21298
21299 ;; Two pops case is tricky, since pop causes dependency on destination register.
21300 ;; We use two registers if available.
21301 (define_peephole2
21302   [(match_scratch:SI 0 "r")
21303    (match_scratch:SI 1 "r")
21304    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21305               (clobber (reg:CC FLAGS_REG))
21306               (clobber (mem:BLK (scratch)))])]
21307   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21308   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21309               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21310               (clobber (mem:BLK (scratch)))])
21311    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21312               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21313   "")
21314
21315 (define_peephole2
21316   [(match_scratch:SI 0 "r")
21317    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21318               (clobber (reg:CC FLAGS_REG))
21319               (clobber (mem:BLK (scratch)))])]
21320   "optimize_insn_for_size_p ()"
21321   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21322               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21323               (clobber (mem:BLK (scratch)))])
21324    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21325               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21326   "")
21327
21328 ;; Convert esp additions to pop.
21329 (define_peephole2
21330   [(match_scratch:SI 0 "r")
21331    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21332               (clobber (reg:CC FLAGS_REG))])]
21333   ""
21334   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21335               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21336   "")
21337
21338 ;; Two pops case is tricky, since pop causes dependency on destination register.
21339 ;; We use two registers if available.
21340 (define_peephole2
21341   [(match_scratch:SI 0 "r")
21342    (match_scratch:SI 1 "r")
21343    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21344               (clobber (reg:CC FLAGS_REG))])]
21345   ""
21346   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21347               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21348    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21349               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21350   "")
21351
21352 (define_peephole2
21353   [(match_scratch:SI 0 "r")
21354    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21355               (clobber (reg:CC FLAGS_REG))])]
21356   "optimize_insn_for_size_p ()"
21357   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21358               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21359    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21360               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21361   "")
21362 \f
21363 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21364 ;; required and register dies.  Similarly for 128 to -128.
21365 (define_peephole2
21366   [(set (match_operand 0 "flags_reg_operand" "")
21367         (match_operator 1 "compare_operator"
21368           [(match_operand 2 "register_operand" "")
21369            (match_operand 3 "const_int_operand" "")]))]
21370   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
21371      && incdec_operand (operands[3], GET_MODE (operands[3])))
21372     || (!TARGET_FUSE_CMP_AND_BRANCH
21373         && INTVAL (operands[3]) == 128))
21374    && ix86_match_ccmode (insn, CCGCmode)
21375    && peep2_reg_dead_p (1, operands[2])"
21376   [(parallel [(set (match_dup 0)
21377                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21378               (clobber (match_dup 2))])]
21379   "")
21380 \f
21381 (define_peephole2
21382   [(match_scratch:DI 0 "r")
21383    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21384               (clobber (reg:CC FLAGS_REG))
21385               (clobber (mem:BLK (scratch)))])]
21386   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21387   [(clobber (match_dup 0))
21388    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21389               (clobber (mem:BLK (scratch)))])])
21390
21391 (define_peephole2
21392   [(match_scratch:DI 0 "r")
21393    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21394               (clobber (reg:CC FLAGS_REG))
21395               (clobber (mem:BLK (scratch)))])]
21396   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21397   [(clobber (match_dup 0))
21398    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21399    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21400               (clobber (mem:BLK (scratch)))])])
21401
21402 ;; Convert esp subtractions to push.
21403 (define_peephole2
21404   [(match_scratch:DI 0 "r")
21405    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21406               (clobber (reg:CC FLAGS_REG))])]
21407   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21408   [(clobber (match_dup 0))
21409    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21410
21411 (define_peephole2
21412   [(match_scratch:DI 0 "r")
21413    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21414               (clobber (reg:CC FLAGS_REG))])]
21415   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21416   [(clobber (match_dup 0))
21417    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21418    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21419
21420 ;; Convert epilogue deallocator to pop.
21421 (define_peephole2
21422   [(match_scratch:DI 0 "r")
21423    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21424               (clobber (reg:CC FLAGS_REG))
21425               (clobber (mem:BLK (scratch)))])]
21426   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21427   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21428               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21429               (clobber (mem:BLK (scratch)))])]
21430   "")
21431
21432 ;; Two pops case is tricky, since pop causes dependency on destination register.
21433 ;; We use two registers if available.
21434 (define_peephole2
21435   [(match_scratch:DI 0 "r")
21436    (match_scratch:DI 1 "r")
21437    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21438               (clobber (reg:CC FLAGS_REG))
21439               (clobber (mem:BLK (scratch)))])]
21440   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21441   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21442               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21443               (clobber (mem:BLK (scratch)))])
21444    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21445               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21446   "")
21447
21448 (define_peephole2
21449   [(match_scratch:DI 0 "r")
21450    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21451               (clobber (reg:CC FLAGS_REG))
21452               (clobber (mem:BLK (scratch)))])]
21453   "optimize_insn_for_size_p ()"
21454   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21455               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21456               (clobber (mem:BLK (scratch)))])
21457    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21458               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21459   "")
21460
21461 ;; Convert esp additions to pop.
21462 (define_peephole2
21463   [(match_scratch:DI 0 "r")
21464    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21465               (clobber (reg:CC FLAGS_REG))])]
21466   ""
21467   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21468               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21469   "")
21470
21471 ;; Two pops case is tricky, since pop causes dependency on destination register.
21472 ;; We use two registers if available.
21473 (define_peephole2
21474   [(match_scratch:DI 0 "r")
21475    (match_scratch:DI 1 "r")
21476    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21477               (clobber (reg:CC FLAGS_REG))])]
21478   ""
21479   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21480               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21481    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21482               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21483   "")
21484
21485 (define_peephole2
21486   [(match_scratch:DI 0 "r")
21487    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21488               (clobber (reg:CC FLAGS_REG))])]
21489   "optimize_insn_for_size_p ()"
21490   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21491               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21492    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21493               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21494   "")
21495 \f
21496 ;; Convert imul by three, five and nine into lea
21497 (define_peephole2
21498   [(parallel
21499     [(set (match_operand:SI 0 "register_operand" "")
21500           (mult:SI (match_operand:SI 1 "register_operand" "")
21501                    (match_operand:SI 2 "const_int_operand" "")))
21502      (clobber (reg:CC FLAGS_REG))])]
21503   "INTVAL (operands[2]) == 3
21504    || INTVAL (operands[2]) == 5
21505    || INTVAL (operands[2]) == 9"
21506   [(set (match_dup 0)
21507         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21508                  (match_dup 1)))]
21509   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21510
21511 (define_peephole2
21512   [(parallel
21513     [(set (match_operand:SI 0 "register_operand" "")
21514           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21515                    (match_operand:SI 2 "const_int_operand" "")))
21516      (clobber (reg:CC FLAGS_REG))])]
21517   "optimize_insn_for_speed_p ()
21518    && (INTVAL (operands[2]) == 3
21519        || INTVAL (operands[2]) == 5
21520        || INTVAL (operands[2]) == 9)"
21521   [(set (match_dup 0) (match_dup 1))
21522    (set (match_dup 0)
21523         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21524                  (match_dup 0)))]
21525   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21526
21527 (define_peephole2
21528   [(parallel
21529     [(set (match_operand:DI 0 "register_operand" "")
21530           (mult:DI (match_operand:DI 1 "register_operand" "")
21531                    (match_operand:DI 2 "const_int_operand" "")))
21532      (clobber (reg:CC FLAGS_REG))])]
21533   "TARGET_64BIT
21534    && (INTVAL (operands[2]) == 3
21535        || INTVAL (operands[2]) == 5
21536        || INTVAL (operands[2]) == 9)"
21537   [(set (match_dup 0)
21538         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21539                  (match_dup 1)))]
21540   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21541
21542 (define_peephole2
21543   [(parallel
21544     [(set (match_operand:DI 0 "register_operand" "")
21545           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21546                    (match_operand:DI 2 "const_int_operand" "")))
21547      (clobber (reg:CC FLAGS_REG))])]
21548   "TARGET_64BIT
21549    && optimize_insn_for_speed_p ()
21550    && (INTVAL (operands[2]) == 3
21551        || INTVAL (operands[2]) == 5
21552        || INTVAL (operands[2]) == 9)"
21553   [(set (match_dup 0) (match_dup 1))
21554    (set (match_dup 0)
21555         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21556                  (match_dup 0)))]
21557   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21558
21559 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21560 ;; imul $32bit_imm, reg, reg is direct decoded.
21561 (define_peephole2
21562   [(match_scratch:DI 3 "r")
21563    (parallel [(set (match_operand:DI 0 "register_operand" "")
21564                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21565                             (match_operand:DI 2 "immediate_operand" "")))
21566               (clobber (reg:CC FLAGS_REG))])]
21567   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21568    && !satisfies_constraint_K (operands[2])"
21569   [(set (match_dup 3) (match_dup 1))
21570    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21571               (clobber (reg:CC FLAGS_REG))])]
21572 "")
21573
21574 (define_peephole2
21575   [(match_scratch:SI 3 "r")
21576    (parallel [(set (match_operand:SI 0 "register_operand" "")
21577                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21578                             (match_operand:SI 2 "immediate_operand" "")))
21579               (clobber (reg:CC FLAGS_REG))])]
21580   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21581    && !satisfies_constraint_K (operands[2])"
21582   [(set (match_dup 3) (match_dup 1))
21583    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21584               (clobber (reg:CC FLAGS_REG))])]
21585 "")
21586
21587 (define_peephole2
21588   [(match_scratch:SI 3 "r")
21589    (parallel [(set (match_operand:DI 0 "register_operand" "")
21590                    (zero_extend:DI
21591                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21592                               (match_operand:SI 2 "immediate_operand" ""))))
21593               (clobber (reg:CC FLAGS_REG))])]
21594   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21595    && !satisfies_constraint_K (operands[2])"
21596   [(set (match_dup 3) (match_dup 1))
21597    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21598               (clobber (reg:CC FLAGS_REG))])]
21599 "")
21600
21601 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21602 ;; Convert it into imul reg, reg
21603 ;; It would be better to force assembler to encode instruction using long
21604 ;; immediate, but there is apparently no way to do so.
21605 (define_peephole2
21606   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21607                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21608                             (match_operand:DI 2 "const_int_operand" "")))
21609               (clobber (reg:CC FLAGS_REG))])
21610    (match_scratch:DI 3 "r")]
21611   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21612    && satisfies_constraint_K (operands[2])"
21613   [(set (match_dup 3) (match_dup 2))
21614    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21615               (clobber (reg:CC FLAGS_REG))])]
21616 {
21617   if (!rtx_equal_p (operands[0], operands[1]))
21618     emit_move_insn (operands[0], operands[1]);
21619 })
21620
21621 (define_peephole2
21622   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21623                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21624                             (match_operand:SI 2 "const_int_operand" "")))
21625               (clobber (reg:CC FLAGS_REG))])
21626    (match_scratch:SI 3 "r")]
21627   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21628    && satisfies_constraint_K (operands[2])"
21629   [(set (match_dup 3) (match_dup 2))
21630    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21631               (clobber (reg:CC FLAGS_REG))])]
21632 {
21633   if (!rtx_equal_p (operands[0], operands[1]))
21634     emit_move_insn (operands[0], operands[1]);
21635 })
21636
21637 (define_peephole2
21638   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21639                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21640                             (match_operand:HI 2 "immediate_operand" "")))
21641               (clobber (reg:CC FLAGS_REG))])
21642    (match_scratch:HI 3 "r")]
21643   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21644   [(set (match_dup 3) (match_dup 2))
21645    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21646               (clobber (reg:CC FLAGS_REG))])]
21647 {
21648   if (!rtx_equal_p (operands[0], operands[1]))
21649     emit_move_insn (operands[0], operands[1]);
21650 })
21651
21652 ;; After splitting up read-modify operations, array accesses with memory
21653 ;; operands might end up in form:
21654 ;;  sall    $2, %eax
21655 ;;  movl    4(%esp), %edx
21656 ;;  addl    %edx, %eax
21657 ;; instead of pre-splitting:
21658 ;;  sall    $2, %eax
21659 ;;  addl    4(%esp), %eax
21660 ;; Turn it into:
21661 ;;  movl    4(%esp), %edx
21662 ;;  leal    (%edx,%eax,4), %eax
21663
21664 (define_peephole2
21665   [(parallel [(set (match_operand 0 "register_operand" "")
21666                    (ashift (match_operand 1 "register_operand" "")
21667                            (match_operand 2 "const_int_operand" "")))
21668                (clobber (reg:CC FLAGS_REG))])
21669    (set (match_operand 3 "register_operand")
21670         (match_operand 4 "x86_64_general_operand" ""))
21671    (parallel [(set (match_operand 5 "register_operand" "")
21672                    (plus (match_operand 6 "register_operand" "")
21673                          (match_operand 7 "register_operand" "")))
21674                    (clobber (reg:CC FLAGS_REG))])]
21675   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21676    /* Validate MODE for lea.  */
21677    && ((!TARGET_PARTIAL_REG_STALL
21678         && (GET_MODE (operands[0]) == QImode
21679             || GET_MODE (operands[0]) == HImode))
21680        || GET_MODE (operands[0]) == SImode
21681        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21682    /* We reorder load and the shift.  */
21683    && !rtx_equal_p (operands[1], operands[3])
21684    && !reg_overlap_mentioned_p (operands[0], operands[4])
21685    /* Last PLUS must consist of operand 0 and 3.  */
21686    && !rtx_equal_p (operands[0], operands[3])
21687    && (rtx_equal_p (operands[3], operands[6])
21688        || rtx_equal_p (operands[3], operands[7]))
21689    && (rtx_equal_p (operands[0], operands[6])
21690        || rtx_equal_p (operands[0], operands[7]))
21691    /* The intermediate operand 0 must die or be same as output.  */
21692    && (rtx_equal_p (operands[0], operands[5])
21693        || peep2_reg_dead_p (3, operands[0]))"
21694   [(set (match_dup 3) (match_dup 4))
21695    (set (match_dup 0) (match_dup 1))]
21696 {
21697   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21698   int scale = 1 << INTVAL (operands[2]);
21699   rtx index = gen_lowpart (Pmode, operands[1]);
21700   rtx base = gen_lowpart (Pmode, operands[3]);
21701   rtx dest = gen_lowpart (mode, operands[5]);
21702
21703   operands[1] = gen_rtx_PLUS (Pmode, base,
21704                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21705   if (mode != Pmode)
21706     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21707   operands[0] = dest;
21708 })
21709 \f
21710 ;; Call-value patterns last so that the wildcard operand does not
21711 ;; disrupt insn-recog's switch tables.
21712
21713 (define_insn "*call_value_pop_0"
21714   [(set (match_operand 0 "" "")
21715         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21716               (match_operand:SI 2 "" "")))
21717    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21718                             (match_operand:SI 3 "immediate_operand" "")))]
21719   "!TARGET_64BIT"
21720 {
21721   if (SIBLING_CALL_P (insn))
21722     return "jmp\t%P1";
21723   else
21724     return "call\t%P1";
21725 }
21726   [(set_attr "type" "callv")])
21727
21728 (define_insn "*call_value_pop_1"
21729   [(set (match_operand 0 "" "")
21730         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21731               (match_operand:SI 2 "" "")))
21732    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21733                             (match_operand:SI 3 "immediate_operand" "i")))]
21734   "!TARGET_64BIT"
21735 {
21736   if (constant_call_address_operand (operands[1], Pmode))
21737     {
21738       if (SIBLING_CALL_P (insn))
21739         return "jmp\t%P1";
21740       else
21741         return "call\t%P1";
21742     }
21743   if (SIBLING_CALL_P (insn))
21744     return "jmp\t%A1";
21745   else
21746     return "call\t%A1";
21747 }
21748   [(set_attr "type" "callv")])
21749
21750 (define_insn "*call_value_0"
21751   [(set (match_operand 0 "" "")
21752         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21753               (match_operand:SI 2 "" "")))]
21754   "!TARGET_64BIT"
21755 {
21756   if (SIBLING_CALL_P (insn))
21757     return "jmp\t%P1";
21758   else
21759     return "call\t%P1";
21760 }
21761   [(set_attr "type" "callv")])
21762
21763 (define_insn "*call_value_0_rex64"
21764   [(set (match_operand 0 "" "")
21765         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21766               (match_operand:DI 2 "const_int_operand" "")))]
21767   "TARGET_64BIT"
21768 {
21769   if (SIBLING_CALL_P (insn))
21770     return "jmp\t%P1";
21771   else
21772     return "call\t%P1";
21773 }
21774   [(set_attr "type" "callv")])
21775
21776 (define_insn "*call_value_0_rex64_ms_sysv"
21777   [(set (match_operand 0 "" "")
21778         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21779               (match_operand:DI 2 "const_int_operand" "")))
21780    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21781    (clobber (reg:TI XMM6_REG))
21782    (clobber (reg:TI XMM7_REG))
21783    (clobber (reg:TI XMM8_REG))
21784    (clobber (reg:TI XMM9_REG))
21785    (clobber (reg:TI XMM10_REG))
21786    (clobber (reg:TI XMM11_REG))
21787    (clobber (reg:TI XMM12_REG))
21788    (clobber (reg:TI XMM13_REG))
21789    (clobber (reg:TI XMM14_REG))
21790    (clobber (reg:TI XMM15_REG))
21791    (clobber (reg:DI SI_REG))
21792    (clobber (reg:DI DI_REG))]
21793   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21794 {
21795   if (SIBLING_CALL_P (insn))
21796     return "jmp\t%P1";
21797   else
21798     return "call\t%P1";
21799 }
21800   [(set_attr "type" "callv")])
21801
21802 (define_insn "*call_value_1"
21803   [(set (match_operand 0 "" "")
21804         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21805               (match_operand:SI 2 "" "")))]
21806   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21807 {
21808   if (constant_call_address_operand (operands[1], Pmode))
21809     return "call\t%P1";
21810   return "call\t%A1";
21811 }
21812   [(set_attr "type" "callv")])
21813
21814 (define_insn "*sibcall_value_1"
21815   [(set (match_operand 0 "" "")
21816         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21817               (match_operand:SI 2 "" "")))]
21818   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21819 {
21820   if (constant_call_address_operand (operands[1], Pmode))
21821     return "jmp\t%P1";
21822   return "jmp\t%A1";
21823 }
21824   [(set_attr "type" "callv")])
21825
21826 (define_insn "*call_value_1_rex64"
21827   [(set (match_operand 0 "" "")
21828         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21829               (match_operand:DI 2 "" "")))]
21830   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21831    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21832 {
21833   if (constant_call_address_operand (operands[1], Pmode))
21834     return "call\t%P1";
21835   return "call\t%A1";
21836 }
21837   [(set_attr "type" "callv")])
21838
21839 (define_insn "*call_value_1_rex64_ms_sysv"
21840   [(set (match_operand 0 "" "")
21841         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21842               (match_operand:DI 2 "" "")))
21843    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21844    (clobber (reg:TI 27))
21845    (clobber (reg:TI 28))
21846    (clobber (reg:TI 45))
21847    (clobber (reg:TI 46))
21848    (clobber (reg:TI 47))
21849    (clobber (reg:TI 48))
21850    (clobber (reg:TI 49))
21851    (clobber (reg:TI 50))
21852    (clobber (reg:TI 51))
21853    (clobber (reg:TI 52))
21854    (clobber (reg:DI SI_REG))
21855    (clobber (reg:DI DI_REG))]
21856   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21857 {
21858   if (constant_call_address_operand (operands[1], Pmode))
21859     return "call\t%P1";
21860   return "call\t%A1";
21861 }
21862   [(set_attr "type" "callv")])
21863
21864 (define_insn "*call_value_1_rex64_large"
21865   [(set (match_operand 0 "" "")
21866         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21867               (match_operand:DI 2 "" "")))]
21868   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21869   "call\t%A1"
21870   [(set_attr "type" "callv")])
21871
21872 (define_insn "*sibcall_value_1_rex64"
21873   [(set (match_operand 0 "" "")
21874         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21875               (match_operand:DI 2 "" "")))]
21876   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21877   "jmp\t%P1"
21878   [(set_attr "type" "callv")])
21879
21880 (define_insn "*sibcall_value_1_rex64_v"
21881   [(set (match_operand 0 "" "")
21882         (call (mem:QI (reg:DI R11_REG))
21883               (match_operand:DI 1 "" "")))]
21884   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21885   "jmp\t{*%%}r11"
21886   [(set_attr "type" "callv")])
21887 \f
21888 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21889 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21890 ;; caught for use by garbage collectors and the like.  Using an insn that
21891 ;; maps to SIGILL makes it more likely the program will rightfully die.
21892 ;; Keeping with tradition, "6" is in honor of #UD.
21893 (define_insn "trap"
21894   [(trap_if (const_int 1) (const_int 6))]
21895   ""
21896   { return ASM_SHORT "0x0b0f"; }
21897   [(set_attr "length" "2")])
21898
21899 (define_expand "sse_prologue_save"
21900   [(parallel [(set (match_operand:BLK 0 "" "")
21901                    (unspec:BLK [(reg:DI 21)
21902                                 (reg:DI 22)
21903                                 (reg:DI 23)
21904                                 (reg:DI 24)
21905                                 (reg:DI 25)
21906                                 (reg:DI 26)
21907                                 (reg:DI 27)
21908                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21909               (use (match_operand:DI 1 "register_operand" ""))
21910               (use (match_operand:DI 2 "immediate_operand" ""))
21911               (use (label_ref:DI (match_operand 3 "" "")))])]
21912   "TARGET_64BIT"
21913   "")
21914
21915 (define_insn "*sse_prologue_save_insn"
21916   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21917                           (match_operand:DI 4 "const_int_operand" "n")))
21918         (unspec:BLK [(reg:DI 21)
21919                      (reg:DI 22)
21920                      (reg:DI 23)
21921                      (reg:DI 24)
21922                      (reg:DI 25)
21923                      (reg:DI 26)
21924                      (reg:DI 27)
21925                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21926    (use (match_operand:DI 1 "register_operand" "r"))
21927    (use (match_operand:DI 2 "const_int_operand" "i"))
21928    (use (label_ref:DI (match_operand 3 "" "X")))]
21929   "TARGET_64BIT
21930    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21931    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21932 {
21933   int i;
21934   operands[0] = gen_rtx_MEM (Pmode,
21935                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21936   /* VEX instruction with a REX prefix will #UD.  */
21937   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21938     gcc_unreachable ();
21939
21940   output_asm_insn ("jmp\t%A1", operands);
21941   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21942     {
21943       operands[4] = adjust_address (operands[0], DImode, i*16);
21944       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21945       PUT_MODE (operands[4], TImode);
21946       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21947         output_asm_insn ("rex", operands);
21948       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21949     }
21950   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21951                                      CODE_LABEL_NUMBER (operands[3]));
21952   return "";
21953 }
21954   [(set_attr "type" "other")
21955    (set_attr "length_immediate" "0")
21956    (set_attr "length_address" "0")
21957    (set (attr "length")
21958      (if_then_else
21959        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21960        (const_string "34")
21961        (const_string "42")))
21962    (set_attr "memory" "store")
21963    (set_attr "modrm" "0")
21964    (set_attr "prefix" "maybe_vex")
21965    (set_attr "mode" "DI")])
21966
21967 (define_expand "prefetch"
21968   [(prefetch (match_operand 0 "address_operand" "")
21969              (match_operand:SI 1 "const_int_operand" "")
21970              (match_operand:SI 2 "const_int_operand" ""))]
21971   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21972 {
21973   int rw = INTVAL (operands[1]);
21974   int locality = INTVAL (operands[2]);
21975
21976   gcc_assert (rw == 0 || rw == 1);
21977   gcc_assert (locality >= 0 && locality <= 3);
21978   gcc_assert (GET_MODE (operands[0]) == Pmode
21979               || GET_MODE (operands[0]) == VOIDmode);
21980
21981   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21982      supported by SSE counterpart or the SSE prefetch is not available
21983      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21984      of locality.  */
21985   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21986     operands[2] = GEN_INT (3);
21987   else
21988     operands[1] = const0_rtx;
21989 })
21990
21991 (define_insn "*prefetch_sse"
21992   [(prefetch (match_operand:SI 0 "address_operand" "p")
21993              (const_int 0)
21994              (match_operand:SI 1 "const_int_operand" ""))]
21995   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21996 {
21997   static const char * const patterns[4] = {
21998    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21999   };
22000
22001   int locality = INTVAL (operands[1]);
22002   gcc_assert (locality >= 0 && locality <= 3);
22003
22004   return patterns[locality];
22005 }
22006   [(set_attr "type" "sse")
22007    (set_attr "atom_sse_attr" "prefetch")
22008    (set_attr "memory" "none")])
22009
22010 (define_insn "*prefetch_sse_rex"
22011   [(prefetch (match_operand:DI 0 "address_operand" "p")
22012              (const_int 0)
22013              (match_operand:SI 1 "const_int_operand" ""))]
22014   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22015 {
22016   static const char * const patterns[4] = {
22017    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22018   };
22019
22020   int locality = INTVAL (operands[1]);
22021   gcc_assert (locality >= 0 && locality <= 3);
22022
22023   return patterns[locality];
22024 }
22025   [(set_attr "type" "sse")
22026    (set_attr "atom_sse_attr" "prefetch")
22027    (set_attr "memory" "none")])
22028
22029 (define_insn "*prefetch_3dnow"
22030   [(prefetch (match_operand:SI 0 "address_operand" "p")
22031              (match_operand:SI 1 "const_int_operand" "n")
22032              (const_int 3))]
22033   "TARGET_3DNOW && !TARGET_64BIT"
22034 {
22035   if (INTVAL (operands[1]) == 0)
22036     return "prefetch\t%a0";
22037   else
22038     return "prefetchw\t%a0";
22039 }
22040   [(set_attr "type" "mmx")
22041    (set_attr "memory" "none")])
22042
22043 (define_insn "*prefetch_3dnow_rex"
22044   [(prefetch (match_operand:DI 0 "address_operand" "p")
22045              (match_operand:SI 1 "const_int_operand" "n")
22046              (const_int 3))]
22047   "TARGET_3DNOW && TARGET_64BIT"
22048 {
22049   if (INTVAL (operands[1]) == 0)
22050     return "prefetch\t%a0";
22051   else
22052     return "prefetchw\t%a0";
22053 }
22054   [(set_attr "type" "mmx")
22055    (set_attr "memory" "none")])
22056
22057 (define_expand "stack_protect_set"
22058   [(match_operand 0 "memory_operand" "")
22059    (match_operand 1 "memory_operand" "")]
22060   ""
22061 {
22062 #ifdef TARGET_THREAD_SSP_OFFSET
22063   if (TARGET_64BIT)
22064     emit_insn (gen_stack_tls_protect_set_di (operands[0],
22065                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22066   else
22067     emit_insn (gen_stack_tls_protect_set_si (operands[0],
22068                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22069 #else
22070   if (TARGET_64BIT)
22071     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
22072   else
22073     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
22074 #endif
22075   DONE;
22076 })
22077
22078 (define_insn "stack_protect_set_si"
22079   [(set (match_operand:SI 0 "memory_operand" "=m")
22080         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22081    (set (match_scratch:SI 2 "=&r") (const_int 0))
22082    (clobber (reg:CC FLAGS_REG))]
22083   ""
22084   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22085   [(set_attr "type" "multi")])
22086
22087 (define_insn "stack_protect_set_di"
22088   [(set (match_operand:DI 0 "memory_operand" "=m")
22089         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22090    (set (match_scratch:DI 2 "=&r") (const_int 0))
22091    (clobber (reg:CC FLAGS_REG))]
22092   "TARGET_64BIT"
22093   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
22094   [(set_attr "type" "multi")])
22095
22096 (define_insn "stack_tls_protect_set_si"
22097   [(set (match_operand:SI 0 "memory_operand" "=m")
22098         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22099    (set (match_scratch:SI 2 "=&r") (const_int 0))
22100    (clobber (reg:CC FLAGS_REG))]
22101   ""
22102   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22103   [(set_attr "type" "multi")])
22104
22105 (define_insn "stack_tls_protect_set_di"
22106   [(set (match_operand:DI 0 "memory_operand" "=m")
22107         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22108    (set (match_scratch:DI 2 "=&r") (const_int 0))
22109    (clobber (reg:CC FLAGS_REG))]
22110   "TARGET_64BIT"
22111   {
22112      /* The kernel uses a different segment register for performance reasons; a
22113         system call would not have to trash the userspace segment register,
22114         which would be expensive */
22115      if (ix86_cmodel != CM_KERNEL)
22116         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22117      else
22118         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22119   }
22120   [(set_attr "type" "multi")])
22121
22122 (define_expand "stack_protect_test"
22123   [(match_operand 0 "memory_operand" "")
22124    (match_operand 1 "memory_operand" "")
22125    (match_operand 2 "" "")]
22126   ""
22127 {
22128   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
22129
22130 #ifdef TARGET_THREAD_SSP_OFFSET
22131   if (TARGET_64BIT)
22132     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
22133                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22134   else
22135     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
22136                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22137 #else
22138   if (TARGET_64BIT)
22139     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22140   else
22141     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
22142 #endif
22143
22144   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
22145                                   flags, const0_rtx, operands[2]));
22146   DONE;
22147 })
22148
22149 (define_insn "stack_protect_test_si"
22150   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22151         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22152                      (match_operand:SI 2 "memory_operand" "m")]
22153                     UNSPEC_SP_TEST))
22154    (clobber (match_scratch:SI 3 "=&r"))]
22155   ""
22156   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22157   [(set_attr "type" "multi")])
22158
22159 (define_insn "stack_protect_test_di"
22160   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22161         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22162                      (match_operand:DI 2 "memory_operand" "m")]
22163                     UNSPEC_SP_TEST))
22164    (clobber (match_scratch:DI 3 "=&r"))]
22165   "TARGET_64BIT"
22166   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22167   [(set_attr "type" "multi")])
22168
22169 (define_insn "stack_tls_protect_test_si"
22170   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22171         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22172                      (match_operand:SI 2 "const_int_operand" "i")]
22173                     UNSPEC_SP_TLS_TEST))
22174    (clobber (match_scratch:SI 3 "=r"))]
22175   ""
22176   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22177   [(set_attr "type" "multi")])
22178
22179 (define_insn "stack_tls_protect_test_di"
22180   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22181         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22182                      (match_operand:DI 2 "const_int_operand" "i")]
22183                     UNSPEC_SP_TLS_TEST))
22184    (clobber (match_scratch:DI 3 "=r"))]
22185   "TARGET_64BIT"
22186   {
22187      /* The kernel uses a different segment register for performance reasons; a
22188         system call would not have to trash the userspace segment register,
22189         which would be expensive */
22190      if (ix86_cmodel != CM_KERNEL)
22191         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22192      else
22193         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22194   }
22195   [(set_attr "type" "multi")])
22196
22197 (define_mode_iterator CRC32MODE [QI HI SI])
22198 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22199 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22200
22201 (define_insn "sse4_2_crc32<mode>"
22202   [(set (match_operand:SI 0 "register_operand" "=r")
22203         (unspec:SI
22204           [(match_operand:SI 1 "register_operand" "0")
22205            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22206           UNSPEC_CRC32))]
22207   "TARGET_SSE4_2"
22208   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22209   [(set_attr "type" "sselog1")
22210    (set_attr "prefix_rep" "1")
22211    (set_attr "prefix_extra" "1")
22212    (set_attr "mode" "SI")])
22213
22214 (define_insn "sse4_2_crc32di"
22215   [(set (match_operand:DI 0 "register_operand" "=r")
22216         (unspec:DI
22217           [(match_operand:DI 1 "register_operand" "0")
22218            (match_operand:DI 2 "nonimmediate_operand" "rm")]
22219           UNSPEC_CRC32))]
22220   "TARGET_SSE4_2 && TARGET_64BIT"
22221   "crc32q\t{%2, %0|%0, %2}"
22222   [(set_attr "type" "sselog1")
22223    (set_attr "prefix_rep" "1")
22224    (set_attr "prefix_extra" "1")
22225    (set_attr "mode" "DI")])
22226
22227 (include "mmx.md")
22228 (include "sse.md")
22229 (include "sync.md")