OSDN Git Service

29794313716757ba9a678c060846f04489124ba5
[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 instructions.
763
764 ;; All compare insns have expanders that save the operands away without
765 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
766 ;; after the cmp) will actually emit the cmpM.
767
768 (define_expand "cmpti"
769   [(set (reg:CC FLAGS_REG)
770         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
771                     (match_operand:TI 1 "x86_64_general_operand" "")))]
772   "TARGET_64BIT"
773 {
774   if (MEM_P (operands[0]) && MEM_P (operands[1]))
775     operands[0] = force_reg (TImode, operands[0]);
776   ix86_compare_op0 = operands[0];
777   ix86_compare_op1 = operands[1];
778   DONE;
779 })
780
781 (define_expand "cmpdi"
782   [(set (reg:CC FLAGS_REG)
783         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
784                     (match_operand:DI 1 "x86_64_general_operand" "")))]
785   ""
786 {
787   if (MEM_P (operands[0]) && MEM_P (operands[1]))
788     operands[0] = force_reg (DImode, operands[0]);
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 (define_expand "cmpsi"
795   [(set (reg:CC FLAGS_REG)
796         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
797                     (match_operand:SI 1 "general_operand" "")))]
798   ""
799 {
800   if (MEM_P (operands[0]) && MEM_P (operands[1]))
801     operands[0] = force_reg (SImode, operands[0]);
802   ix86_compare_op0 = operands[0];
803   ix86_compare_op1 = operands[1];
804   DONE;
805 })
806
807 (define_expand "cmphi"
808   [(set (reg:CC FLAGS_REG)
809         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
810                     (match_operand:HI 1 "general_operand" "")))]
811   ""
812 {
813   if (MEM_P (operands[0]) && MEM_P (operands[1]))
814     operands[0] = force_reg (HImode, operands[0]);
815   ix86_compare_op0 = operands[0];
816   ix86_compare_op1 = operands[1];
817   DONE;
818 })
819
820 (define_expand "cmpqi"
821   [(set (reg:CC FLAGS_REG)
822         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
823                     (match_operand:QI 1 "general_operand" "")))]
824   "TARGET_QIMODE_MATH"
825 {
826   if (MEM_P (operands[0]) && MEM_P (operands[1]))
827     operands[0] = force_reg (QImode, operands[0]);
828   ix86_compare_op0 = operands[0];
829   ix86_compare_op1 = operands[1];
830   DONE;
831 })
832
833 (define_insn "cmpdi_ccno_1_rex64"
834   [(set (reg FLAGS_REG)
835         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
836                  (match_operand:DI 1 "const0_operand" "")))]
837   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
838   "@
839    test{q}\t%0, %0
840    cmp{q}\t{%1, %0|%0, %1}"
841   [(set_attr "type" "test,icmp")
842    (set_attr "length_immediate" "0,1")
843    (set_attr "mode" "DI")])
844
845 (define_insn "*cmpdi_minus_1_rex64"
846   [(set (reg FLAGS_REG)
847         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
848                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
849                  (const_int 0)))]
850   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
851   "cmp{q}\t{%1, %0|%0, %1}"
852   [(set_attr "type" "icmp")
853    (set_attr "mode" "DI")])
854
855 (define_expand "cmpdi_1_rex64"
856   [(set (reg:CC FLAGS_REG)
857         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
858                     (match_operand:DI 1 "general_operand" "")))]
859   "TARGET_64BIT"
860   "")
861
862 (define_insn "cmpdi_1_insn_rex64"
863   [(set (reg FLAGS_REG)
864         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
865                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
866   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
867   "cmp{q}\t{%1, %0|%0, %1}"
868   [(set_attr "type" "icmp")
869    (set_attr "mode" "DI")])
870
871
872 (define_insn "*cmpsi_ccno_1"
873   [(set (reg FLAGS_REG)
874         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
875                  (match_operand:SI 1 "const0_operand" "")))]
876   "ix86_match_ccmode (insn, CCNOmode)"
877   "@
878    test{l}\t%0, %0
879    cmp{l}\t{%1, %0|%0, %1}"
880   [(set_attr "type" "test,icmp")
881    (set_attr "length_immediate" "0,1")
882    (set_attr "mode" "SI")])
883
884 (define_insn "*cmpsi_minus_1"
885   [(set (reg FLAGS_REG)
886         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
887                            (match_operand:SI 1 "general_operand" "ri,mr"))
888                  (const_int 0)))]
889   "ix86_match_ccmode (insn, CCGOCmode)"
890   "cmp{l}\t{%1, %0|%0, %1}"
891   [(set_attr "type" "icmp")
892    (set_attr "mode" "SI")])
893
894 (define_expand "cmpsi_1"
895   [(set (reg:CC FLAGS_REG)
896         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
897                     (match_operand:SI 1 "general_operand" "")))]
898   ""
899   "")
900
901 (define_insn "*cmpsi_1_insn"
902   [(set (reg FLAGS_REG)
903         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
904                  (match_operand:SI 1 "general_operand" "ri,mr")))]
905   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
906     && ix86_match_ccmode (insn, CCmode)"
907   "cmp{l}\t{%1, %0|%0, %1}"
908   [(set_attr "type" "icmp")
909    (set_attr "mode" "SI")])
910
911 (define_insn "*cmphi_ccno_1"
912   [(set (reg FLAGS_REG)
913         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
914                  (match_operand:HI 1 "const0_operand" "")))]
915   "ix86_match_ccmode (insn, CCNOmode)"
916   "@
917    test{w}\t%0, %0
918    cmp{w}\t{%1, %0|%0, %1}"
919   [(set_attr "type" "test,icmp")
920    (set_attr "length_immediate" "0,1")
921    (set_attr "mode" "HI")])
922
923 (define_insn "*cmphi_minus_1"
924   [(set (reg FLAGS_REG)
925         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
926                            (match_operand:HI 1 "general_operand" "rn,mr"))
927                  (const_int 0)))]
928   "ix86_match_ccmode (insn, CCGOCmode)"
929   "cmp{w}\t{%1, %0|%0, %1}"
930   [(set_attr "type" "icmp")
931    (set_attr "mode" "HI")])
932
933 (define_insn "*cmphi_1"
934   [(set (reg FLAGS_REG)
935         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
936                  (match_operand:HI 1 "general_operand" "rn,mr")))]
937   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
938    && ix86_match_ccmode (insn, CCmode)"
939   "cmp{w}\t{%1, %0|%0, %1}"
940   [(set_attr "type" "icmp")
941    (set_attr "mode" "HI")])
942
943 (define_insn "*cmpqi_ccno_1"
944   [(set (reg FLAGS_REG)
945         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
946                  (match_operand:QI 1 "const0_operand" "")))]
947   "ix86_match_ccmode (insn, CCNOmode)"
948   "@
949    test{b}\t%0, %0
950    cmp{b}\t{$0, %0|%0, 0}"
951   [(set_attr "type" "test,icmp")
952    (set_attr "length_immediate" "0,1")
953    (set_attr "mode" "QI")])
954
955 (define_insn "*cmpqi_1"
956   [(set (reg FLAGS_REG)
957         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
958                  (match_operand:QI 1 "general_operand" "qn,mq")))]
959   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
960     && ix86_match_ccmode (insn, CCmode)"
961   "cmp{b}\t{%1, %0|%0, %1}"
962   [(set_attr "type" "icmp")
963    (set_attr "mode" "QI")])
964
965 (define_insn "*cmpqi_minus_1"
966   [(set (reg FLAGS_REG)
967         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
968                            (match_operand:QI 1 "general_operand" "qn,mq"))
969                  (const_int 0)))]
970   "ix86_match_ccmode (insn, CCGOCmode)"
971   "cmp{b}\t{%1, %0|%0, %1}"
972   [(set_attr "type" "icmp")
973    (set_attr "mode" "QI")])
974
975 (define_insn "*cmpqi_ext_1"
976   [(set (reg FLAGS_REG)
977         (compare
978           (match_operand:QI 0 "general_operand" "Qm")
979           (subreg:QI
980             (zero_extract:SI
981               (match_operand 1 "ext_register_operand" "Q")
982               (const_int 8)
983               (const_int 8)) 0)))]
984   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
985   "cmp{b}\t{%h1, %0|%0, %h1}"
986   [(set_attr "type" "icmp")
987    (set_attr "mode" "QI")])
988
989 (define_insn "*cmpqi_ext_1_rex64"
990   [(set (reg FLAGS_REG)
991         (compare
992           (match_operand:QI 0 "register_operand" "Q")
993           (subreg:QI
994             (zero_extract:SI
995               (match_operand 1 "ext_register_operand" "Q")
996               (const_int 8)
997               (const_int 8)) 0)))]
998   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
999   "cmp{b}\t{%h1, %0|%0, %h1}"
1000   [(set_attr "type" "icmp")
1001    (set_attr "mode" "QI")])
1002
1003 (define_insn "*cmpqi_ext_2"
1004   [(set (reg FLAGS_REG)
1005         (compare
1006           (subreg:QI
1007             (zero_extract:SI
1008               (match_operand 0 "ext_register_operand" "Q")
1009               (const_int 8)
1010               (const_int 8)) 0)
1011           (match_operand:QI 1 "const0_operand" "")))]
1012   "ix86_match_ccmode (insn, CCNOmode)"
1013   "test{b}\t%h0, %h0"
1014   [(set_attr "type" "test")
1015    (set_attr "length_immediate" "0")
1016    (set_attr "mode" "QI")])
1017
1018 (define_expand "cmpqi_ext_3"
1019   [(set (reg:CC FLAGS_REG)
1020         (compare:CC
1021           (subreg:QI
1022             (zero_extract:SI
1023               (match_operand 0 "ext_register_operand" "")
1024               (const_int 8)
1025               (const_int 8)) 0)
1026           (match_operand:QI 1 "general_operand" "")))]
1027   ""
1028   "")
1029
1030 (define_insn "cmpqi_ext_3_insn"
1031   [(set (reg FLAGS_REG)
1032         (compare
1033           (subreg:QI
1034             (zero_extract:SI
1035               (match_operand 0 "ext_register_operand" "Q")
1036               (const_int 8)
1037               (const_int 8)) 0)
1038           (match_operand:QI 1 "general_operand" "Qmn")))]
1039   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1040   "cmp{b}\t{%1, %h0|%h0, %1}"
1041   [(set_attr "type" "icmp")
1042    (set_attr "mode" "QI")])
1043
1044 (define_insn "cmpqi_ext_3_insn_rex64"
1045   [(set (reg FLAGS_REG)
1046         (compare
1047           (subreg:QI
1048             (zero_extract:SI
1049               (match_operand 0 "ext_register_operand" "Q")
1050               (const_int 8)
1051               (const_int 8)) 0)
1052           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1053   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1054   "cmp{b}\t{%1, %h0|%h0, %1}"
1055   [(set_attr "type" "icmp")
1056    (set_attr "mode" "QI")])
1057
1058 (define_insn "*cmpqi_ext_4"
1059   [(set (reg FLAGS_REG)
1060         (compare
1061           (subreg:QI
1062             (zero_extract:SI
1063               (match_operand 0 "ext_register_operand" "Q")
1064               (const_int 8)
1065               (const_int 8)) 0)
1066           (subreg:QI
1067             (zero_extract:SI
1068               (match_operand 1 "ext_register_operand" "Q")
1069               (const_int 8)
1070               (const_int 8)) 0)))]
1071   "ix86_match_ccmode (insn, CCmode)"
1072   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1073   [(set_attr "type" "icmp")
1074    (set_attr "mode" "QI")])
1075
1076 ;; These implement float point compares.
1077 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1078 ;; which would allow mix and match FP modes on the compares.  Which is what
1079 ;; the old patterns did, but with many more of them.
1080
1081 (define_expand "cmpxf"
1082   [(set (reg:CC FLAGS_REG)
1083         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1084                     (match_operand:XF 1 "nonmemory_operand" "")))]
1085   "TARGET_80387"
1086 {
1087   ix86_compare_op0 = operands[0];
1088   ix86_compare_op1 = operands[1];
1089   DONE;
1090 })
1091
1092 (define_expand "cmp<mode>"
1093   [(set (reg:CC FLAGS_REG)
1094         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1095                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1096   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1097 {
1098   ix86_compare_op0 = operands[0];
1099   ix86_compare_op1 = operands[1];
1100   DONE;
1101 })
1102
1103 (define_expand "cmpcc"
1104   [(set (reg:CC FLAGS_REG)
1105         (compare:CC (match_operand 0 "flags_reg_operand" "")
1106                     (match_operand 1 "general_operand" "")))]
1107   ""
1108 {
1109   ix86_compare_op0 = operands[0];
1110   ix86_compare_op1 = operands[1];
1111   DONE;
1112 })
1113
1114 ;; FP compares, step 1:
1115 ;; Set the FP condition codes.
1116 ;;
1117 ;; CCFPmode     compare with exceptions
1118 ;; CCFPUmode    compare with no exceptions
1119
1120 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1121 ;; used to manage the reg stack popping would not be preserved.
1122
1123 (define_insn "*cmpfp_0"
1124   [(set (match_operand:HI 0 "register_operand" "=a")
1125         (unspec:HI
1126           [(compare:CCFP
1127              (match_operand 1 "register_operand" "f")
1128              (match_operand 2 "const0_operand" ""))]
1129         UNSPEC_FNSTSW))]
1130   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1131    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1132   "* return output_fp_compare (insn, operands, 0, 0);"
1133   [(set_attr "type" "multi")
1134    (set_attr "unit" "i387")
1135    (set (attr "mode")
1136      (cond [(match_operand:SF 1 "" "")
1137               (const_string "SF")
1138             (match_operand:DF 1 "" "")
1139               (const_string "DF")
1140            ]
1141            (const_string "XF")))])
1142
1143 (define_insn_and_split "*cmpfp_0_cc"
1144   [(set (reg:CCFP FLAGS_REG)
1145         (compare:CCFP
1146           (match_operand 1 "register_operand" "f")
1147           (match_operand 2 "const0_operand" "")))
1148    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1149   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1150    && TARGET_SAHF && !TARGET_CMOVE
1151    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1152   "#"
1153   "&& reload_completed"
1154   [(set (match_dup 0)
1155         (unspec:HI
1156           [(compare:CCFP (match_dup 1)(match_dup 2))]
1157         UNSPEC_FNSTSW))
1158    (set (reg:CC FLAGS_REG)
1159         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1160   ""
1161   [(set_attr "type" "multi")
1162    (set_attr "unit" "i387")
1163    (set (attr "mode")
1164      (cond [(match_operand:SF 1 "" "")
1165               (const_string "SF")
1166             (match_operand:DF 1 "" "")
1167               (const_string "DF")
1168            ]
1169            (const_string "XF")))])
1170
1171 (define_insn "*cmpfp_xf"
1172   [(set (match_operand:HI 0 "register_operand" "=a")
1173         (unspec:HI
1174           [(compare:CCFP
1175              (match_operand:XF 1 "register_operand" "f")
1176              (match_operand:XF 2 "register_operand" "f"))]
1177           UNSPEC_FNSTSW))]
1178   "TARGET_80387"
1179   "* return output_fp_compare (insn, operands, 0, 0);"
1180   [(set_attr "type" "multi")
1181    (set_attr "unit" "i387")
1182    (set_attr "mode" "XF")])
1183
1184 (define_insn_and_split "*cmpfp_xf_cc"
1185   [(set (reg:CCFP FLAGS_REG)
1186         (compare:CCFP
1187           (match_operand:XF 1 "register_operand" "f")
1188           (match_operand:XF 2 "register_operand" "f")))
1189    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1190   "TARGET_80387
1191    && TARGET_SAHF && !TARGET_CMOVE"
1192   "#"
1193   "&& reload_completed"
1194   [(set (match_dup 0)
1195         (unspec:HI
1196           [(compare:CCFP (match_dup 1)(match_dup 2))]
1197         UNSPEC_FNSTSW))
1198    (set (reg:CC FLAGS_REG)
1199         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1200   ""
1201   [(set_attr "type" "multi")
1202    (set_attr "unit" "i387")
1203    (set_attr "mode" "XF")])
1204
1205 (define_insn "*cmpfp_<mode>"
1206   [(set (match_operand:HI 0 "register_operand" "=a")
1207         (unspec:HI
1208           [(compare:CCFP
1209              (match_operand:MODEF 1 "register_operand" "f")
1210              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1211           UNSPEC_FNSTSW))]
1212   "TARGET_80387"
1213   "* return output_fp_compare (insn, operands, 0, 0);"
1214   [(set_attr "type" "multi")
1215    (set_attr "unit" "i387")
1216    (set_attr "mode" "<MODE>")])
1217
1218 (define_insn_and_split "*cmpfp_<mode>_cc"
1219   [(set (reg:CCFP FLAGS_REG)
1220         (compare:CCFP
1221           (match_operand:MODEF 1 "register_operand" "f")
1222           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1223    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1224   "TARGET_80387
1225    && TARGET_SAHF && !TARGET_CMOVE"
1226   "#"
1227   "&& reload_completed"
1228   [(set (match_dup 0)
1229         (unspec:HI
1230           [(compare:CCFP (match_dup 1)(match_dup 2))]
1231         UNSPEC_FNSTSW))
1232    (set (reg:CC FLAGS_REG)
1233         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1234   ""
1235   [(set_attr "type" "multi")
1236    (set_attr "unit" "i387")
1237    (set_attr "mode" "<MODE>")])
1238
1239 (define_insn "*cmpfp_u"
1240   [(set (match_operand:HI 0 "register_operand" "=a")
1241         (unspec:HI
1242           [(compare:CCFPU
1243              (match_operand 1 "register_operand" "f")
1244              (match_operand 2 "register_operand" "f"))]
1245           UNSPEC_FNSTSW))]
1246   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1247    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1248   "* return output_fp_compare (insn, operands, 0, 1);"
1249   [(set_attr "type" "multi")
1250    (set_attr "unit" "i387")
1251    (set (attr "mode")
1252      (cond [(match_operand:SF 1 "" "")
1253               (const_string "SF")
1254             (match_operand:DF 1 "" "")
1255               (const_string "DF")
1256            ]
1257            (const_string "XF")))])
1258
1259 (define_insn_and_split "*cmpfp_u_cc"
1260   [(set (reg:CCFPU FLAGS_REG)
1261         (compare:CCFPU
1262           (match_operand 1 "register_operand" "f")
1263           (match_operand 2 "register_operand" "f")))
1264    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1265   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1266    && TARGET_SAHF && !TARGET_CMOVE
1267    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1268   "#"
1269   "&& reload_completed"
1270   [(set (match_dup 0)
1271         (unspec:HI
1272           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1273         UNSPEC_FNSTSW))
1274    (set (reg:CC FLAGS_REG)
1275         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1276   ""
1277   [(set_attr "type" "multi")
1278    (set_attr "unit" "i387")
1279    (set (attr "mode")
1280      (cond [(match_operand:SF 1 "" "")
1281               (const_string "SF")
1282             (match_operand:DF 1 "" "")
1283               (const_string "DF")
1284            ]
1285            (const_string "XF")))])
1286
1287 (define_insn "*cmpfp_<mode>"
1288   [(set (match_operand:HI 0 "register_operand" "=a")
1289         (unspec:HI
1290           [(compare:CCFP
1291              (match_operand 1 "register_operand" "f")
1292              (match_operator 3 "float_operator"
1293                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1294           UNSPEC_FNSTSW))]
1295   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1296    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1297    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1298   "* return output_fp_compare (insn, operands, 0, 0);"
1299   [(set_attr "type" "multi")
1300    (set_attr "unit" "i387")
1301    (set_attr "fp_int_src" "true")
1302    (set_attr "mode" "<MODE>")])
1303
1304 (define_insn_and_split "*cmpfp_<mode>_cc"
1305   [(set (reg:CCFP FLAGS_REG)
1306         (compare:CCFP
1307           (match_operand 1 "register_operand" "f")
1308           (match_operator 3 "float_operator"
1309             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1310    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1311   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1312    && TARGET_SAHF && !TARGET_CMOVE
1313    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1314    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1315   "#"
1316   "&& reload_completed"
1317   [(set (match_dup 0)
1318         (unspec:HI
1319           [(compare:CCFP
1320              (match_dup 1)
1321              (match_op_dup 3 [(match_dup 2)]))]
1322         UNSPEC_FNSTSW))
1323    (set (reg:CC FLAGS_REG)
1324         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1325   ""
1326   [(set_attr "type" "multi")
1327    (set_attr "unit" "i387")
1328    (set_attr "fp_int_src" "true")
1329    (set_attr "mode" "<MODE>")])
1330
1331 ;; FP compares, step 2
1332 ;; Move the fpsw to ax.
1333
1334 (define_insn "x86_fnstsw_1"
1335   [(set (match_operand:HI 0 "register_operand" "=a")
1336         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1337   "TARGET_80387"
1338   "fnstsw\t%0"
1339   [(set_attr "length" "2")
1340    (set_attr "mode" "SI")
1341    (set_attr "unit" "i387")])
1342
1343 ;; FP compares, step 3
1344 ;; Get ax into flags, general case.
1345
1346 (define_insn "x86_sahf_1"
1347   [(set (reg:CC FLAGS_REG)
1348         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1349                    UNSPEC_SAHF))]
1350   "TARGET_SAHF"
1351 {
1352 #ifdef HAVE_AS_IX86_SAHF
1353   return "sahf";
1354 #else
1355   return ".byte\t0x9e";
1356 #endif
1357 }
1358   [(set_attr "length" "1")
1359    (set_attr "athlon_decode" "vector")
1360    (set_attr "amdfam10_decode" "direct")
1361    (set_attr "mode" "SI")])
1362
1363 ;; Pentium Pro can do steps 1 through 3 in one go.
1364 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1365 (define_insn "*cmpfp_i_mixed"
1366   [(set (reg:CCFP FLAGS_REG)
1367         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1368                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1369   "TARGET_MIX_SSE_I387
1370    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1371    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372   "* return output_fp_compare (insn, operands, 1, 0);"
1373   [(set_attr "type" "fcmp,ssecomi")
1374    (set_attr "prefix" "orig,maybe_vex")
1375    (set (attr "mode")
1376      (if_then_else (match_operand:SF 1 "" "")
1377         (const_string "SF")
1378         (const_string "DF")))
1379    (set_attr "athlon_decode" "vector")
1380    (set_attr "amdfam10_decode" "direct")])
1381
1382 (define_insn "*cmpfp_i_sse"
1383   [(set (reg:CCFP FLAGS_REG)
1384         (compare:CCFP (match_operand 0 "register_operand" "x")
1385                       (match_operand 1 "nonimmediate_operand" "xm")))]
1386   "TARGET_SSE_MATH
1387    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1388    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1389   "* return output_fp_compare (insn, operands, 1, 0);"
1390   [(set_attr "type" "ssecomi")
1391    (set_attr "prefix" "maybe_vex")
1392    (set (attr "mode")
1393      (if_then_else (match_operand:SF 1 "" "")
1394         (const_string "SF")
1395         (const_string "DF")))
1396    (set_attr "athlon_decode" "vector")
1397    (set_attr "amdfam10_decode" "direct")])
1398
1399 (define_insn "*cmpfp_i_i387"
1400   [(set (reg:CCFP FLAGS_REG)
1401         (compare:CCFP (match_operand 0 "register_operand" "f")
1402                       (match_operand 1 "register_operand" "f")))]
1403   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1404    && TARGET_CMOVE
1405    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1406    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1407   "* return output_fp_compare (insn, operands, 1, 0);"
1408   [(set_attr "type" "fcmp")
1409    (set (attr "mode")
1410      (cond [(match_operand:SF 1 "" "")
1411               (const_string "SF")
1412             (match_operand:DF 1 "" "")
1413               (const_string "DF")
1414            ]
1415            (const_string "XF")))
1416    (set_attr "athlon_decode" "vector")
1417    (set_attr "amdfam10_decode" "direct")])
1418
1419 (define_insn "*cmpfp_iu_mixed"
1420   [(set (reg:CCFPU FLAGS_REG)
1421         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1422                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1423   "TARGET_MIX_SSE_I387
1424    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1425    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1426   "* return output_fp_compare (insn, operands, 1, 1);"
1427   [(set_attr "type" "fcmp,ssecomi")
1428    (set_attr "prefix" "orig,maybe_vex")
1429    (set (attr "mode")
1430      (if_then_else (match_operand:SF 1 "" "")
1431         (const_string "SF")
1432         (const_string "DF")))
1433    (set_attr "athlon_decode" "vector")
1434    (set_attr "amdfam10_decode" "direct")])
1435
1436 (define_insn "*cmpfp_iu_sse"
1437   [(set (reg:CCFPU FLAGS_REG)
1438         (compare:CCFPU (match_operand 0 "register_operand" "x")
1439                        (match_operand 1 "nonimmediate_operand" "xm")))]
1440   "TARGET_SSE_MATH
1441    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1442    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1443   "* return output_fp_compare (insn, operands, 1, 1);"
1444   [(set_attr "type" "ssecomi")
1445    (set_attr "prefix" "maybe_vex")
1446    (set (attr "mode")
1447      (if_then_else (match_operand:SF 1 "" "")
1448         (const_string "SF")
1449         (const_string "DF")))
1450    (set_attr "athlon_decode" "vector")
1451    (set_attr "amdfam10_decode" "direct")])
1452
1453 (define_insn "*cmpfp_iu_387"
1454   [(set (reg:CCFPU FLAGS_REG)
1455         (compare:CCFPU (match_operand 0 "register_operand" "f")
1456                        (match_operand 1 "register_operand" "f")))]
1457   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1458    && TARGET_CMOVE
1459    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1460    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1461   "* return output_fp_compare (insn, operands, 1, 1);"
1462   [(set_attr "type" "fcmp")
1463    (set (attr "mode")
1464      (cond [(match_operand:SF 1 "" "")
1465               (const_string "SF")
1466             (match_operand:DF 1 "" "")
1467               (const_string "DF")
1468            ]
1469            (const_string "XF")))
1470    (set_attr "athlon_decode" "vector")
1471    (set_attr "amdfam10_decode" "direct")])
1472 \f
1473 ;; Move instructions.
1474
1475 ;; General case of fullword move.
1476
1477 (define_expand "movsi"
1478   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1479         (match_operand:SI 1 "general_operand" ""))]
1480   ""
1481   "ix86_expand_move (SImode, operands); DONE;")
1482
1483 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1484 ;; general_operand.
1485 ;;
1486 ;; %%% We don't use a post-inc memory reference because x86 is not a
1487 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1488 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1489 ;; targets without our curiosities, and it is just as easy to represent
1490 ;; this differently.
1491
1492 (define_insn "*pushsi2"
1493   [(set (match_operand:SI 0 "push_operand" "=<")
1494         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1495   "!TARGET_64BIT"
1496   "push{l}\t%1"
1497   [(set_attr "type" "push")
1498    (set_attr "mode" "SI")])
1499
1500 ;; For 64BIT abi we always round up to 8 bytes.
1501 (define_insn "*pushsi2_rex64"
1502   [(set (match_operand:SI 0 "push_operand" "=X")
1503         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1504   "TARGET_64BIT"
1505   "push{q}\t%q1"
1506   [(set_attr "type" "push")
1507    (set_attr "mode" "SI")])
1508
1509 (define_insn "*pushsi2_prologue"
1510   [(set (match_operand:SI 0 "push_operand" "=<")
1511         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1512    (clobber (mem:BLK (scratch)))]
1513   "!TARGET_64BIT"
1514   "push{l}\t%1"
1515   [(set_attr "type" "push")
1516    (set_attr "mode" "SI")])
1517
1518 (define_insn "*popsi1_epilogue"
1519   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1520         (mem:SI (reg:SI SP_REG)))
1521    (set (reg:SI SP_REG)
1522         (plus:SI (reg:SI SP_REG) (const_int 4)))
1523    (clobber (mem:BLK (scratch)))]
1524   "!TARGET_64BIT"
1525   "pop{l}\t%0"
1526   [(set_attr "type" "pop")
1527    (set_attr "mode" "SI")])
1528
1529 (define_insn "popsi1"
1530   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1531         (mem:SI (reg:SI SP_REG)))
1532    (set (reg:SI SP_REG)
1533         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1534   "!TARGET_64BIT"
1535   "pop{l}\t%0"
1536   [(set_attr "type" "pop")
1537    (set_attr "mode" "SI")])
1538
1539 (define_insn "*movsi_xor"
1540   [(set (match_operand:SI 0 "register_operand" "=r")
1541         (match_operand:SI 1 "const0_operand" ""))
1542    (clobber (reg:CC FLAGS_REG))]
1543   "reload_completed"
1544   "xor{l}\t%0, %0"
1545   [(set_attr "type" "alu1")
1546    (set_attr "mode" "SI")
1547    (set_attr "length_immediate" "0")])
1548
1549 (define_insn "*movsi_or"
1550   [(set (match_operand:SI 0 "register_operand" "=r")
1551         (match_operand:SI 1 "immediate_operand" "i"))
1552    (clobber (reg:CC FLAGS_REG))]
1553   "reload_completed
1554    && operands[1] == constm1_rtx"
1555 {
1556   operands[1] = constm1_rtx;
1557   return "or{l}\t{%1, %0|%0, %1}";
1558 }
1559   [(set_attr "type" "alu1")
1560    (set_attr "mode" "SI")
1561    (set_attr "length_immediate" "1")])
1562
1563 (define_insn "*movsi_1"
1564   [(set (match_operand:SI 0 "nonimmediate_operand"
1565                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1566         (match_operand:SI 1 "general_operand"
1567                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1568   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1569 {
1570   switch (get_attr_type (insn))
1571     {
1572     case TYPE_SSELOG1:
1573       if (get_attr_mode (insn) == MODE_TI)
1574         return "%vpxor\t%0, %d0";
1575       return "%vxorps\t%0, %d0";
1576
1577     case TYPE_SSEMOV:
1578       switch (get_attr_mode (insn))
1579         {
1580         case MODE_TI:
1581           return "%vmovdqa\t{%1, %0|%0, %1}";
1582         case MODE_V4SF:
1583           return "%vmovaps\t{%1, %0|%0, %1}";
1584         case MODE_SI:
1585           return "%vmovd\t{%1, %0|%0, %1}";
1586         case MODE_SF:
1587           return "%vmovss\t{%1, %0|%0, %1}";
1588         default:
1589           gcc_unreachable ();
1590         }
1591
1592     case TYPE_MMX:
1593       return "pxor\t%0, %0";
1594
1595     case TYPE_MMXMOV:
1596       if (get_attr_mode (insn) == MODE_DI)
1597         return "movq\t{%1, %0|%0, %1}";
1598       return "movd\t{%1, %0|%0, %1}";
1599
1600     case TYPE_LEA:
1601       return "lea{l}\t{%1, %0|%0, %1}";
1602
1603     default:
1604       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1605       return "mov{l}\t{%1, %0|%0, %1}";
1606     }
1607 }
1608   [(set (attr "type")
1609      (cond [(eq_attr "alternative" "2")
1610               (const_string "mmx")
1611             (eq_attr "alternative" "3,4,5")
1612               (const_string "mmxmov")
1613             (eq_attr "alternative" "6")
1614               (const_string "sselog1")
1615             (eq_attr "alternative" "7,8,9,10,11")
1616               (const_string "ssemov")
1617             (match_operand:DI 1 "pic_32bit_operand" "")
1618               (const_string "lea")
1619            ]
1620            (const_string "imov")))
1621    (set (attr "prefix")
1622      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1623        (const_string "orig")
1624        (const_string "maybe_vex")))
1625    (set (attr "mode")
1626      (cond [(eq_attr "alternative" "2,3")
1627               (const_string "DI")
1628             (eq_attr "alternative" "6,7")
1629               (if_then_else
1630                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1631                 (const_string "V4SF")
1632                 (const_string "TI"))
1633             (and (eq_attr "alternative" "8,9,10,11")
1634                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1635               (const_string "SF")
1636            ]
1637            (const_string "SI")))])
1638
1639 ;; Stores and loads of ax to arbitrary constant address.
1640 ;; We fake an second form of instruction to force reload to load address
1641 ;; into register when rax is not available
1642 (define_insn "*movabssi_1_rex64"
1643   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1644         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1645   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1646   "@
1647    movabs{l}\t{%1, %P0|%P0, %1}
1648    mov{l}\t{%1, %a0|%a0, %1}"
1649   [(set_attr "type" "imov")
1650    (set_attr "modrm" "0,*")
1651    (set_attr "length_address" "8,0")
1652    (set_attr "length_immediate" "0,*")
1653    (set_attr "memory" "store")
1654    (set_attr "mode" "SI")])
1655
1656 (define_insn "*movabssi_2_rex64"
1657   [(set (match_operand:SI 0 "register_operand" "=a,r")
1658         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1659   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1660   "@
1661    movabs{l}\t{%P1, %0|%0, %P1}
1662    mov{l}\t{%a1, %0|%0, %a1}"
1663   [(set_attr "type" "imov")
1664    (set_attr "modrm" "0,*")
1665    (set_attr "length_address" "8,0")
1666    (set_attr "length_immediate" "0")
1667    (set_attr "memory" "load")
1668    (set_attr "mode" "SI")])
1669
1670 (define_insn "*swapsi"
1671   [(set (match_operand:SI 0 "register_operand" "+r")
1672         (match_operand:SI 1 "register_operand" "+r"))
1673    (set (match_dup 1)
1674         (match_dup 0))]
1675   ""
1676   "xchg{l}\t%1, %0"
1677   [(set_attr "type" "imov")
1678    (set_attr "mode" "SI")
1679    (set_attr "pent_pair" "np")
1680    (set_attr "athlon_decode" "vector")
1681    (set_attr "amdfam10_decode" "double")])
1682
1683 (define_expand "movhi"
1684   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1685         (match_operand:HI 1 "general_operand" ""))]
1686   ""
1687   "ix86_expand_move (HImode, operands); DONE;")
1688
1689 (define_insn "*pushhi2"
1690   [(set (match_operand:HI 0 "push_operand" "=X")
1691         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1692   "!TARGET_64BIT"
1693   "push{l}\t%k1"
1694   [(set_attr "type" "push")
1695    (set_attr "mode" "SI")])
1696
1697 ;; For 64BIT abi we always round up to 8 bytes.
1698 (define_insn "*pushhi2_rex64"
1699   [(set (match_operand:HI 0 "push_operand" "=X")
1700         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1701   "TARGET_64BIT"
1702   "push{q}\t%q1"
1703   [(set_attr "type" "push")
1704    (set_attr "mode" "DI")])
1705
1706 (define_insn "*movhi_1"
1707   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1708         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1709   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1710 {
1711   switch (get_attr_type (insn))
1712     {
1713     case TYPE_IMOVX:
1714       /* movzwl is faster than movw on p2 due to partial word stalls,
1715          though not as fast as an aligned movl.  */
1716       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1717     default:
1718       if (get_attr_mode (insn) == MODE_SI)
1719         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1720       else
1721         return "mov{w}\t{%1, %0|%0, %1}";
1722     }
1723 }
1724   [(set (attr "type")
1725      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1726               (const_string "imov")
1727             (and (eq_attr "alternative" "0")
1728                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1729                           (const_int 0))
1730                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1731                           (const_int 0))))
1732               (const_string "imov")
1733             (and (eq_attr "alternative" "1,2")
1734                  (match_operand:HI 1 "aligned_operand" ""))
1735               (const_string "imov")
1736             (and (ne (symbol_ref "TARGET_MOVX")
1737                      (const_int 0))
1738                  (eq_attr "alternative" "0,2"))
1739               (const_string "imovx")
1740            ]
1741            (const_string "imov")))
1742     (set (attr "mode")
1743       (cond [(eq_attr "type" "imovx")
1744                (const_string "SI")
1745              (and (eq_attr "alternative" "1,2")
1746                   (match_operand:HI 1 "aligned_operand" ""))
1747                (const_string "SI")
1748              (and (eq_attr "alternative" "0")
1749                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1750                            (const_int 0))
1751                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1752                            (const_int 0))))
1753                (const_string "SI")
1754             ]
1755             (const_string "HI")))])
1756
1757 ;; Stores and loads of ax to arbitrary constant address.
1758 ;; We fake an second form of instruction to force reload to load address
1759 ;; into register when rax is not available
1760 (define_insn "*movabshi_1_rex64"
1761   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1762         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1763   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1764   "@
1765    movabs{w}\t{%1, %P0|%P0, %1}
1766    mov{w}\t{%1, %a0|%a0, %1}"
1767   [(set_attr "type" "imov")
1768    (set_attr "modrm" "0,*")
1769    (set_attr "length_address" "8,0")
1770    (set_attr "length_immediate" "0,*")
1771    (set_attr "memory" "store")
1772    (set_attr "mode" "HI")])
1773
1774 (define_insn "*movabshi_2_rex64"
1775   [(set (match_operand:HI 0 "register_operand" "=a,r")
1776         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1777   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1778   "@
1779    movabs{w}\t{%P1, %0|%0, %P1}
1780    mov{w}\t{%a1, %0|%0, %a1}"
1781   [(set_attr "type" "imov")
1782    (set_attr "modrm" "0,*")
1783    (set_attr "length_address" "8,0")
1784    (set_attr "length_immediate" "0")
1785    (set_attr "memory" "load")
1786    (set_attr "mode" "HI")])
1787
1788 (define_insn "*swaphi_1"
1789   [(set (match_operand:HI 0 "register_operand" "+r")
1790         (match_operand:HI 1 "register_operand" "+r"))
1791    (set (match_dup 1)
1792         (match_dup 0))]
1793   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1794   "xchg{l}\t%k1, %k0"
1795   [(set_attr "type" "imov")
1796    (set_attr "mode" "SI")
1797    (set_attr "pent_pair" "np")
1798    (set_attr "athlon_decode" "vector")
1799    (set_attr "amdfam10_decode" "double")])
1800
1801 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1802 (define_insn "*swaphi_2"
1803   [(set (match_operand:HI 0 "register_operand" "+r")
1804         (match_operand:HI 1 "register_operand" "+r"))
1805    (set (match_dup 1)
1806         (match_dup 0))]
1807   "TARGET_PARTIAL_REG_STALL"
1808   "xchg{w}\t%1, %0"
1809   [(set_attr "type" "imov")
1810    (set_attr "mode" "HI")
1811    (set_attr "pent_pair" "np")
1812    (set_attr "athlon_decode" "vector")])
1813
1814 (define_expand "movstricthi"
1815   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1816         (match_operand:HI 1 "general_operand" ""))]
1817   ""
1818 {
1819   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1820     FAIL;
1821   /* Don't generate memory->memory moves, go through a register */
1822   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1823     operands[1] = force_reg (HImode, operands[1]);
1824 })
1825
1826 (define_insn "*movstricthi_1"
1827   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1828         (match_operand:HI 1 "general_operand" "rn,m"))]
1829   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1830    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1831   "mov{w}\t{%1, %0|%0, %1}"
1832   [(set_attr "type" "imov")
1833    (set_attr "mode" "HI")])
1834
1835 (define_insn "*movstricthi_xor"
1836   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1837         (match_operand:HI 1 "const0_operand" ""))
1838    (clobber (reg:CC FLAGS_REG))]
1839   "reload_completed"
1840   "xor{w}\t%0, %0"
1841   [(set_attr "type" "alu1")
1842    (set_attr "mode" "HI")
1843    (set_attr "length_immediate" "0")])
1844
1845 (define_expand "movqi"
1846   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1847         (match_operand:QI 1 "general_operand" ""))]
1848   ""
1849   "ix86_expand_move (QImode, operands); DONE;")
1850
1851 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1852 ;; "push a byte".  But actually we use pushl, which has the effect
1853 ;; of rounding the amount pushed up to a word.
1854
1855 (define_insn "*pushqi2"
1856   [(set (match_operand:QI 0 "push_operand" "=X")
1857         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1858   "!TARGET_64BIT"
1859   "push{l}\t%k1"
1860   [(set_attr "type" "push")
1861    (set_attr "mode" "SI")])
1862
1863 ;; For 64BIT abi we always round up to 8 bytes.
1864 (define_insn "*pushqi2_rex64"
1865   [(set (match_operand:QI 0 "push_operand" "=X")
1866         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1867   "TARGET_64BIT"
1868   "push{q}\t%q1"
1869   [(set_attr "type" "push")
1870    (set_attr "mode" "DI")])
1871
1872 ;; Situation is quite tricky about when to choose full sized (SImode) move
1873 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1874 ;; partial register dependency machines (such as AMD Athlon), where QImode
1875 ;; moves issue extra dependency and for partial register stalls machines
1876 ;; that don't use QImode patterns (and QImode move cause stall on the next
1877 ;; instruction).
1878 ;;
1879 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1880 ;; register stall machines with, where we use QImode instructions, since
1881 ;; partial register stall can be caused there.  Then we use movzx.
1882 (define_insn "*movqi_1"
1883   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1884         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1885   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1886 {
1887   switch (get_attr_type (insn))
1888     {
1889     case TYPE_IMOVX:
1890       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1891       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1892     default:
1893       if (get_attr_mode (insn) == MODE_SI)
1894         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1895       else
1896         return "mov{b}\t{%1, %0|%0, %1}";
1897     }
1898 }
1899   [(set (attr "type")
1900      (cond [(and (eq_attr "alternative" "5")
1901                  (not (match_operand:QI 1 "aligned_operand" "")))
1902               (const_string "imovx")
1903             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1904               (const_string "imov")
1905             (and (eq_attr "alternative" "3")
1906                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1907                           (const_int 0))
1908                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1909                           (const_int 0))))
1910               (const_string "imov")
1911             (eq_attr "alternative" "3,5")
1912               (const_string "imovx")
1913             (and (ne (symbol_ref "TARGET_MOVX")
1914                      (const_int 0))
1915                  (eq_attr "alternative" "2"))
1916               (const_string "imovx")
1917            ]
1918            (const_string "imov")))
1919    (set (attr "mode")
1920       (cond [(eq_attr "alternative" "3,4,5")
1921                (const_string "SI")
1922              (eq_attr "alternative" "6")
1923                (const_string "QI")
1924              (eq_attr "type" "imovx")
1925                (const_string "SI")
1926              (and (eq_attr "type" "imov")
1927                   (and (eq_attr "alternative" "0,1")
1928                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1929                                 (const_int 0))
1930                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1931                                      (const_int 0))
1932                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1933                                      (const_int 0))))))
1934                (const_string "SI")
1935              ;; Avoid partial register stalls when not using QImode arithmetic
1936              (and (eq_attr "type" "imov")
1937                   (and (eq_attr "alternative" "0,1")
1938                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1939                                 (const_int 0))
1940                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1941                                 (const_int 0)))))
1942                (const_string "SI")
1943            ]
1944            (const_string "QI")))])
1945
1946 (define_insn "*swapqi_1"
1947   [(set (match_operand:QI 0 "register_operand" "+r")
1948         (match_operand:QI 1 "register_operand" "+r"))
1949    (set (match_dup 1)
1950         (match_dup 0))]
1951   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1952   "xchg{l}\t%k1, %k0"
1953   [(set_attr "type" "imov")
1954    (set_attr "mode" "SI")
1955    (set_attr "pent_pair" "np")
1956    (set_attr "athlon_decode" "vector")
1957    (set_attr "amdfam10_decode" "vector")])
1958
1959 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1960 (define_insn "*swapqi_2"
1961   [(set (match_operand:QI 0 "register_operand" "+q")
1962         (match_operand:QI 1 "register_operand" "+q"))
1963    (set (match_dup 1)
1964         (match_dup 0))]
1965   "TARGET_PARTIAL_REG_STALL"
1966   "xchg{b}\t%1, %0"
1967   [(set_attr "type" "imov")
1968    (set_attr "mode" "QI")
1969    (set_attr "pent_pair" "np")
1970    (set_attr "athlon_decode" "vector")])
1971
1972 (define_expand "movstrictqi"
1973   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1974         (match_operand:QI 1 "general_operand" ""))]
1975   ""
1976 {
1977   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1978     FAIL;
1979   /* Don't generate memory->memory moves, go through a register.  */
1980   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1981     operands[1] = force_reg (QImode, operands[1]);
1982 })
1983
1984 (define_insn "*movstrictqi_1"
1985   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1986         (match_operand:QI 1 "general_operand" "*qn,m"))]
1987   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1988    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1989   "mov{b}\t{%1, %0|%0, %1}"
1990   [(set_attr "type" "imov")
1991    (set_attr "mode" "QI")])
1992
1993 (define_insn "*movstrictqi_xor"
1994   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1995         (match_operand:QI 1 "const0_operand" ""))
1996    (clobber (reg:CC FLAGS_REG))]
1997   "reload_completed"
1998   "xor{b}\t%0, %0"
1999   [(set_attr "type" "alu1")
2000    (set_attr "mode" "QI")
2001    (set_attr "length_immediate" "0")])
2002
2003 (define_insn "*movsi_extv_1"
2004   [(set (match_operand:SI 0 "register_operand" "=R")
2005         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2006                          (const_int 8)
2007                          (const_int 8)))]
2008   ""
2009   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2010   [(set_attr "type" "imovx")
2011    (set_attr "mode" "SI")])
2012
2013 (define_insn "*movhi_extv_1"
2014   [(set (match_operand:HI 0 "register_operand" "=R")
2015         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2016                          (const_int 8)
2017                          (const_int 8)))]
2018   ""
2019   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2020   [(set_attr "type" "imovx")
2021    (set_attr "mode" "SI")])
2022
2023 (define_insn "*movqi_extv_1"
2024   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2025         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2026                          (const_int 8)
2027                          (const_int 8)))]
2028   "!TARGET_64BIT"
2029 {
2030   switch (get_attr_type (insn))
2031     {
2032     case TYPE_IMOVX:
2033       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2034     default:
2035       return "mov{b}\t{%h1, %0|%0, %h1}";
2036     }
2037 }
2038   [(set (attr "type")
2039      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2040                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2041                              (ne (symbol_ref "TARGET_MOVX")
2042                                  (const_int 0))))
2043         (const_string "imovx")
2044         (const_string "imov")))
2045    (set (attr "mode")
2046      (if_then_else (eq_attr "type" "imovx")
2047         (const_string "SI")
2048         (const_string "QI")))])
2049
2050 (define_insn "*movqi_extv_1_rex64"
2051   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2052         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2053                          (const_int 8)
2054                          (const_int 8)))]
2055   "TARGET_64BIT"
2056 {
2057   switch (get_attr_type (insn))
2058     {
2059     case TYPE_IMOVX:
2060       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2061     default:
2062       return "mov{b}\t{%h1, %0|%0, %h1}";
2063     }
2064 }
2065   [(set (attr "type")
2066      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2067                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2068                              (ne (symbol_ref "TARGET_MOVX")
2069                                  (const_int 0))))
2070         (const_string "imovx")
2071         (const_string "imov")))
2072    (set (attr "mode")
2073      (if_then_else (eq_attr "type" "imovx")
2074         (const_string "SI")
2075         (const_string "QI")))])
2076
2077 ;; Stores and loads of ax to arbitrary constant address.
2078 ;; We fake an second form of instruction to force reload to load address
2079 ;; into register when rax is not available
2080 (define_insn "*movabsqi_1_rex64"
2081   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2082         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2083   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2084   "@
2085    movabs{b}\t{%1, %P0|%P0, %1}
2086    mov{b}\t{%1, %a0|%a0, %1}"
2087   [(set_attr "type" "imov")
2088    (set_attr "modrm" "0,*")
2089    (set_attr "length_address" "8,0")
2090    (set_attr "length_immediate" "0,*")
2091    (set_attr "memory" "store")
2092    (set_attr "mode" "QI")])
2093
2094 (define_insn "*movabsqi_2_rex64"
2095   [(set (match_operand:QI 0 "register_operand" "=a,r")
2096         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2097   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2098   "@
2099    movabs{b}\t{%P1, %0|%0, %P1}
2100    mov{b}\t{%a1, %0|%0, %a1}"
2101   [(set_attr "type" "imov")
2102    (set_attr "modrm" "0,*")
2103    (set_attr "length_address" "8,0")
2104    (set_attr "length_immediate" "0")
2105    (set_attr "memory" "load")
2106    (set_attr "mode" "QI")])
2107
2108 (define_insn "*movdi_extzv_1"
2109   [(set (match_operand:DI 0 "register_operand" "=R")
2110         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2111                          (const_int 8)
2112                          (const_int 8)))]
2113   "TARGET_64BIT"
2114   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2115   [(set_attr "type" "imovx")
2116    (set_attr "mode" "DI")])
2117
2118 (define_insn "*movsi_extzv_1"
2119   [(set (match_operand:SI 0 "register_operand" "=R")
2120         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2121                          (const_int 8)
2122                          (const_int 8)))]
2123   ""
2124   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2125   [(set_attr "type" "imovx")
2126    (set_attr "mode" "SI")])
2127
2128 (define_insn "*movqi_extzv_2"
2129   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2130         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2131                                     (const_int 8)
2132                                     (const_int 8)) 0))]
2133   "!TARGET_64BIT"
2134 {
2135   switch (get_attr_type (insn))
2136     {
2137     case TYPE_IMOVX:
2138       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2139     default:
2140       return "mov{b}\t{%h1, %0|%0, %h1}";
2141     }
2142 }
2143   [(set (attr "type")
2144      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2145                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2146                              (ne (symbol_ref "TARGET_MOVX")
2147                                  (const_int 0))))
2148         (const_string "imovx")
2149         (const_string "imov")))
2150    (set (attr "mode")
2151      (if_then_else (eq_attr "type" "imovx")
2152         (const_string "SI")
2153         (const_string "QI")))])
2154
2155 (define_insn "*movqi_extzv_2_rex64"
2156   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2157         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2158                                     (const_int 8)
2159                                     (const_int 8)) 0))]
2160   "TARGET_64BIT"
2161 {
2162   switch (get_attr_type (insn))
2163     {
2164     case TYPE_IMOVX:
2165       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2166     default:
2167       return "mov{b}\t{%h1, %0|%0, %h1}";
2168     }
2169 }
2170   [(set (attr "type")
2171      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2172                         (ne (symbol_ref "TARGET_MOVX")
2173                             (const_int 0)))
2174         (const_string "imovx")
2175         (const_string "imov")))
2176    (set (attr "mode")
2177      (if_then_else (eq_attr "type" "imovx")
2178         (const_string "SI")
2179         (const_string "QI")))])
2180
2181 (define_insn "movsi_insv_1"
2182   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2183                          (const_int 8)
2184                          (const_int 8))
2185         (match_operand:SI 1 "general_operand" "Qmn"))]
2186   "!TARGET_64BIT"
2187   "mov{b}\t{%b1, %h0|%h0, %b1}"
2188   [(set_attr "type" "imov")
2189    (set_attr "mode" "QI")])
2190
2191 (define_insn "*movsi_insv_1_rex64"
2192   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2193                          (const_int 8)
2194                          (const_int 8))
2195         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2196   "TARGET_64BIT"
2197   "mov{b}\t{%b1, %h0|%h0, %b1}"
2198   [(set_attr "type" "imov")
2199    (set_attr "mode" "QI")])
2200
2201 (define_insn "movdi_insv_1_rex64"
2202   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2203                          (const_int 8)
2204                          (const_int 8))
2205         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2206   "TARGET_64BIT"
2207   "mov{b}\t{%b1, %h0|%h0, %b1}"
2208   [(set_attr "type" "imov")
2209    (set_attr "mode" "QI")])
2210
2211 (define_insn "*movqi_insv_2"
2212   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2213                          (const_int 8)
2214                          (const_int 8))
2215         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2216                      (const_int 8)))]
2217   ""
2218   "mov{b}\t{%h1, %h0|%h0, %h1}"
2219   [(set_attr "type" "imov")
2220    (set_attr "mode" "QI")])
2221
2222 (define_expand "movdi"
2223   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2224         (match_operand:DI 1 "general_operand" ""))]
2225   ""
2226   "ix86_expand_move (DImode, operands); DONE;")
2227
2228 (define_insn "*pushdi"
2229   [(set (match_operand:DI 0 "push_operand" "=<")
2230         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2231   "!TARGET_64BIT"
2232   "#")
2233
2234 (define_insn "*pushdi2_rex64"
2235   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2236         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2237   "TARGET_64BIT"
2238   "@
2239    push{q}\t%1
2240    #"
2241   [(set_attr "type" "push,multi")
2242    (set_attr "mode" "DI")])
2243
2244 ;; Convert impossible pushes of immediate to existing instructions.
2245 ;; First try to get scratch register and go through it.  In case this
2246 ;; fails, push sign extended lower part first and then overwrite
2247 ;; upper part by 32bit move.
2248 (define_peephole2
2249   [(match_scratch:DI 2 "r")
2250    (set (match_operand:DI 0 "push_operand" "")
2251         (match_operand:DI 1 "immediate_operand" ""))]
2252   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2253    && !x86_64_immediate_operand (operands[1], DImode)"
2254   [(set (match_dup 2) (match_dup 1))
2255    (set (match_dup 0) (match_dup 2))]
2256   "")
2257
2258 ;; We need to define this as both peepholer and splitter for case
2259 ;; peephole2 pass is not run.
2260 ;; "&& 1" is needed to keep it from matching the previous pattern.
2261 (define_peephole2
2262   [(set (match_operand:DI 0 "push_operand" "")
2263         (match_operand:DI 1 "immediate_operand" ""))]
2264   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2265    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2266   [(set (match_dup 0) (match_dup 1))
2267    (set (match_dup 2) (match_dup 3))]
2268   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2269    operands[1] = gen_lowpart (DImode, operands[2]);
2270    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2271                                                     GEN_INT (4)));
2272   ")
2273
2274 (define_split
2275   [(set (match_operand:DI 0 "push_operand" "")
2276         (match_operand:DI 1 "immediate_operand" ""))]
2277   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2278                     ? epilogue_completed : reload_completed)
2279    && !symbolic_operand (operands[1], DImode)
2280    && !x86_64_immediate_operand (operands[1], DImode)"
2281   [(set (match_dup 0) (match_dup 1))
2282    (set (match_dup 2) (match_dup 3))]
2283   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2284    operands[1] = gen_lowpart (DImode, operands[2]);
2285    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2286                                                     GEN_INT (4)));
2287   ")
2288
2289 (define_insn "*pushdi2_prologue_rex64"
2290   [(set (match_operand:DI 0 "push_operand" "=<")
2291         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2292    (clobber (mem:BLK (scratch)))]
2293   "TARGET_64BIT"
2294   "push{q}\t%1"
2295   [(set_attr "type" "push")
2296    (set_attr "mode" "DI")])
2297
2298 (define_insn "*popdi1_epilogue_rex64"
2299   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2300         (mem:DI (reg:DI SP_REG)))
2301    (set (reg:DI SP_REG)
2302         (plus:DI (reg:DI SP_REG) (const_int 8)))
2303    (clobber (mem:BLK (scratch)))]
2304   "TARGET_64BIT"
2305   "pop{q}\t%0"
2306   [(set_attr "type" "pop")
2307    (set_attr "mode" "DI")])
2308
2309 (define_insn "popdi1"
2310   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2311         (mem:DI (reg:DI SP_REG)))
2312    (set (reg:DI SP_REG)
2313         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2314   "TARGET_64BIT"
2315   "pop{q}\t%0"
2316   [(set_attr "type" "pop")
2317    (set_attr "mode" "DI")])
2318
2319 (define_insn "*movdi_xor_rex64"
2320   [(set (match_operand:DI 0 "register_operand" "=r")
2321         (match_operand:DI 1 "const0_operand" ""))
2322    (clobber (reg:CC FLAGS_REG))]
2323   "TARGET_64BIT
2324    && reload_completed"
2325   "xor{l}\t%k0, %k0";
2326   [(set_attr "type" "alu1")
2327    (set_attr "mode" "SI")
2328    (set_attr "length_immediate" "0")])
2329
2330 (define_insn "*movdi_or_rex64"
2331   [(set (match_operand:DI 0 "register_operand" "=r")
2332         (match_operand:DI 1 "const_int_operand" "i"))
2333    (clobber (reg:CC FLAGS_REG))]
2334   "TARGET_64BIT
2335    && reload_completed
2336    && operands[1] == constm1_rtx"
2337 {
2338   operands[1] = constm1_rtx;
2339   return "or{q}\t{%1, %0|%0, %1}";
2340 }
2341   [(set_attr "type" "alu1")
2342    (set_attr "mode" "DI")
2343    (set_attr "length_immediate" "1")])
2344
2345 (define_insn "*movdi_2"
2346   [(set (match_operand:DI 0 "nonimmediate_operand"
2347                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2348         (match_operand:DI 1 "general_operand"
2349                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2350   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2351   "@
2352    #
2353    #
2354    pxor\t%0, %0
2355    movq\t{%1, %0|%0, %1}
2356    movq\t{%1, %0|%0, %1}
2357    %vpxor\t%0, %d0
2358    %vmovq\t{%1, %0|%0, %1}
2359    %vmovdqa\t{%1, %0|%0, %1}
2360    %vmovq\t{%1, %0|%0, %1}
2361    xorps\t%0, %0
2362    movlps\t{%1, %0|%0, %1}
2363    movaps\t{%1, %0|%0, %1}
2364    movlps\t{%1, %0|%0, %1}"
2365   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2366    (set (attr "prefix")
2367      (if_then_else (eq_attr "alternative" "5,6,7,8")
2368        (const_string "vex")
2369        (const_string "orig")))
2370    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2371
2372 (define_split
2373   [(set (match_operand:DI 0 "push_operand" "")
2374         (match_operand:DI 1 "general_operand" ""))]
2375   "!TARGET_64BIT && reload_completed
2376    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2377   [(const_int 0)]
2378   "ix86_split_long_move (operands); DONE;")
2379
2380 ;; %%% This multiword shite has got to go.
2381 (define_split
2382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2383         (match_operand:DI 1 "general_operand" ""))]
2384   "!TARGET_64BIT && reload_completed
2385    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2386    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2387   [(const_int 0)]
2388   "ix86_split_long_move (operands); DONE;")
2389
2390 (define_insn "*movdi_1_rex64"
2391   [(set (match_operand:DI 0 "nonimmediate_operand"
2392           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2393         (match_operand:DI 1 "general_operand"
2394           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2395   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2396 {
2397   switch (get_attr_type (insn))
2398     {
2399     case TYPE_SSECVT:
2400       if (SSE_REG_P (operands[0]))
2401         return "movq2dq\t{%1, %0|%0, %1}";
2402       else
2403         return "movdq2q\t{%1, %0|%0, %1}";
2404
2405     case TYPE_SSEMOV:
2406       if (TARGET_AVX)
2407         {
2408           if (get_attr_mode (insn) == MODE_TI)
2409             return "vmovdqa\t{%1, %0|%0, %1}";
2410           else
2411             return "vmovq\t{%1, %0|%0, %1}";
2412         }
2413
2414       if (get_attr_mode (insn) == MODE_TI)
2415         return "movdqa\t{%1, %0|%0, %1}";
2416       /* FALLTHRU */
2417
2418     case TYPE_MMXMOV:
2419       /* Moves from and into integer register is done using movd
2420          opcode with REX prefix.  */
2421       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2422         return "movd\t{%1, %0|%0, %1}";
2423       return "movq\t{%1, %0|%0, %1}";
2424
2425     case TYPE_SSELOG1:
2426       return "%vpxor\t%0, %d0";
2427
2428     case TYPE_MMX:
2429       return "pxor\t%0, %0";
2430
2431     case TYPE_MULTI:
2432       return "#";
2433
2434     case TYPE_LEA:
2435       return "lea{q}\t{%a1, %0|%0, %a1}";
2436
2437     default:
2438       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2439       if (get_attr_mode (insn) == MODE_SI)
2440         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2441       else if (which_alternative == 2)
2442         return "movabs{q}\t{%1, %0|%0, %1}";
2443       else
2444         return "mov{q}\t{%1, %0|%0, %1}";
2445     }
2446 }
2447   [(set (attr "type")
2448      (cond [(eq_attr "alternative" "5")
2449               (const_string "mmx")
2450             (eq_attr "alternative" "6,7,8,9,10")
2451               (const_string "mmxmov")
2452             (eq_attr "alternative" "11")
2453               (const_string "sselog1")
2454             (eq_attr "alternative" "12,13,14,15,16")
2455               (const_string "ssemov")
2456             (eq_attr "alternative" "17,18")
2457               (const_string "ssecvt")
2458             (eq_attr "alternative" "4")
2459               (const_string "multi")
2460             (match_operand:DI 1 "pic_32bit_operand" "")
2461               (const_string "lea")
2462            ]
2463            (const_string "imov")))
2464    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2465    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2466    (set (attr "prefix")
2467      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2468        (const_string "maybe_vex")
2469        (const_string "orig")))
2470    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2471
2472 ;; Stores and loads of ax to arbitrary constant address.
2473 ;; We fake an second form of instruction to force reload to load address
2474 ;; into register when rax is not available
2475 (define_insn "*movabsdi_1_rex64"
2476   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2477         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2478   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2479   "@
2480    movabs{q}\t{%1, %P0|%P0, %1}
2481    mov{q}\t{%1, %a0|%a0, %1}"
2482   [(set_attr "type" "imov")
2483    (set_attr "modrm" "0,*")
2484    (set_attr "length_address" "8,0")
2485    (set_attr "length_immediate" "0,*")
2486    (set_attr "memory" "store")
2487    (set_attr "mode" "DI")])
2488
2489 (define_insn "*movabsdi_2_rex64"
2490   [(set (match_operand:DI 0 "register_operand" "=a,r")
2491         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2492   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2493   "@
2494    movabs{q}\t{%P1, %0|%0, %P1}
2495    mov{q}\t{%a1, %0|%0, %a1}"
2496   [(set_attr "type" "imov")
2497    (set_attr "modrm" "0,*")
2498    (set_attr "length_address" "8,0")
2499    (set_attr "length_immediate" "0")
2500    (set_attr "memory" "load")
2501    (set_attr "mode" "DI")])
2502
2503 ;; Convert impossible stores of immediate to existing instructions.
2504 ;; First try to get scratch register and go through it.  In case this
2505 ;; fails, move by 32bit parts.
2506 (define_peephole2
2507   [(match_scratch:DI 2 "r")
2508    (set (match_operand:DI 0 "memory_operand" "")
2509         (match_operand:DI 1 "immediate_operand" ""))]
2510   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2511    && !x86_64_immediate_operand (operands[1], DImode)"
2512   [(set (match_dup 2) (match_dup 1))
2513    (set (match_dup 0) (match_dup 2))]
2514   "")
2515
2516 ;; We need to define this as both peepholer and splitter for case
2517 ;; peephole2 pass is not run.
2518 ;; "&& 1" is needed to keep it from matching the previous pattern.
2519 (define_peephole2
2520   [(set (match_operand:DI 0 "memory_operand" "")
2521         (match_operand:DI 1 "immediate_operand" ""))]
2522   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2523    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2524   [(set (match_dup 2) (match_dup 3))
2525    (set (match_dup 4) (match_dup 5))]
2526   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2527
2528 (define_split
2529   [(set (match_operand:DI 0 "memory_operand" "")
2530         (match_operand:DI 1 "immediate_operand" ""))]
2531   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2532                     ? epilogue_completed : reload_completed)
2533    && !symbolic_operand (operands[1], DImode)
2534    && !x86_64_immediate_operand (operands[1], DImode)"
2535   [(set (match_dup 2) (match_dup 3))
2536    (set (match_dup 4) (match_dup 5))]
2537   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2538
2539 (define_insn "*swapdi_rex64"
2540   [(set (match_operand:DI 0 "register_operand" "+r")
2541         (match_operand:DI 1 "register_operand" "+r"))
2542    (set (match_dup 1)
2543         (match_dup 0))]
2544   "TARGET_64BIT"
2545   "xchg{q}\t%1, %0"
2546   [(set_attr "type" "imov")
2547    (set_attr "mode" "DI")
2548    (set_attr "pent_pair" "np")
2549    (set_attr "athlon_decode" "vector")
2550    (set_attr "amdfam10_decode" "double")])
2551
2552 (define_expand "movoi"
2553   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2554         (match_operand:OI 1 "general_operand" ""))]
2555   "TARGET_AVX"
2556   "ix86_expand_move (OImode, operands); DONE;")
2557
2558 (define_insn "*movoi_internal"
2559   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2560         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2561   "TARGET_AVX
2562    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2563 {
2564   switch (which_alternative)
2565     {
2566     case 0:
2567       return "vxorps\t%0, %0, %0";
2568     case 1:
2569     case 2:
2570       if (misaligned_operand (operands[0], OImode)
2571           || misaligned_operand (operands[1], OImode))
2572         return "vmovdqu\t{%1, %0|%0, %1}";
2573       else
2574         return "vmovdqa\t{%1, %0|%0, %1}";
2575     default:
2576       gcc_unreachable ();
2577     }
2578 }
2579   [(set_attr "type" "sselog1,ssemov,ssemov")
2580    (set_attr "prefix" "vex")
2581    (set_attr "mode" "OI")])
2582
2583 (define_expand "movti"
2584   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2585         (match_operand:TI 1 "nonimmediate_operand" ""))]
2586   "TARGET_SSE || TARGET_64BIT"
2587 {
2588   if (TARGET_64BIT)
2589     ix86_expand_move (TImode, operands);
2590   else if (push_operand (operands[0], TImode))
2591     ix86_expand_push (TImode, operands[1]);
2592   else
2593     ix86_expand_vector_move (TImode, operands);
2594   DONE;
2595 })
2596
2597 (define_insn "*movti_internal"
2598   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2599         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2600   "TARGET_SSE && !TARGET_64BIT
2601    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2602 {
2603   switch (which_alternative)
2604     {
2605     case 0:
2606       if (get_attr_mode (insn) == MODE_V4SF)
2607         return "%vxorps\t%0, %d0";
2608       else
2609         return "%vpxor\t%0, %d0";
2610     case 1:
2611     case 2:
2612       /* TDmode values are passed as TImode on the stack.  Moving them
2613          to stack may result in unaligned memory access.  */
2614       if (misaligned_operand (operands[0], TImode)
2615           || misaligned_operand (operands[1], TImode))
2616         {
2617           if (get_attr_mode (insn) == MODE_V4SF)
2618             return "%vmovups\t{%1, %0|%0, %1}";
2619          else
2620            return "%vmovdqu\t{%1, %0|%0, %1}";
2621         }
2622       else
2623         {
2624           if (get_attr_mode (insn) == MODE_V4SF)
2625             return "%vmovaps\t{%1, %0|%0, %1}";
2626          else
2627            return "%vmovdqa\t{%1, %0|%0, %1}";
2628         }
2629     default:
2630       gcc_unreachable ();
2631     }
2632 }
2633   [(set_attr "type" "sselog1,ssemov,ssemov")
2634    (set_attr "prefix" "maybe_vex")
2635    (set (attr "mode")
2636         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2637                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2638                  (const_string "V4SF")
2639                (and (eq_attr "alternative" "2")
2640                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2641                         (const_int 0)))
2642                  (const_string "V4SF")]
2643               (const_string "TI")))])
2644
2645 (define_insn "*movti_rex64"
2646   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2647         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2648   "TARGET_64BIT
2649    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2650 {
2651   switch (which_alternative)
2652     {
2653     case 0:
2654     case 1:
2655       return "#";
2656     case 2:
2657       if (get_attr_mode (insn) == MODE_V4SF)
2658         return "%vxorps\t%0, %d0";
2659       else
2660         return "%vpxor\t%0, %d0";
2661     case 3:
2662     case 4:
2663       /* TDmode values are passed as TImode on the stack.  Moving them
2664          to stack may result in unaligned memory access.  */
2665       if (misaligned_operand (operands[0], TImode)
2666           || misaligned_operand (operands[1], TImode))
2667         {
2668           if (get_attr_mode (insn) == MODE_V4SF)
2669             return "%vmovups\t{%1, %0|%0, %1}";
2670          else
2671            return "%vmovdqu\t{%1, %0|%0, %1}";
2672         }
2673       else
2674         {
2675           if (get_attr_mode (insn) == MODE_V4SF)
2676             return "%vmovaps\t{%1, %0|%0, %1}";
2677          else
2678            return "%vmovdqa\t{%1, %0|%0, %1}";
2679         }
2680     default:
2681       gcc_unreachable ();
2682     }
2683 }
2684   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2685    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2686    (set (attr "mode")
2687         (cond [(eq_attr "alternative" "2,3")
2688                  (if_then_else
2689                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2690                        (const_int 0))
2691                    (const_string "V4SF")
2692                    (const_string "TI"))
2693                (eq_attr "alternative" "4")
2694                  (if_then_else
2695                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2696                             (const_int 0))
2697                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2698                             (const_int 0)))
2699                    (const_string "V4SF")
2700                    (const_string "TI"))]
2701                (const_string "DI")))])
2702
2703 (define_split
2704   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2705         (match_operand:TI 1 "general_operand" ""))]
2706   "reload_completed && !SSE_REG_P (operands[0])
2707    && !SSE_REG_P (operands[1])"
2708   [(const_int 0)]
2709   "ix86_split_long_move (operands); DONE;")
2710
2711 ;; This expands to what emit_move_complex would generate if we didn't
2712 ;; have a movti pattern.  Having this avoids problems with reload on
2713 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2714 ;; to have around all the time.
2715 (define_expand "movcdi"
2716   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2717         (match_operand:CDI 1 "general_operand" ""))]
2718   ""
2719 {
2720   if (push_operand (operands[0], CDImode))
2721     emit_move_complex_push (CDImode, operands[0], operands[1]);
2722   else
2723     emit_move_complex_parts (operands[0], operands[1]);
2724   DONE;
2725 })
2726
2727 (define_expand "movsf"
2728   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2729         (match_operand:SF 1 "general_operand" ""))]
2730   ""
2731   "ix86_expand_move (SFmode, operands); DONE;")
2732
2733 (define_insn "*pushsf"
2734   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2735         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2736   "!TARGET_64BIT"
2737 {
2738   /* Anything else should be already split before reg-stack.  */
2739   gcc_assert (which_alternative == 1);
2740   return "push{l}\t%1";
2741 }
2742   [(set_attr "type" "multi,push,multi")
2743    (set_attr "unit" "i387,*,*")
2744    (set_attr "mode" "SF,SI,SF")])
2745
2746 (define_insn "*pushsf_rex64"
2747   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2749   "TARGET_64BIT"
2750 {
2751   /* Anything else should be already split before reg-stack.  */
2752   gcc_assert (which_alternative == 1);
2753   return "push{q}\t%q1";
2754 }
2755   [(set_attr "type" "multi,push,multi")
2756    (set_attr "unit" "i387,*,*")
2757    (set_attr "mode" "SF,DI,SF")])
2758
2759 (define_split
2760   [(set (match_operand:SF 0 "push_operand" "")
2761         (match_operand:SF 1 "memory_operand" ""))]
2762   "reload_completed
2763    && MEM_P (operands[1])
2764    && (operands[2] = find_constant_src (insn))"
2765   [(set (match_dup 0)
2766         (match_dup 2))])
2767
2768
2769 ;; %%% Kill this when call knows how to work this out.
2770 (define_split
2771   [(set (match_operand:SF 0 "push_operand" "")
2772         (match_operand:SF 1 "any_fp_register_operand" ""))]
2773   "!TARGET_64BIT"
2774   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2775    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2776
2777 (define_split
2778   [(set (match_operand:SF 0 "push_operand" "")
2779         (match_operand:SF 1 "any_fp_register_operand" ""))]
2780   "TARGET_64BIT"
2781   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2782    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2783
2784 (define_insn "*movsf_1"
2785   [(set (match_operand:SF 0 "nonimmediate_operand"
2786           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2787         (match_operand:SF 1 "general_operand"
2788           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2789   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2790    && (reload_in_progress || reload_completed
2791        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2792        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2793            && standard_80387_constant_p (operands[1]))
2794        || GET_CODE (operands[1]) != CONST_DOUBLE
2795        || memory_operand (operands[0], SFmode))"
2796 {
2797   switch (which_alternative)
2798     {
2799     case 0:
2800     case 1:
2801       return output_387_reg_move (insn, operands);
2802
2803     case 2:
2804       return standard_80387_constant_opcode (operands[1]);
2805
2806     case 3:
2807     case 4:
2808       return "mov{l}\t{%1, %0|%0, %1}";
2809     case 5:
2810       if (get_attr_mode (insn) == MODE_TI)
2811         return "%vpxor\t%0, %d0";
2812       else
2813         return "%vxorps\t%0, %d0";
2814     case 6:
2815       if (get_attr_mode (insn) == MODE_V4SF)
2816         return "%vmovaps\t{%1, %0|%0, %1}";
2817       else
2818         return "%vmovss\t{%1, %d0|%d0, %1}";
2819     case 7:
2820       if (TARGET_AVX)
2821         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2822                                    : "vmovss\t{%1, %0|%0, %1}";
2823       else
2824         return "movss\t{%1, %0|%0, %1}";
2825     case 8:
2826       return "%vmovss\t{%1, %0|%0, %1}";
2827
2828     case 9: case 10: case 14: case 15:
2829       return "movd\t{%1, %0|%0, %1}";
2830     case 12: case 13:
2831       return "%vmovd\t{%1, %0|%0, %1}";
2832
2833     case 11:
2834       return "movq\t{%1, %0|%0, %1}";
2835
2836     default:
2837       gcc_unreachable ();
2838     }
2839 }
2840   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2841    (set (attr "prefix")
2842      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2843        (const_string "maybe_vex")
2844        (const_string "orig")))
2845    (set (attr "mode")
2846         (cond [(eq_attr "alternative" "3,4,9,10")
2847                  (const_string "SI")
2848                (eq_attr "alternative" "5")
2849                  (if_then_else
2850                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2851                                  (const_int 0))
2852                              (ne (symbol_ref "TARGET_SSE2")
2853                                  (const_int 0)))
2854                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2855                             (const_int 0)))
2856                    (const_string "TI")
2857                    (const_string "V4SF"))
2858                /* For architectures resolving dependencies on
2859                   whole SSE registers use APS move to break dependency
2860                   chains, otherwise use short move to avoid extra work.
2861
2862                   Do the same for architectures resolving dependencies on
2863                   the parts.  While in DF mode it is better to always handle
2864                   just register parts, the SF mode is different due to lack
2865                   of instructions to load just part of the register.  It is
2866                   better to maintain the whole registers in single format
2867                   to avoid problems on using packed logical operations.  */
2868                (eq_attr "alternative" "6")
2869                  (if_then_else
2870                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2871                             (const_int 0))
2872                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2873                             (const_int 0)))
2874                    (const_string "V4SF")
2875                    (const_string "SF"))
2876                (eq_attr "alternative" "11")
2877                  (const_string "DI")]
2878                (const_string "SF")))])
2879
2880 (define_insn "*swapsf"
2881   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2882         (match_operand:SF 1 "fp_register_operand" "+f"))
2883    (set (match_dup 1)
2884         (match_dup 0))]
2885   "reload_completed || TARGET_80387"
2886 {
2887   if (STACK_TOP_P (operands[0]))
2888     return "fxch\t%1";
2889   else
2890     return "fxch\t%0";
2891 }
2892   [(set_attr "type" "fxch")
2893    (set_attr "mode" "SF")])
2894
2895 (define_expand "movdf"
2896   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2897         (match_operand:DF 1 "general_operand" ""))]
2898   ""
2899   "ix86_expand_move (DFmode, operands); DONE;")
2900
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2903 ;; On the average, pushdf using integers can be still shorter.  Allow this
2904 ;; pattern for optimize_size too.
2905
2906 (define_insn "*pushdf_nointeger"
2907   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2908         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2909   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2910 {
2911   /* This insn should be already split before reg-stack.  */
2912   gcc_unreachable ();
2913 }
2914   [(set_attr "type" "multi")
2915    (set_attr "unit" "i387,*,*,*")
2916    (set_attr "mode" "DF,SI,SI,DF")])
2917
2918 (define_insn "*pushdf_integer"
2919   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2920         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2921   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2922 {
2923   /* This insn should be already split before reg-stack.  */
2924   gcc_unreachable ();
2925 }
2926   [(set_attr "type" "multi")
2927    (set_attr "unit" "i387,*,*")
2928    (set_attr "mode" "DF,SI,DF")])
2929
2930 ;; %%% Kill this when call knows how to work this out.
2931 (define_split
2932   [(set (match_operand:DF 0 "push_operand" "")
2933         (match_operand:DF 1 "any_fp_register_operand" ""))]
2934   "reload_completed"
2935   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2936    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2937   "")
2938
2939 (define_split
2940   [(set (match_operand:DF 0 "push_operand" "")
2941         (match_operand:DF 1 "general_operand" ""))]
2942   "reload_completed"
2943   [(const_int 0)]
2944   "ix86_split_long_move (operands); DONE;")
2945
2946 ;; Moving is usually shorter when only FP registers are used. This separate
2947 ;; movdf pattern avoids the use of integer registers for FP operations
2948 ;; when optimizing for size.
2949
2950 (define_insn "*movdf_nointeger"
2951   [(set (match_operand:DF 0 "nonimmediate_operand"
2952                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2953         (match_operand:DF 1 "general_operand"
2954                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2955   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2956    && ((optimize_function_for_size_p (cfun)
2957        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2958    && (reload_in_progress || reload_completed
2959        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2960        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2961            && optimize_function_for_size_p (cfun)
2962            && !memory_operand (operands[0], DFmode)
2963            && standard_80387_constant_p (operands[1]))
2964        || GET_CODE (operands[1]) != CONST_DOUBLE
2965        || ((optimize_function_for_size_p (cfun)
2966             || !TARGET_MEMORY_MISMATCH_STALL
2967             || reload_in_progress || reload_completed)
2968            && memory_operand (operands[0], DFmode)))"
2969 {
2970   switch (which_alternative)
2971     {
2972     case 0:
2973     case 1:
2974       return output_387_reg_move (insn, operands);
2975
2976     case 2:
2977       return standard_80387_constant_opcode (operands[1]);
2978
2979     case 3:
2980     case 4:
2981       return "#";
2982     case 5:
2983       switch (get_attr_mode (insn))
2984         {
2985         case MODE_V4SF:
2986           return "%vxorps\t%0, %d0";
2987         case MODE_V2DF:
2988           return "%vxorpd\t%0, %d0";
2989         case MODE_TI:
2990           return "%vpxor\t%0, %d0";
2991         default:
2992           gcc_unreachable ();
2993         }
2994     case 6:
2995     case 7:
2996     case 8:
2997       switch (get_attr_mode (insn))
2998         {
2999         case MODE_V4SF:
3000           return "%vmovaps\t{%1, %0|%0, %1}";
3001         case MODE_V2DF:
3002           return "%vmovapd\t{%1, %0|%0, %1}";
3003         case MODE_TI:
3004           return "%vmovdqa\t{%1, %0|%0, %1}";
3005         case MODE_DI:
3006           return "%vmovq\t{%1, %0|%0, %1}";
3007         case MODE_DF:
3008           if (TARGET_AVX)
3009             {
3010               if (REG_P (operands[0]) && REG_P (operands[1]))
3011                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3012               else
3013                 return "vmovsd\t{%1, %0|%0, %1}";
3014             }
3015           else
3016             return "movsd\t{%1, %0|%0, %1}";
3017         case MODE_V1DF:
3018           if (TARGET_AVX)
3019             {
3020               if (REG_P (operands[0]))
3021                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3022               else
3023                 return "vmovlpd\t{%1, %0|%0, %1}";
3024             }
3025           else
3026             return "movlpd\t{%1, %0|%0, %1}";
3027         case MODE_V2SF:
3028           if (TARGET_AVX)
3029             {
3030               if (REG_P (operands[0]))
3031                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3032               else
3033                 return "vmovlps\t{%1, %0|%0, %1}";
3034             }
3035           else
3036             return "movlps\t{%1, %0|%0, %1}";
3037         default:
3038           gcc_unreachable ();
3039         }
3040
3041     default:
3042       gcc_unreachable ();
3043     }
3044 }
3045   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3046    (set (attr "prefix")
3047      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3048        (const_string "orig")
3049        (const_string "maybe_vex")))
3050    (set (attr "mode")
3051         (cond [(eq_attr "alternative" "0,1,2")
3052                  (const_string "DF")
3053                (eq_attr "alternative" "3,4")
3054                  (const_string "SI")
3055
3056                /* For SSE1, we have many fewer alternatives.  */
3057                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3058                  (cond [(eq_attr "alternative" "5,6")
3059                           (const_string "V4SF")
3060                        ]
3061                    (const_string "V2SF"))
3062
3063                /* xorps is one byte shorter.  */
3064                (eq_attr "alternative" "5")
3065                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3066                             (const_int 0))
3067                           (const_string "V4SF")
3068                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3069                             (const_int 0))
3070                           (const_string "TI")
3071                        ]
3072                        (const_string "V2DF"))
3073
3074                /* For architectures resolving dependencies on
3075                   whole SSE registers use APD move to break dependency
3076                   chains, otherwise use short move to avoid extra work.
3077
3078                   movaps encodes one byte shorter.  */
3079                (eq_attr "alternative" "6")
3080                  (cond
3081                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3082                         (const_int 0))
3083                       (const_string "V4SF")
3084                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3085                         (const_int 0))
3086                       (const_string "V2DF")
3087                    ]
3088                    (const_string "DF"))
3089                /* For architectures resolving dependencies on register
3090                   parts we may avoid extra work to zero out upper part
3091                   of register.  */
3092                (eq_attr "alternative" "7")
3093                  (if_then_else
3094                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3095                        (const_int 0))
3096                    (const_string "V1DF")
3097                    (const_string "DF"))
3098               ]
3099               (const_string "DF")))])
3100
3101 (define_insn "*movdf_integer_rex64"
3102   [(set (match_operand:DF 0 "nonimmediate_operand"
3103                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3104         (match_operand:DF 1 "general_operand"
3105                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3106   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3107    && (reload_in_progress || reload_completed
3108        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3109        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3110            && optimize_function_for_size_p (cfun)
3111            && standard_80387_constant_p (operands[1]))
3112        || GET_CODE (operands[1]) != CONST_DOUBLE
3113        || memory_operand (operands[0], DFmode))"
3114 {
3115   switch (which_alternative)
3116     {
3117     case 0:
3118     case 1:
3119       return output_387_reg_move (insn, operands);
3120
3121     case 2:
3122       return standard_80387_constant_opcode (operands[1]);
3123
3124     case 3:
3125     case 4:
3126       return "#";
3127
3128     case 5:
3129       switch (get_attr_mode (insn))
3130         {
3131         case MODE_V4SF:
3132           return "%vxorps\t%0, %d0";
3133         case MODE_V2DF:
3134           return "%vxorpd\t%0, %d0";
3135         case MODE_TI:
3136           return "%vpxor\t%0, %d0";
3137         default:
3138           gcc_unreachable ();
3139         }
3140     case 6:
3141     case 7:
3142     case 8:
3143       switch (get_attr_mode (insn))
3144         {
3145         case MODE_V4SF:
3146           return "%vmovaps\t{%1, %0|%0, %1}";
3147         case MODE_V2DF:
3148           return "%vmovapd\t{%1, %0|%0, %1}";
3149         case MODE_TI:
3150           return "%vmovdqa\t{%1, %0|%0, %1}";
3151         case MODE_DI:
3152           return "%vmovq\t{%1, %0|%0, %1}";
3153         case MODE_DF:
3154           if (TARGET_AVX)
3155             {
3156               if (REG_P (operands[0]) && REG_P (operands[1]))
3157                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3158               else
3159                 return "vmovsd\t{%1, %0|%0, %1}";
3160             }
3161           else
3162             return "movsd\t{%1, %0|%0, %1}";
3163         case MODE_V1DF:
3164           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3165         case MODE_V2SF:
3166           return "%vmovlps\t{%1, %d0|%d0, %1}";
3167         default:
3168           gcc_unreachable ();
3169         }
3170
3171     case 9:
3172     case 10:
3173     return "%vmovd\t{%1, %0|%0, %1}";
3174
3175     default:
3176       gcc_unreachable();
3177     }
3178 }
3179   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3180    (set (attr "prefix")
3181      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3182        (const_string "orig")
3183        (const_string "maybe_vex")))
3184    (set (attr "mode")
3185         (cond [(eq_attr "alternative" "0,1,2")
3186                  (const_string "DF")
3187                (eq_attr "alternative" "3,4,9,10")
3188                  (const_string "DI")
3189
3190                /* For SSE1, we have many fewer alternatives.  */
3191                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3192                  (cond [(eq_attr "alternative" "5,6")
3193                           (const_string "V4SF")
3194                        ]
3195                    (const_string "V2SF"))
3196
3197                /* xorps is one byte shorter.  */
3198                (eq_attr "alternative" "5")
3199                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3200                             (const_int 0))
3201                           (const_string "V4SF")
3202                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3203                             (const_int 0))
3204                           (const_string "TI")
3205                        ]
3206                        (const_string "V2DF"))
3207
3208                /* For architectures resolving dependencies on
3209                   whole SSE registers use APD move to break dependency
3210                   chains, otherwise use short move to avoid extra work.
3211
3212                   movaps encodes one byte shorter.  */
3213                (eq_attr "alternative" "6")
3214                  (cond
3215                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3216                         (const_int 0))
3217                       (const_string "V4SF")
3218                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3219                         (const_int 0))
3220                       (const_string "V2DF")
3221                    ]
3222                    (const_string "DF"))
3223                /* For architectures resolving dependencies on register
3224                   parts we may avoid extra work to zero out upper part
3225                   of register.  */
3226                (eq_attr "alternative" "7")
3227                  (if_then_else
3228                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3229                        (const_int 0))
3230                    (const_string "V1DF")
3231                    (const_string "DF"))
3232               ]
3233               (const_string "DF")))])
3234
3235 (define_insn "*movdf_integer"
3236   [(set (match_operand:DF 0 "nonimmediate_operand"
3237                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3238         (match_operand:DF 1 "general_operand"
3239                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3240   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3241    && optimize_function_for_speed_p (cfun)
3242    && TARGET_INTEGER_DFMODE_MOVES
3243    && (reload_in_progress || reload_completed
3244        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3245        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3246            && optimize_function_for_size_p (cfun)
3247            && standard_80387_constant_p (operands[1]))
3248        || GET_CODE (operands[1]) != CONST_DOUBLE
3249        || memory_operand (operands[0], DFmode))"
3250 {
3251   switch (which_alternative)
3252     {
3253     case 0:
3254     case 1:
3255       return output_387_reg_move (insn, operands);
3256
3257     case 2:
3258       return standard_80387_constant_opcode (operands[1]);
3259
3260     case 3:
3261     case 4:
3262       return "#";
3263
3264     case 5:
3265       switch (get_attr_mode (insn))
3266         {
3267         case MODE_V4SF:
3268           return "xorps\t%0, %0";
3269         case MODE_V2DF:
3270           return "xorpd\t%0, %0";
3271         case MODE_TI:
3272           return "pxor\t%0, %0";
3273         default:
3274           gcc_unreachable ();
3275         }
3276     case 6:
3277     case 7:
3278     case 8:
3279       switch (get_attr_mode (insn))
3280         {
3281         case MODE_V4SF:
3282           return "movaps\t{%1, %0|%0, %1}";
3283         case MODE_V2DF:
3284           return "movapd\t{%1, %0|%0, %1}";
3285         case MODE_TI:
3286           return "movdqa\t{%1, %0|%0, %1}";
3287         case MODE_DI:
3288           return "movq\t{%1, %0|%0, %1}";
3289         case MODE_DF:
3290           return "movsd\t{%1, %0|%0, %1}";
3291         case MODE_V1DF:
3292           return "movlpd\t{%1, %0|%0, %1}";
3293         case MODE_V2SF:
3294           return "movlps\t{%1, %0|%0, %1}";
3295         default:
3296           gcc_unreachable ();
3297         }
3298
3299     default:
3300       gcc_unreachable();
3301     }
3302 }
3303   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3304    (set (attr "mode")
3305         (cond [(eq_attr "alternative" "0,1,2")
3306                  (const_string "DF")
3307                (eq_attr "alternative" "3,4")
3308                  (const_string "SI")
3309
3310                /* For SSE1, we have many fewer alternatives.  */
3311                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3312                  (cond [(eq_attr "alternative" "5,6")
3313                           (const_string "V4SF")
3314                        ]
3315                    (const_string "V2SF"))
3316
3317                /* xorps is one byte shorter.  */
3318                (eq_attr "alternative" "5")
3319                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3320                             (const_int 0))
3321                           (const_string "V4SF")
3322                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3323                             (const_int 0))
3324                           (const_string "TI")
3325                        ]
3326                        (const_string "V2DF"))
3327
3328                /* For architectures resolving dependencies on
3329                   whole SSE registers use APD move to break dependency
3330                   chains, otherwise use short move to avoid extra work.
3331
3332                   movaps encodes one byte shorter.  */
3333                (eq_attr "alternative" "6")
3334                  (cond
3335                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3336                         (const_int 0))
3337                       (const_string "V4SF")
3338                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3339                         (const_int 0))
3340                       (const_string "V2DF")
3341                    ]
3342                    (const_string "DF"))
3343                /* For architectures resolving dependencies on register
3344                   parts we may avoid extra work to zero out upper part
3345                   of register.  */
3346                (eq_attr "alternative" "7")
3347                  (if_then_else
3348                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3349                        (const_int 0))
3350                    (const_string "V1DF")
3351                    (const_string "DF"))
3352               ]
3353               (const_string "DF")))])
3354
3355 (define_split
3356   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3357         (match_operand:DF 1 "general_operand" ""))]
3358   "reload_completed
3359    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3360    && ! (ANY_FP_REG_P (operands[0]) ||
3361          (GET_CODE (operands[0]) == SUBREG
3362           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3363    && ! (ANY_FP_REG_P (operands[1]) ||
3364          (GET_CODE (operands[1]) == SUBREG
3365           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3366   [(const_int 0)]
3367   "ix86_split_long_move (operands); DONE;")
3368
3369 (define_insn "*swapdf"
3370   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3371         (match_operand:DF 1 "fp_register_operand" "+f"))
3372    (set (match_dup 1)
3373         (match_dup 0))]
3374   "reload_completed || TARGET_80387"
3375 {
3376   if (STACK_TOP_P (operands[0]))
3377     return "fxch\t%1";
3378   else
3379     return "fxch\t%0";
3380 }
3381   [(set_attr "type" "fxch")
3382    (set_attr "mode" "DF")])
3383
3384 (define_expand "movxf"
3385   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3386         (match_operand:XF 1 "general_operand" ""))]
3387   ""
3388   "ix86_expand_move (XFmode, operands); DONE;")
3389
3390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3391 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3392 ;; Pushing using integer instructions is longer except for constants
3393 ;; and direct memory references.
3394 ;; (assuming that any given constant is pushed only once, but this ought to be
3395 ;;  handled elsewhere).
3396
3397 (define_insn "*pushxf_nointeger"
3398   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3399         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3400   "optimize_function_for_size_p (cfun)"
3401 {
3402   /* This insn should be already split before reg-stack.  */
3403   gcc_unreachable ();
3404 }
3405   [(set_attr "type" "multi")
3406    (set_attr "unit" "i387,*,*")
3407    (set_attr "mode" "XF,SI,SI")])
3408
3409 (define_insn "*pushxf_integer"
3410   [(set (match_operand:XF 0 "push_operand" "=<,<")
3411         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3412   "optimize_function_for_speed_p (cfun)"
3413 {
3414   /* This insn should be already split before reg-stack.  */
3415   gcc_unreachable ();
3416 }
3417   [(set_attr "type" "multi")
3418    (set_attr "unit" "i387,*")
3419    (set_attr "mode" "XF,SI")])
3420
3421 (define_split
3422   [(set (match_operand 0 "push_operand" "")
3423         (match_operand 1 "general_operand" ""))]
3424   "reload_completed
3425    && (GET_MODE (operands[0]) == XFmode
3426        || GET_MODE (operands[0]) == DFmode)
3427    && !ANY_FP_REG_P (operands[1])"
3428   [(const_int 0)]
3429   "ix86_split_long_move (operands); DONE;")
3430
3431 (define_split
3432   [(set (match_operand:XF 0 "push_operand" "")
3433         (match_operand:XF 1 "any_fp_register_operand" ""))]
3434   ""
3435   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3436    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3437   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3438
3439 ;; Do not use integer registers when optimizing for size
3440 (define_insn "*movxf_nointeger"
3441   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3442         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3443   "optimize_function_for_size_p (cfun)
3444    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3445    && (reload_in_progress || reload_completed
3446        || standard_80387_constant_p (operands[1])
3447        || GET_CODE (operands[1]) != CONST_DOUBLE
3448        || memory_operand (operands[0], XFmode))"
3449 {
3450   switch (which_alternative)
3451     {
3452     case 0:
3453     case 1:
3454       return output_387_reg_move (insn, operands);
3455
3456     case 2:
3457       return standard_80387_constant_opcode (operands[1]);
3458
3459     case 3: case 4:
3460       return "#";
3461     default:
3462       gcc_unreachable ();
3463     }
3464 }
3465   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3466    (set_attr "mode" "XF,XF,XF,SI,SI")])
3467
3468 (define_insn "*movxf_integer"
3469   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3470         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3471   "optimize_function_for_speed_p (cfun)
3472    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3473    && (reload_in_progress || reload_completed
3474        || GET_CODE (operands[1]) != CONST_DOUBLE
3475        || memory_operand (operands[0], XFmode))"
3476 {
3477   switch (which_alternative)
3478     {
3479     case 0:
3480     case 1:
3481       return output_387_reg_move (insn, operands);
3482
3483     case 2:
3484       return standard_80387_constant_opcode (operands[1]);
3485
3486     case 3: case 4:
3487       return "#";
3488
3489     default:
3490       gcc_unreachable ();
3491     }
3492 }
3493   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3494    (set_attr "mode" "XF,XF,XF,SI,SI")])
3495
3496 (define_expand "movtf"
3497   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3498         (match_operand:TF 1 "nonimmediate_operand" ""))]
3499   "TARGET_SSE2"
3500 {
3501   ix86_expand_move (TFmode, operands);
3502   DONE;
3503 })
3504
3505 (define_insn "*movtf_internal"
3506   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3507         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3508   "TARGET_SSE2
3509    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3510 {
3511   switch (which_alternative)
3512     {
3513     case 0:
3514     case 1:
3515       if (get_attr_mode (insn) == MODE_V4SF)
3516         return "%vmovaps\t{%1, %0|%0, %1}";
3517       else
3518         return "%vmovdqa\t{%1, %0|%0, %1}";
3519     case 2:
3520       if (get_attr_mode (insn) == MODE_V4SF)
3521         return "%vxorps\t%0, %d0";
3522       else
3523         return "%vpxor\t%0, %d0";
3524     case 3:
3525     case 4:
3526         return "#";
3527     default:
3528       gcc_unreachable ();
3529     }
3530 }
3531   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3532    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3533    (set (attr "mode")
3534         (cond [(eq_attr "alternative" "0,2")
3535                  (if_then_else
3536                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3537                        (const_int 0))
3538                    (const_string "V4SF")
3539                    (const_string "TI"))
3540                (eq_attr "alternative" "1")
3541                  (if_then_else
3542                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3543                             (const_int 0))
3544                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3545                             (const_int 0)))
3546                    (const_string "V4SF")
3547                    (const_string "TI"))]
3548                (const_string "DI")))])
3549
3550 (define_insn "*pushtf_sse"
3551   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3552         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3553   "TARGET_SSE2"
3554 {
3555   /* This insn should be already split before reg-stack.  */
3556   gcc_unreachable ();
3557 }
3558   [(set_attr "type" "multi")
3559    (set_attr "unit" "sse,*,*")
3560    (set_attr "mode" "TF,SI,SI")])
3561
3562 (define_split
3563   [(set (match_operand:TF 0 "push_operand" "")
3564         (match_operand:TF 1 "general_operand" ""))]
3565   "TARGET_SSE2 && reload_completed
3566    && !SSE_REG_P (operands[1])"
3567   [(const_int 0)]
3568   "ix86_split_long_move (operands); DONE;")
3569
3570 (define_split
3571   [(set (match_operand:TF 0 "push_operand" "")
3572         (match_operand:TF 1 "any_fp_register_operand" ""))]
3573   "TARGET_SSE2"
3574   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3575    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3576   "")
3577
3578 (define_split
3579   [(set (match_operand 0 "nonimmediate_operand" "")
3580         (match_operand 1 "general_operand" ""))]
3581   "reload_completed
3582    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3583    && GET_MODE (operands[0]) == XFmode
3584    && ! (ANY_FP_REG_P (operands[0]) ||
3585          (GET_CODE (operands[0]) == SUBREG
3586           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3587    && ! (ANY_FP_REG_P (operands[1]) ||
3588          (GET_CODE (operands[1]) == SUBREG
3589           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3590   [(const_int 0)]
3591   "ix86_split_long_move (operands); DONE;")
3592
3593 (define_split
3594   [(set (match_operand 0 "register_operand" "")
3595         (match_operand 1 "memory_operand" ""))]
3596   "reload_completed
3597    && MEM_P (operands[1])
3598    && (GET_MODE (operands[0]) == TFmode
3599        || GET_MODE (operands[0]) == XFmode
3600        || GET_MODE (operands[0]) == SFmode
3601        || GET_MODE (operands[0]) == DFmode)
3602    && (operands[2] = find_constant_src (insn))"
3603   [(set (match_dup 0) (match_dup 2))]
3604 {
3605   rtx c = operands[2];
3606   rtx r = operands[0];
3607
3608   if (GET_CODE (r) == SUBREG)
3609     r = SUBREG_REG (r);
3610
3611   if (SSE_REG_P (r))
3612     {
3613       if (!standard_sse_constant_p (c))
3614         FAIL;
3615     }
3616   else if (FP_REG_P (r))
3617     {
3618       if (!standard_80387_constant_p (c))
3619         FAIL;
3620     }
3621   else if (MMX_REG_P (r))
3622     FAIL;
3623 })
3624
3625 (define_split
3626   [(set (match_operand 0 "register_operand" "")
3627         (float_extend (match_operand 1 "memory_operand" "")))]
3628   "reload_completed
3629    && MEM_P (operands[1])
3630    && (GET_MODE (operands[0]) == TFmode
3631        || GET_MODE (operands[0]) == XFmode
3632        || GET_MODE (operands[0]) == SFmode
3633        || GET_MODE (operands[0]) == DFmode)
3634    && (operands[2] = find_constant_src (insn))"
3635   [(set (match_dup 0) (match_dup 2))]
3636 {
3637   rtx c = operands[2];
3638   rtx r = operands[0];
3639
3640   if (GET_CODE (r) == SUBREG)
3641     r = SUBREG_REG (r);
3642
3643   if (SSE_REG_P (r))
3644     {
3645       if (!standard_sse_constant_p (c))
3646         FAIL;
3647     }
3648   else if (FP_REG_P (r))
3649     {
3650       if (!standard_80387_constant_p (c))
3651         FAIL;
3652     }
3653   else if (MMX_REG_P (r))
3654     FAIL;
3655 })
3656
3657 (define_insn "swapxf"
3658   [(set (match_operand:XF 0 "register_operand" "+f")
3659         (match_operand:XF 1 "register_operand" "+f"))
3660    (set (match_dup 1)
3661         (match_dup 0))]
3662   "TARGET_80387"
3663 {
3664   if (STACK_TOP_P (operands[0]))
3665     return "fxch\t%1";
3666   else
3667     return "fxch\t%0";
3668 }
3669   [(set_attr "type" "fxch")
3670    (set_attr "mode" "XF")])
3671
3672 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3673 (define_split
3674   [(set (match_operand:X87MODEF 0 "register_operand" "")
3675         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3676   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3677    && (standard_80387_constant_p (operands[1]) == 8
3678        || standard_80387_constant_p (operands[1]) == 9)"
3679   [(set (match_dup 0)(match_dup 1))
3680    (set (match_dup 0)
3681         (neg:X87MODEF (match_dup 0)))]
3682 {
3683   REAL_VALUE_TYPE r;
3684
3685   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3686   if (real_isnegzero (&r))
3687     operands[1] = CONST0_RTX (<MODE>mode);
3688   else
3689     operands[1] = CONST1_RTX (<MODE>mode);
3690 })
3691
3692 (define_split
3693   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3694         (match_operand:TF 1 "general_operand" ""))]
3695   "reload_completed
3696    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3697   [(const_int 0)]
3698   "ix86_split_long_move (operands); DONE;")
3699 \f
3700 ;; Zero extension instructions
3701
3702 (define_expand "zero_extendhisi2"
3703   [(set (match_operand:SI 0 "register_operand" "")
3704      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3705   ""
3706 {
3707   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3708     {
3709       operands[1] = force_reg (HImode, operands[1]);
3710       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3711       DONE;
3712     }
3713 })
3714
3715 (define_insn "zero_extendhisi2_and"
3716   [(set (match_operand:SI 0 "register_operand" "=r")
3717      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3718    (clobber (reg:CC FLAGS_REG))]
3719   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3720   "#"
3721   [(set_attr "type" "alu1")
3722    (set_attr "mode" "SI")])
3723
3724 (define_split
3725   [(set (match_operand:SI 0 "register_operand" "")
3726         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3727    (clobber (reg:CC FLAGS_REG))]
3728   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3729    && optimize_function_for_speed_p (cfun)"
3730   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3731               (clobber (reg:CC FLAGS_REG))])]
3732   "")
3733
3734 (define_insn "*zero_extendhisi2_movzwl"
3735   [(set (match_operand:SI 0 "register_operand" "=r")
3736      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3737   "!TARGET_ZERO_EXTEND_WITH_AND
3738    || optimize_function_for_size_p (cfun)"
3739   "movz{wl|x}\t{%1, %0|%0, %1}"
3740   [(set_attr "type" "imovx")
3741    (set_attr "mode" "SI")])
3742
3743 (define_expand "zero_extendqihi2"
3744   [(parallel
3745     [(set (match_operand:HI 0 "register_operand" "")
3746        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3747      (clobber (reg:CC FLAGS_REG))])]
3748   ""
3749   "")
3750
3751 (define_insn "*zero_extendqihi2_and"
3752   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3753      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3754    (clobber (reg:CC FLAGS_REG))]
3755   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3756   "#"
3757   [(set_attr "type" "alu1")
3758    (set_attr "mode" "HI")])
3759
3760 (define_insn "*zero_extendqihi2_movzbw_and"
3761   [(set (match_operand:HI 0 "register_operand" "=r,r")
3762      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3763    (clobber (reg:CC FLAGS_REG))]
3764   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3765   "#"
3766   [(set_attr "type" "imovx,alu1")
3767    (set_attr "mode" "HI")])
3768
3769 ; zero extend to SImode here to avoid partial register stalls
3770 (define_insn "*zero_extendqihi2_movzbl"
3771   [(set (match_operand:HI 0 "register_operand" "=r")
3772      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3773   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3774    && reload_completed"
3775   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3776   [(set_attr "type" "imovx")
3777    (set_attr "mode" "SI")])
3778
3779 ;; For the movzbw case strip only the clobber
3780 (define_split
3781   [(set (match_operand:HI 0 "register_operand" "")
3782         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3783    (clobber (reg:CC FLAGS_REG))]
3784   "reload_completed
3785    && (!TARGET_ZERO_EXTEND_WITH_AND
3786        || optimize_function_for_size_p (cfun))
3787    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3788   [(set (match_operand:HI 0 "register_operand" "")
3789         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3790
3791 ;; When source and destination does not overlap, clear destination
3792 ;; first and then do the movb
3793 (define_split
3794   [(set (match_operand:HI 0 "register_operand" "")
3795         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3796    (clobber (reg:CC FLAGS_REG))]
3797   "reload_completed
3798    && ANY_QI_REG_P (operands[0])
3799    && (TARGET_ZERO_EXTEND_WITH_AND
3800        && optimize_function_for_speed_p (cfun))
3801    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3802   [(set (match_dup 0) (const_int 0))
3803    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3804   "operands[2] = gen_lowpart (QImode, operands[0]);")
3805
3806 ;; Rest is handled by single and.
3807 (define_split
3808   [(set (match_operand:HI 0 "register_operand" "")
3809         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3810    (clobber (reg:CC FLAGS_REG))]
3811   "reload_completed
3812    && true_regnum (operands[0]) == true_regnum (operands[1])"
3813   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3814               (clobber (reg:CC FLAGS_REG))])]
3815   "")
3816
3817 (define_expand "zero_extendqisi2"
3818   [(parallel
3819     [(set (match_operand:SI 0 "register_operand" "")
3820        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3821      (clobber (reg:CC FLAGS_REG))])]
3822   ""
3823   "")
3824
3825 (define_insn "*zero_extendqisi2_and"
3826   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3827      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3828    (clobber (reg:CC FLAGS_REG))]
3829   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3830   "#"
3831   [(set_attr "type" "alu1")
3832    (set_attr "mode" "SI")])
3833
3834 (define_insn "*zero_extendqisi2_movzbw_and"
3835   [(set (match_operand:SI 0 "register_operand" "=r,r")
3836      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3837    (clobber (reg:CC FLAGS_REG))]
3838   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3839   "#"
3840   [(set_attr "type" "imovx,alu1")
3841    (set_attr "mode" "SI")])
3842
3843 (define_insn "*zero_extendqisi2_movzbw"
3844   [(set (match_operand:SI 0 "register_operand" "=r")
3845      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3846   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3847    && reload_completed"
3848   "movz{bl|x}\t{%1, %0|%0, %1}"
3849   [(set_attr "type" "imovx")
3850    (set_attr "mode" "SI")])
3851
3852 ;; For the movzbl case strip only the clobber
3853 (define_split
3854   [(set (match_operand:SI 0 "register_operand" "")
3855         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3856    (clobber (reg:CC FLAGS_REG))]
3857   "reload_completed
3858    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3859    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3860   [(set (match_dup 0)
3861         (zero_extend:SI (match_dup 1)))])
3862
3863 ;; When source and destination does not overlap, clear destination
3864 ;; first and then do the movb
3865 (define_split
3866   [(set (match_operand:SI 0 "register_operand" "")
3867         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3868    (clobber (reg:CC FLAGS_REG))]
3869   "reload_completed
3870    && ANY_QI_REG_P (operands[0])
3871    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3872    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3873    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3874   [(set (match_dup 0) (const_int 0))
3875    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3876   "operands[2] = gen_lowpart (QImode, operands[0]);")
3877
3878 ;; Rest is handled by single and.
3879 (define_split
3880   [(set (match_operand:SI 0 "register_operand" "")
3881         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3882    (clobber (reg:CC FLAGS_REG))]
3883   "reload_completed
3884    && true_regnum (operands[0]) == true_regnum (operands[1])"
3885   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3886               (clobber (reg:CC FLAGS_REG))])]
3887   "")
3888
3889 ;; %%% Kill me once multi-word ops are sane.
3890 (define_expand "zero_extendsidi2"
3891   [(set (match_operand:DI 0 "register_operand" "")
3892      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3893   ""
3894 {
3895   if (!TARGET_64BIT)
3896     {
3897       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3898       DONE;
3899     }
3900 })
3901
3902 (define_insn "zero_extendsidi2_32"
3903   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3904         (zero_extend:DI
3905          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3906    (clobber (reg:CC FLAGS_REG))]
3907   "!TARGET_64BIT"
3908   "@
3909    #
3910    #
3911    #
3912    movd\t{%1, %0|%0, %1}
3913    movd\t{%1, %0|%0, %1}
3914    %vmovd\t{%1, %0|%0, %1}
3915    %vmovd\t{%1, %0|%0, %1}"
3916   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3917    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3918    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3919
3920 (define_insn "zero_extendsidi2_rex64"
3921   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3922      (zero_extend:DI
3923        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3924   "TARGET_64BIT"
3925   "@
3926    mov\t{%k1, %k0|%k0, %k1}
3927    #
3928    movd\t{%1, %0|%0, %1}
3929    movd\t{%1, %0|%0, %1}
3930    %vmovd\t{%1, %0|%0, %1}
3931    %vmovd\t{%1, %0|%0, %1}"
3932   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3933    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3934    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3935
3936 (define_split
3937   [(set (match_operand:DI 0 "memory_operand" "")
3938      (zero_extend:DI (match_dup 0)))]
3939   "TARGET_64BIT"
3940   [(set (match_dup 4) (const_int 0))]
3941   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3942
3943 (define_split
3944   [(set (match_operand:DI 0 "register_operand" "")
3945         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3946    (clobber (reg:CC FLAGS_REG))]
3947   "!TARGET_64BIT && reload_completed
3948    && true_regnum (operands[0]) == true_regnum (operands[1])"
3949   [(set (match_dup 4) (const_int 0))]
3950   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3951
3952 (define_split
3953   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3954         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3955    (clobber (reg:CC FLAGS_REG))]
3956   "!TARGET_64BIT && reload_completed
3957    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3958   [(set (match_dup 3) (match_dup 1))
3959    (set (match_dup 4) (const_int 0))]
3960   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3961
3962 (define_insn "zero_extendhidi2"
3963   [(set (match_operand:DI 0 "register_operand" "=r")
3964      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3965   "TARGET_64BIT"
3966   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3967   [(set_attr "type" "imovx")
3968    (set_attr "mode" "DI")])
3969
3970 (define_insn "zero_extendqidi2"
3971   [(set (match_operand:DI 0 "register_operand" "=r")
3972      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3973   "TARGET_64BIT"
3974   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3975   [(set_attr "type" "imovx")
3976    (set_attr "mode" "DI")])
3977 \f
3978 ;; Sign extension instructions
3979
3980 (define_expand "extendsidi2"
3981   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3982                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3983               (clobber (reg:CC FLAGS_REG))
3984               (clobber (match_scratch:SI 2 ""))])]
3985   ""
3986 {
3987   if (TARGET_64BIT)
3988     {
3989       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3990       DONE;
3991     }
3992 })
3993
3994 (define_insn "*extendsidi2_1"
3995   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3996         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3997    (clobber (reg:CC FLAGS_REG))
3998    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3999   "!TARGET_64BIT"
4000   "#")
4001
4002 (define_insn "extendsidi2_rex64"
4003   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4004         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4005   "TARGET_64BIT"
4006   "@
4007    {cltq|cdqe}
4008    movs{lq|x}\t{%1,%0|%0, %1}"
4009   [(set_attr "type" "imovx")
4010    (set_attr "mode" "DI")
4011    (set_attr "prefix_0f" "0")
4012    (set_attr "modrm" "0,1")])
4013
4014 (define_insn "extendhidi2"
4015   [(set (match_operand:DI 0 "register_operand" "=r")
4016         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4017   "TARGET_64BIT"
4018   "movs{wq|x}\t{%1,%0|%0, %1}"
4019   [(set_attr "type" "imovx")
4020    (set_attr "mode" "DI")])
4021
4022 (define_insn "extendqidi2"
4023   [(set (match_operand:DI 0 "register_operand" "=r")
4024         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4025   "TARGET_64BIT"
4026   "movs{bq|x}\t{%1,%0|%0, %1}"
4027    [(set_attr "type" "imovx")
4028     (set_attr "mode" "DI")])
4029
4030 ;; Extend to memory case when source register does die.
4031 (define_split
4032   [(set (match_operand:DI 0 "memory_operand" "")
4033         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4034    (clobber (reg:CC FLAGS_REG))
4035    (clobber (match_operand:SI 2 "register_operand" ""))]
4036   "(reload_completed
4037     && dead_or_set_p (insn, operands[1])
4038     && !reg_mentioned_p (operands[1], operands[0]))"
4039   [(set (match_dup 3) (match_dup 1))
4040    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4041               (clobber (reg:CC FLAGS_REG))])
4042    (set (match_dup 4) (match_dup 1))]
4043   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4044
4045 ;; Extend to memory case when source register does not die.
4046 (define_split
4047   [(set (match_operand:DI 0 "memory_operand" "")
4048         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4049    (clobber (reg:CC FLAGS_REG))
4050    (clobber (match_operand:SI 2 "register_operand" ""))]
4051   "reload_completed"
4052   [(const_int 0)]
4053 {
4054   split_di (&operands[0], 1, &operands[3], &operands[4]);
4055
4056   emit_move_insn (operands[3], operands[1]);
4057
4058   /* Generate a cltd if possible and doing so it profitable.  */
4059   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4060       && true_regnum (operands[1]) == AX_REG
4061       && true_regnum (operands[2]) == DX_REG)
4062     {
4063       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4064     }
4065   else
4066     {
4067       emit_move_insn (operands[2], operands[1]);
4068       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4069     }
4070   emit_move_insn (operands[4], operands[2]);
4071   DONE;
4072 })
4073
4074 ;; Extend to register case.  Optimize case where source and destination
4075 ;; registers match and cases where we can use cltd.
4076 (define_split
4077   [(set (match_operand:DI 0 "register_operand" "")
4078         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4079    (clobber (reg:CC FLAGS_REG))
4080    (clobber (match_scratch:SI 2 ""))]
4081   "reload_completed"
4082   [(const_int 0)]
4083 {
4084   split_di (&operands[0], 1, &operands[3], &operands[4]);
4085
4086   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4087     emit_move_insn (operands[3], operands[1]);
4088
4089   /* Generate a cltd if possible and doing so it profitable.  */
4090   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4091       && true_regnum (operands[3]) == AX_REG)
4092     {
4093       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4094       DONE;
4095     }
4096
4097   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4098     emit_move_insn (operands[4], operands[1]);
4099
4100   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4101   DONE;
4102 })
4103
4104 (define_insn "extendhisi2"
4105   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4106         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4107   ""
4108 {
4109   switch (get_attr_prefix_0f (insn))
4110     {
4111     case 0:
4112       return "{cwtl|cwde}";
4113     default:
4114       return "movs{wl|x}\t{%1,%0|%0, %1}";
4115     }
4116 }
4117   [(set_attr "type" "imovx")
4118    (set_attr "mode" "SI")
4119    (set (attr "prefix_0f")
4120      ;; movsx is short decodable while cwtl is vector decoded.
4121      (if_then_else (and (eq_attr "cpu" "!k6")
4122                         (eq_attr "alternative" "0"))
4123         (const_string "0")
4124         (const_string "1")))
4125    (set (attr "modrm")
4126      (if_then_else (eq_attr "prefix_0f" "0")
4127         (const_string "0")
4128         (const_string "1")))])
4129
4130 (define_insn "*extendhisi2_zext"
4131   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4132         (zero_extend:DI
4133           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4134   "TARGET_64BIT"
4135 {
4136   switch (get_attr_prefix_0f (insn))
4137     {
4138     case 0:
4139       return "{cwtl|cwde}";
4140     default:
4141       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4142     }
4143 }
4144   [(set_attr "type" "imovx")
4145    (set_attr "mode" "SI")
4146    (set (attr "prefix_0f")
4147      ;; movsx is short decodable while cwtl is vector decoded.
4148      (if_then_else (and (eq_attr "cpu" "!k6")
4149                         (eq_attr "alternative" "0"))
4150         (const_string "0")
4151         (const_string "1")))
4152    (set (attr "modrm")
4153      (if_then_else (eq_attr "prefix_0f" "0")
4154         (const_string "0")
4155         (const_string "1")))])
4156
4157 (define_insn "extendqihi2"
4158   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4159         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4160   ""
4161 {
4162   switch (get_attr_prefix_0f (insn))
4163     {
4164     case 0:
4165       return "{cbtw|cbw}";
4166     default:
4167       return "movs{bw|x}\t{%1,%0|%0, %1}";
4168     }
4169 }
4170   [(set_attr "type" "imovx")
4171    (set_attr "mode" "HI")
4172    (set (attr "prefix_0f")
4173      ;; movsx is short decodable while cwtl is vector decoded.
4174      (if_then_else (and (eq_attr "cpu" "!k6")
4175                         (eq_attr "alternative" "0"))
4176         (const_string "0")
4177         (const_string "1")))
4178    (set (attr "modrm")
4179      (if_then_else (eq_attr "prefix_0f" "0")
4180         (const_string "0")
4181         (const_string "1")))])
4182
4183 (define_insn "extendqisi2"
4184   [(set (match_operand:SI 0 "register_operand" "=r")
4185         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4186   ""
4187   "movs{bl|x}\t{%1,%0|%0, %1}"
4188    [(set_attr "type" "imovx")
4189     (set_attr "mode" "SI")])
4190
4191 (define_insn "*extendqisi2_zext"
4192   [(set (match_operand:DI 0 "register_operand" "=r")
4193         (zero_extend:DI
4194           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4195   "TARGET_64BIT"
4196   "movs{bl|x}\t{%1,%k0|%k0, %1}"
4197    [(set_attr "type" "imovx")
4198     (set_attr "mode" "SI")])
4199 \f
4200 ;; Conversions between float and double.
4201
4202 ;; These are all no-ops in the model used for the 80387.  So just
4203 ;; emit moves.
4204
4205 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4206 (define_insn "*dummy_extendsfdf2"
4207   [(set (match_operand:DF 0 "push_operand" "=<")
4208         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4209   "0"
4210   "#")
4211
4212 (define_split
4213   [(set (match_operand:DF 0 "push_operand" "")
4214         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4215   ""
4216   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4217    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4218
4219 (define_insn "*dummy_extendsfxf2"
4220   [(set (match_operand:XF 0 "push_operand" "=<")
4221         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4222   "0"
4223   "#")
4224
4225 (define_split
4226   [(set (match_operand:XF 0 "push_operand" "")
4227         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4228   ""
4229   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4230    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4231   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4232
4233 (define_split
4234   [(set (match_operand:XF 0 "push_operand" "")
4235         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4236   ""
4237   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4238    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4239   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4240
4241 (define_expand "extendsfdf2"
4242   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4243         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4244   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4245 {
4246   /* ??? Needed for compress_float_constant since all fp constants
4247      are LEGITIMATE_CONSTANT_P.  */
4248   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4249     {
4250       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4251           && standard_80387_constant_p (operands[1]) > 0)
4252         {
4253           operands[1] = simplify_const_unary_operation
4254             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4255           emit_move_insn_1 (operands[0], operands[1]);
4256           DONE;
4257         }
4258       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4259     }
4260 })
4261
4262 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4263    cvtss2sd:
4264       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4265       cvtps2pd xmm2,xmm1
4266    We do the conversion post reload to avoid producing of 128bit spills
4267    that might lead to ICE on 32bit target.  The sequence unlikely combine
4268    anyway.  */
4269 (define_split
4270   [(set (match_operand:DF 0 "register_operand" "")
4271         (float_extend:DF
4272           (match_operand:SF 1 "nonimmediate_operand" "")))]
4273   "TARGET_USE_VECTOR_FP_CONVERTS
4274    && optimize_insn_for_speed_p ()
4275    && reload_completed && SSE_REG_P (operands[0])"
4276    [(set (match_dup 2)
4277          (float_extend:V2DF
4278            (vec_select:V2SF
4279              (match_dup 3)
4280              (parallel [(const_int 0) (const_int 1)]))))]
4281 {
4282   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4283   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4284   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4285      Try to avoid move when unpacking can be done in source.  */
4286   if (REG_P (operands[1]))
4287     {
4288       /* If it is unsafe to overwrite upper half of source, we need
4289          to move to destination and unpack there.  */
4290       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4291            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4292           && true_regnum (operands[0]) != true_regnum (operands[1]))
4293         {
4294           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4295           emit_move_insn (tmp, operands[1]);
4296         }
4297       else
4298         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4299       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4300     }
4301   else
4302     emit_insn (gen_vec_setv4sf_0 (operands[3],
4303                                   CONST0_RTX (V4SFmode), operands[1]));
4304 })
4305
4306 (define_insn "*extendsfdf2_mixed"
4307   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4308         (float_extend:DF
4309           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4310   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4311 {
4312   switch (which_alternative)
4313     {
4314     case 0:
4315     case 1:
4316       return output_387_reg_move (insn, operands);
4317
4318     case 2:
4319       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4320
4321     default:
4322       gcc_unreachable ();
4323     }
4324 }
4325   [(set_attr "type" "fmov,fmov,ssecvt")
4326    (set_attr "prefix" "orig,orig,maybe_vex")
4327    (set_attr "mode" "SF,XF,DF")])
4328
4329 (define_insn "*extendsfdf2_sse"
4330   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4331         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4332   "TARGET_SSE2 && TARGET_SSE_MATH"
4333   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4334   [(set_attr "type" "ssecvt")
4335    (set_attr "prefix" "maybe_vex")
4336    (set_attr "mode" "DF")])
4337
4338 (define_insn "*extendsfdf2_i387"
4339   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4340         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4341   "TARGET_80387"
4342   "* return output_387_reg_move (insn, operands);"
4343   [(set_attr "type" "fmov")
4344    (set_attr "mode" "SF,XF")])
4345
4346 (define_expand "extend<mode>xf2"
4347   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4348         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4349   "TARGET_80387"
4350 {
4351   /* ??? Needed for compress_float_constant since all fp constants
4352      are LEGITIMATE_CONSTANT_P.  */
4353   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4354     {
4355       if (standard_80387_constant_p (operands[1]) > 0)
4356         {
4357           operands[1] = simplify_const_unary_operation
4358             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4359           emit_move_insn_1 (operands[0], operands[1]);
4360           DONE;
4361         }
4362       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4363     }
4364 })
4365
4366 (define_insn "*extend<mode>xf2_i387"
4367   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4368         (float_extend:XF
4369           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4370   "TARGET_80387"
4371   "* return output_387_reg_move (insn, operands);"
4372   [(set_attr "type" "fmov")
4373    (set_attr "mode" "<MODE>,XF")])
4374
4375 ;; %%% This seems bad bad news.
4376 ;; This cannot output into an f-reg because there is no way to be sure
4377 ;; of truncating in that case.  Otherwise this is just like a simple move
4378 ;; insn.  So we pretend we can output to a reg in order to get better
4379 ;; register preferencing, but we really use a stack slot.
4380
4381 ;; Conversion from DFmode to SFmode.
4382
4383 (define_expand "truncdfsf2"
4384   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4385         (float_truncate:SF
4386           (match_operand:DF 1 "nonimmediate_operand" "")))]
4387   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4388 {
4389   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4390     ;
4391   else if (flag_unsafe_math_optimizations)
4392     ;
4393   else
4394     {
4395       enum ix86_stack_slot slot = (virtuals_instantiated
4396                                    ? SLOT_TEMP
4397                                    : SLOT_VIRTUAL);
4398       rtx temp = assign_386_stack_local (SFmode, slot);
4399       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4400       DONE;
4401     }
4402 })
4403
4404 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4405    cvtsd2ss:
4406       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4407       cvtpd2ps xmm2,xmm1
4408    We do the conversion post reload to avoid producing of 128bit spills
4409    that might lead to ICE on 32bit target.  The sequence unlikely combine
4410    anyway.  */
4411 (define_split
4412   [(set (match_operand:SF 0 "register_operand" "")
4413         (float_truncate:SF
4414           (match_operand:DF 1 "nonimmediate_operand" "")))]
4415   "TARGET_USE_VECTOR_FP_CONVERTS
4416    && optimize_insn_for_speed_p ()
4417    && reload_completed && SSE_REG_P (operands[0])"
4418    [(set (match_dup 2)
4419          (vec_concat:V4SF
4420            (float_truncate:V2SF
4421              (match_dup 4))
4422            (match_dup 3)))]
4423 {
4424   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4425   operands[3] = CONST0_RTX (V2SFmode);
4426   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4427   /* Use movsd for loading from memory, unpcklpd for registers.
4428      Try to avoid move when unpacking can be done in source, or SSE3
4429      movddup is available.  */
4430   if (REG_P (operands[1]))
4431     {
4432       if (!TARGET_SSE3
4433           && true_regnum (operands[0]) != true_regnum (operands[1])
4434           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4435               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4436         {
4437           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4438           emit_move_insn (tmp, operands[1]);
4439           operands[1] = tmp;
4440         }
4441       else if (!TARGET_SSE3)
4442         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4443       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4444     }
4445   else
4446     emit_insn (gen_sse2_loadlpd (operands[4],
4447                                  CONST0_RTX (V2DFmode), operands[1]));
4448 })
4449
4450 (define_expand "truncdfsf2_with_temp"
4451   [(parallel [(set (match_operand:SF 0 "" "")
4452                    (float_truncate:SF (match_operand:DF 1 "" "")))
4453               (clobber (match_operand:SF 2 "" ""))])]
4454   "")
4455
4456 (define_insn "*truncdfsf_fast_mixed"
4457   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4458         (float_truncate:SF
4459           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4460   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4461 {
4462   switch (which_alternative)
4463     {
4464     case 0:
4465       return output_387_reg_move (insn, operands);
4466     case 1:
4467       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4468     default:
4469       gcc_unreachable ();
4470     }
4471 }
4472   [(set_attr "type" "fmov,ssecvt")
4473    (set_attr "prefix" "orig,maybe_vex")
4474    (set_attr "mode" "SF")])
4475
4476 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4477 ;; because nothing we do here is unsafe.
4478 (define_insn "*truncdfsf_fast_sse"
4479   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4480         (float_truncate:SF
4481           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4482   "TARGET_SSE2 && TARGET_SSE_MATH"
4483   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4484   [(set_attr "type" "ssecvt")
4485    (set_attr "prefix" "maybe_vex")
4486    (set_attr "mode" "SF")])
4487
4488 (define_insn "*truncdfsf_fast_i387"
4489   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4490         (float_truncate:SF
4491           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4492   "TARGET_80387 && flag_unsafe_math_optimizations"
4493   "* return output_387_reg_move (insn, operands);"
4494   [(set_attr "type" "fmov")
4495    (set_attr "mode" "SF")])
4496
4497 (define_insn "*truncdfsf_mixed"
4498   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4499         (float_truncate:SF
4500           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4501    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4502   "TARGET_MIX_SSE_I387"
4503 {
4504   switch (which_alternative)
4505     {
4506     case 0:
4507       return output_387_reg_move (insn, operands);
4508     case 1:
4509       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4510
4511     default:
4512       return "#";
4513     }
4514 }
4515   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4516    (set_attr "unit" "*,*,i387,i387,i387")
4517    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4518    (set_attr "mode" "SF")])
4519
4520 (define_insn "*truncdfsf_i387"
4521   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4522         (float_truncate:SF
4523           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4524    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4525   "TARGET_80387"
4526 {
4527   switch (which_alternative)
4528     {
4529     case 0:
4530       return output_387_reg_move (insn, operands);
4531
4532     default:
4533       return "#";
4534     }
4535 }
4536   [(set_attr "type" "fmov,multi,multi,multi")
4537    (set_attr "unit" "*,i387,i387,i387")
4538    (set_attr "mode" "SF")])
4539
4540 (define_insn "*truncdfsf2_i387_1"
4541   [(set (match_operand:SF 0 "memory_operand" "=m")
4542         (float_truncate:SF
4543           (match_operand:DF 1 "register_operand" "f")))]
4544   "TARGET_80387
4545    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4546    && !TARGET_MIX_SSE_I387"
4547   "* return output_387_reg_move (insn, operands);"
4548   [(set_attr "type" "fmov")
4549    (set_attr "mode" "SF")])
4550
4551 (define_split
4552   [(set (match_operand:SF 0 "register_operand" "")
4553         (float_truncate:SF
4554          (match_operand:DF 1 "fp_register_operand" "")))
4555    (clobber (match_operand 2 "" ""))]
4556   "reload_completed"
4557   [(set (match_dup 2) (match_dup 1))
4558    (set (match_dup 0) (match_dup 2))]
4559 {
4560   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4561 })
4562
4563 ;; Conversion from XFmode to {SF,DF}mode
4564
4565 (define_expand "truncxf<mode>2"
4566   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4567                    (float_truncate:MODEF
4568                      (match_operand:XF 1 "register_operand" "")))
4569               (clobber (match_dup 2))])]
4570   "TARGET_80387"
4571 {
4572   if (flag_unsafe_math_optimizations)
4573     {
4574       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4575       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4576       if (reg != operands[0])
4577         emit_move_insn (operands[0], reg);
4578       DONE;
4579     }
4580   else
4581     {
4582      enum ix86_stack_slot slot = (virtuals_instantiated
4583                                   ? SLOT_TEMP
4584                                   : SLOT_VIRTUAL);
4585       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4586     }
4587 })
4588
4589 (define_insn "*truncxfsf2_mixed"
4590   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4591         (float_truncate:SF
4592           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4593    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4594   "TARGET_80387"
4595 {
4596   gcc_assert (!which_alternative);
4597   return output_387_reg_move (insn, operands);
4598 }
4599   [(set_attr "type" "fmov,multi,multi,multi")
4600    (set_attr "unit" "*,i387,i387,i387")
4601    (set_attr "mode" "SF")])
4602
4603 (define_insn "*truncxfdf2_mixed"
4604   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4605         (float_truncate:DF
4606           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4607    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4608   "TARGET_80387"
4609 {
4610   gcc_assert (!which_alternative);
4611   return output_387_reg_move (insn, operands);
4612 }
4613   [(set_attr "type" "fmov,multi,multi,multi")
4614    (set_attr "unit" "*,i387,i387,i387")
4615    (set_attr "mode" "DF")])
4616
4617 (define_insn "truncxf<mode>2_i387_noop"
4618   [(set (match_operand:MODEF 0 "register_operand" "=f")
4619         (float_truncate:MODEF
4620           (match_operand:XF 1 "register_operand" "f")))]
4621   "TARGET_80387 && flag_unsafe_math_optimizations"
4622   "* return output_387_reg_move (insn, operands);"
4623   [(set_attr "type" "fmov")
4624    (set_attr "mode" "<MODE>")])
4625
4626 (define_insn "*truncxf<mode>2_i387"
4627   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4628         (float_truncate:MODEF
4629           (match_operand:XF 1 "register_operand" "f")))]
4630   "TARGET_80387"
4631   "* return output_387_reg_move (insn, operands);"
4632   [(set_attr "type" "fmov")
4633    (set_attr "mode" "<MODE>")])
4634
4635 (define_split
4636   [(set (match_operand:MODEF 0 "register_operand" "")
4637         (float_truncate:MODEF
4638           (match_operand:XF 1 "register_operand" "")))
4639    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4640   "TARGET_80387 && reload_completed"
4641   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4642    (set (match_dup 0) (match_dup 2))]
4643   "")
4644
4645 (define_split
4646   [(set (match_operand:MODEF 0 "memory_operand" "")
4647         (float_truncate:MODEF
4648           (match_operand:XF 1 "register_operand" "")))
4649    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4650   "TARGET_80387"
4651   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4652   "")
4653 \f
4654 ;; Signed conversion to DImode.
4655
4656 (define_expand "fix_truncxfdi2"
4657   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4658                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4659               (clobber (reg:CC FLAGS_REG))])]
4660   "TARGET_80387"
4661 {
4662   if (TARGET_FISTTP)
4663    {
4664      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4665      DONE;
4666    }
4667 })
4668
4669 (define_expand "fix_trunc<mode>di2"
4670   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4671                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4672               (clobber (reg:CC FLAGS_REG))])]
4673   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4674 {
4675   if (TARGET_FISTTP
4676       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4677    {
4678      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4679      DONE;
4680    }
4681   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4682    {
4683      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4684      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4685      if (out != operands[0])
4686         emit_move_insn (operands[0], out);
4687      DONE;
4688    }
4689 })
4690
4691 ;; Signed conversion to SImode.
4692
4693 (define_expand "fix_truncxfsi2"
4694   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4695                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4696               (clobber (reg:CC FLAGS_REG))])]
4697   "TARGET_80387"
4698 {
4699   if (TARGET_FISTTP)
4700    {
4701      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4702      DONE;
4703    }
4704 })
4705
4706 (define_expand "fix_trunc<mode>si2"
4707   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4708                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4709               (clobber (reg:CC FLAGS_REG))])]
4710   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4711 {
4712   if (TARGET_FISTTP
4713       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4714    {
4715      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4716      DONE;
4717    }
4718   if (SSE_FLOAT_MODE_P (<MODE>mode))
4719    {
4720      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4721      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4722      if (out != operands[0])
4723         emit_move_insn (operands[0], out);
4724      DONE;
4725    }
4726 })
4727
4728 ;; Signed conversion to HImode.
4729
4730 (define_expand "fix_trunc<mode>hi2"
4731   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4732                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4733               (clobber (reg:CC FLAGS_REG))])]
4734   "TARGET_80387
4735    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4736 {
4737   if (TARGET_FISTTP)
4738    {
4739      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4740      DONE;
4741    }
4742 })
4743
4744 ;; Unsigned conversion to SImode.
4745
4746 (define_expand "fixuns_trunc<mode>si2"
4747   [(parallel
4748     [(set (match_operand:SI 0 "register_operand" "")
4749           (unsigned_fix:SI
4750             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4751      (use (match_dup 2))
4752      (clobber (match_scratch:<ssevecmode> 3 ""))
4753      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4754   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4755 {
4756   enum machine_mode mode = <MODE>mode;
4757   enum machine_mode vecmode = <ssevecmode>mode;
4758   REAL_VALUE_TYPE TWO31r;
4759   rtx two31;
4760
4761   if (optimize_insn_for_size_p ())
4762     FAIL;
4763
4764   real_ldexp (&TWO31r, &dconst1, 31);
4765   two31 = const_double_from_real_value (TWO31r, mode);
4766   two31 = ix86_build_const_vector (mode, true, two31);
4767   operands[2] = force_reg (vecmode, two31);
4768 })
4769
4770 (define_insn_and_split "*fixuns_trunc<mode>_1"
4771   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4772         (unsigned_fix:SI
4773           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4774    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4775    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4776    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4777   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4778    && optimize_function_for_speed_p (cfun)"
4779   "#"
4780   "&& reload_completed"
4781   [(const_int 0)]
4782 {
4783   ix86_split_convert_uns_si_sse (operands);
4784   DONE;
4785 })
4786
4787 ;; Unsigned conversion to HImode.
4788 ;; Without these patterns, we'll try the unsigned SI conversion which
4789 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4790
4791 (define_expand "fixuns_trunc<mode>hi2"
4792   [(set (match_dup 2)
4793         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4794    (set (match_operand:HI 0 "nonimmediate_operand" "")
4795         (subreg:HI (match_dup 2) 0))]
4796   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4797   "operands[2] = gen_reg_rtx (SImode);")
4798
4799 ;; When SSE is available, it is always faster to use it!
4800 (define_insn "fix_trunc<mode>di_sse"
4801   [(set (match_operand:DI 0 "register_operand" "=r,r")
4802         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4803   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4804    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4805   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4806   [(set_attr "type" "sseicvt")
4807    (set_attr "prefix" "maybe_vex")
4808    (set_attr "mode" "<MODE>")
4809    (set_attr "athlon_decode" "double,vector")
4810    (set_attr "amdfam10_decode" "double,double")])
4811
4812 (define_insn "fix_trunc<mode>si_sse"
4813   [(set (match_operand:SI 0 "register_operand" "=r,r")
4814         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4815   "SSE_FLOAT_MODE_P (<MODE>mode)
4816    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4817   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4818   [(set_attr "type" "sseicvt")
4819    (set_attr "prefix" "maybe_vex")
4820    (set_attr "mode" "<MODE>")
4821    (set_attr "athlon_decode" "double,vector")
4822    (set_attr "amdfam10_decode" "double,double")])
4823
4824 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4825 (define_peephole2
4826   [(set (match_operand:MODEF 0 "register_operand" "")
4827         (match_operand:MODEF 1 "memory_operand" ""))
4828    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4829         (fix:SSEMODEI24 (match_dup 0)))]
4830   "TARGET_SHORTEN_X87_SSE
4831    && peep2_reg_dead_p (2, operands[0])"
4832   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4833   "")
4834
4835 ;; Avoid vector decoded forms of the instruction.
4836 (define_peephole2
4837   [(match_scratch:DF 2 "Y2")
4838    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4839         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4840   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4841   [(set (match_dup 2) (match_dup 1))
4842    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4843   "")
4844
4845 (define_peephole2
4846   [(match_scratch:SF 2 "x")
4847    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4848         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4849   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4850   [(set (match_dup 2) (match_dup 1))
4851    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4852   "")
4853
4854 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4855   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4856         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4857   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4858    && TARGET_FISTTP
4859    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4860          && (TARGET_64BIT || <MODE>mode != DImode))
4861         && TARGET_SSE_MATH)
4862    && !(reload_completed || reload_in_progress)"
4863   "#"
4864   "&& 1"
4865   [(const_int 0)]
4866 {
4867   if (memory_operand (operands[0], VOIDmode))
4868     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4869   else
4870     {
4871       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4872       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4873                                                             operands[1],
4874                                                             operands[2]));
4875     }
4876   DONE;
4877 }
4878   [(set_attr "type" "fisttp")
4879    (set_attr "mode" "<MODE>")])
4880
4881 (define_insn "fix_trunc<mode>_i387_fisttp"
4882   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4883         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4884    (clobber (match_scratch:XF 2 "=&1f"))]
4885   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4886    && TARGET_FISTTP
4887    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4888          && (TARGET_64BIT || <MODE>mode != DImode))
4889         && TARGET_SSE_MATH)"
4890   "* return output_fix_trunc (insn, operands, 1);"
4891   [(set_attr "type" "fisttp")
4892    (set_attr "mode" "<MODE>")])
4893
4894 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4895   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4896         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4897    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4898    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4899   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4900    && TARGET_FISTTP
4901    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4902         && (TARGET_64BIT || <MODE>mode != DImode))
4903         && TARGET_SSE_MATH)"
4904   "#"
4905   [(set_attr "type" "fisttp")
4906    (set_attr "mode" "<MODE>")])
4907
4908 (define_split
4909   [(set (match_operand:X87MODEI 0 "register_operand" "")
4910         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4911    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4912    (clobber (match_scratch 3 ""))]
4913   "reload_completed"
4914   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4915               (clobber (match_dup 3))])
4916    (set (match_dup 0) (match_dup 2))]
4917   "")
4918
4919 (define_split
4920   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4921         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4922    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4923    (clobber (match_scratch 3 ""))]
4924   "reload_completed"
4925   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4926               (clobber (match_dup 3))])]
4927   "")
4928
4929 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4930 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4931 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4932 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4933 ;; function in i386.c.
4934 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4935   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4936         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4937    (clobber (reg:CC FLAGS_REG))]
4938   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4939    && !TARGET_FISTTP
4940    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4941          && (TARGET_64BIT || <MODE>mode != DImode))
4942    && !(reload_completed || reload_in_progress)"
4943   "#"
4944   "&& 1"
4945   [(const_int 0)]
4946 {
4947   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4948
4949   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4950   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4951   if (memory_operand (operands[0], VOIDmode))
4952     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4953                                          operands[2], operands[3]));
4954   else
4955     {
4956       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4957       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4958                                                      operands[2], operands[3],
4959                                                      operands[4]));
4960     }
4961   DONE;
4962 }
4963   [(set_attr "type" "fistp")
4964    (set_attr "i387_cw" "trunc")
4965    (set_attr "mode" "<MODE>")])
4966
4967 (define_insn "fix_truncdi_i387"
4968   [(set (match_operand:DI 0 "memory_operand" "=m")
4969         (fix:DI (match_operand 1 "register_operand" "f")))
4970    (use (match_operand:HI 2 "memory_operand" "m"))
4971    (use (match_operand:HI 3 "memory_operand" "m"))
4972    (clobber (match_scratch:XF 4 "=&1f"))]
4973   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4974    && !TARGET_FISTTP
4975    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4976   "* return output_fix_trunc (insn, operands, 0);"
4977   [(set_attr "type" "fistp")
4978    (set_attr "i387_cw" "trunc")
4979    (set_attr "mode" "DI")])
4980
4981 (define_insn "fix_truncdi_i387_with_temp"
4982   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4983         (fix:DI (match_operand 1 "register_operand" "f,f")))
4984    (use (match_operand:HI 2 "memory_operand" "m,m"))
4985    (use (match_operand:HI 3 "memory_operand" "m,m"))
4986    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4987    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4988   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4989    && !TARGET_FISTTP
4990    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4991   "#"
4992   [(set_attr "type" "fistp")
4993    (set_attr "i387_cw" "trunc")
4994    (set_attr "mode" "DI")])
4995
4996 (define_split
4997   [(set (match_operand:DI 0 "register_operand" "")
4998         (fix:DI (match_operand 1 "register_operand" "")))
4999    (use (match_operand:HI 2 "memory_operand" ""))
5000    (use (match_operand:HI 3 "memory_operand" ""))
5001    (clobber (match_operand:DI 4 "memory_operand" ""))
5002    (clobber (match_scratch 5 ""))]
5003   "reload_completed"
5004   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5005               (use (match_dup 2))
5006               (use (match_dup 3))
5007               (clobber (match_dup 5))])
5008    (set (match_dup 0) (match_dup 4))]
5009   "")
5010
5011 (define_split
5012   [(set (match_operand:DI 0 "memory_operand" "")
5013         (fix:DI (match_operand 1 "register_operand" "")))
5014    (use (match_operand:HI 2 "memory_operand" ""))
5015    (use (match_operand:HI 3 "memory_operand" ""))
5016    (clobber (match_operand:DI 4 "memory_operand" ""))
5017    (clobber (match_scratch 5 ""))]
5018   "reload_completed"
5019   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5020               (use (match_dup 2))
5021               (use (match_dup 3))
5022               (clobber (match_dup 5))])]
5023   "")
5024
5025 (define_insn "fix_trunc<mode>_i387"
5026   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5027         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5028    (use (match_operand:HI 2 "memory_operand" "m"))
5029    (use (match_operand:HI 3 "memory_operand" "m"))]
5030   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5031    && !TARGET_FISTTP
5032    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5033   "* return output_fix_trunc (insn, operands, 0);"
5034   [(set_attr "type" "fistp")
5035    (set_attr "i387_cw" "trunc")
5036    (set_attr "mode" "<MODE>")])
5037
5038 (define_insn "fix_trunc<mode>_i387_with_temp"
5039   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5040         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5041    (use (match_operand:HI 2 "memory_operand" "m,m"))
5042    (use (match_operand:HI 3 "memory_operand" "m,m"))
5043    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5044   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5045    && !TARGET_FISTTP
5046    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5047   "#"
5048   [(set_attr "type" "fistp")
5049    (set_attr "i387_cw" "trunc")
5050    (set_attr "mode" "<MODE>")])
5051
5052 (define_split
5053   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5054         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5055    (use (match_operand:HI 2 "memory_operand" ""))
5056    (use (match_operand:HI 3 "memory_operand" ""))
5057    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5058   "reload_completed"
5059   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5060               (use (match_dup 2))
5061               (use (match_dup 3))])
5062    (set (match_dup 0) (match_dup 4))]
5063   "")
5064
5065 (define_split
5066   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5067         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5068    (use (match_operand:HI 2 "memory_operand" ""))
5069    (use (match_operand:HI 3 "memory_operand" ""))
5070    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5071   "reload_completed"
5072   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5073               (use (match_dup 2))
5074               (use (match_dup 3))])]
5075   "")
5076
5077 (define_insn "x86_fnstcw_1"
5078   [(set (match_operand:HI 0 "memory_operand" "=m")
5079         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5080   "TARGET_80387"
5081   "fnstcw\t%0"
5082   [(set_attr "length" "2")
5083    (set_attr "mode" "HI")
5084    (set_attr "unit" "i387")])
5085
5086 (define_insn "x86_fldcw_1"
5087   [(set (reg:HI FPCR_REG)
5088         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5089   "TARGET_80387"
5090   "fldcw\t%0"
5091   [(set_attr "length" "2")
5092    (set_attr "mode" "HI")
5093    (set_attr "unit" "i387")
5094    (set_attr "athlon_decode" "vector")
5095    (set_attr "amdfam10_decode" "vector")])
5096 \f
5097 ;; Conversion between fixed point and floating point.
5098
5099 ;; Even though we only accept memory inputs, the backend _really_
5100 ;; wants to be able to do this between registers.
5101
5102 (define_expand "floathi<mode>2"
5103   [(set (match_operand:X87MODEF 0 "register_operand" "")
5104         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5105   "TARGET_80387
5106    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5107        || TARGET_MIX_SSE_I387)"
5108   "")
5109
5110 ;; Pre-reload splitter to add memory clobber to the pattern.
5111 (define_insn_and_split "*floathi<mode>2_1"
5112   [(set (match_operand:X87MODEF 0 "register_operand" "")
5113         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5114   "TARGET_80387
5115    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5116        || TARGET_MIX_SSE_I387)
5117    && !(reload_completed || reload_in_progress)"
5118   "#"
5119   "&& 1"
5120   [(parallel [(set (match_dup 0)
5121               (float:X87MODEF (match_dup 1)))
5122    (clobber (match_dup 2))])]
5123   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5124
5125 (define_insn "*floathi<mode>2_i387_with_temp"
5126   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5127         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5128   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5129   "TARGET_80387
5130    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5131        || TARGET_MIX_SSE_I387)"
5132   "#"
5133   [(set_attr "type" "fmov,multi")
5134    (set_attr "mode" "<MODE>")
5135    (set_attr "unit" "*,i387")
5136    (set_attr "fp_int_src" "true")])
5137
5138 (define_insn "*floathi<mode>2_i387"
5139   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5140         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5141   "TARGET_80387
5142    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5143        || TARGET_MIX_SSE_I387)"
5144   "fild%Z1\t%1"
5145   [(set_attr "type" "fmov")
5146    (set_attr "mode" "<MODE>")
5147    (set_attr "fp_int_src" "true")])
5148
5149 (define_split
5150   [(set (match_operand:X87MODEF 0 "register_operand" "")
5151         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5152    (clobber (match_operand:HI 2 "memory_operand" ""))]
5153   "TARGET_80387
5154    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5155        || TARGET_MIX_SSE_I387)
5156    && reload_completed"
5157   [(set (match_dup 2) (match_dup 1))
5158    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5159   "")
5160
5161 (define_split
5162   [(set (match_operand:X87MODEF 0 "register_operand" "")
5163         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5164    (clobber (match_operand:HI 2 "memory_operand" ""))]
5165    "TARGET_80387
5166     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5167         || TARGET_MIX_SSE_I387)
5168     && reload_completed"
5169   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5170   "")
5171
5172 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5173   [(set (match_operand:X87MODEF 0 "register_operand" "")
5174         (float:X87MODEF
5175           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5176   "TARGET_80387
5177    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5178        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5179   "
5180 {
5181   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5182         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5183       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5184     {
5185       rtx reg = gen_reg_rtx (XFmode);
5186       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5187 /* Avoid references to nonexistent function in dead code in XFmode case.  */
5188 #define gen_truncxfxf2 gen_truncxfdf2
5189       emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5190 #undef gen_truncxfxf2
5191       DONE;
5192     }
5193 }")
5194
5195 ;; Pre-reload splitter to add memory clobber to the pattern.
5196 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5197   [(set (match_operand:X87MODEF 0 "register_operand" "")
5198         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5199   "((TARGET_80387
5200      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5201      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5202            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5203          || TARGET_MIX_SSE_I387))
5204     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5205         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5206         && ((<SSEMODEI24:MODE>mode == SImode
5207              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5208              && optimize_function_for_speed_p (cfun)
5209              && flag_trapping_math)
5210             || !(TARGET_INTER_UNIT_CONVERSIONS
5211                  || optimize_function_for_size_p (cfun)))))
5212    && !(reload_completed || reload_in_progress)"
5213   "#"
5214   "&& 1"
5215   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5216               (clobber (match_dup 2))])]
5217 {
5218   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5219
5220   /* Avoid store forwarding (partial memory) stall penalty
5221      by passing DImode value through XMM registers.  */
5222   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5223       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5224       && optimize_function_for_speed_p (cfun))
5225     {
5226       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5227                                                             operands[1],
5228                                                             operands[2]));
5229       DONE;
5230     }
5231 })
5232
5233 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5234   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5235         (float:MODEF
5236           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5237    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5238   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5239    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5240   "#"
5241   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5242    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5243    (set_attr "unit" "*,i387,*,*,*")
5244    (set_attr "athlon_decode" "*,*,double,direct,double")
5245    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5246    (set_attr "fp_int_src" "true")])
5247
5248 (define_insn "*floatsi<mode>2_vector_mixed"
5249   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5250         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5251   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5252    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5253   "@
5254    fild%Z1\t%1
5255    #"
5256   [(set_attr "type" "fmov,sseicvt")
5257    (set_attr "mode" "<MODE>,<ssevecmode>")
5258    (set_attr "unit" "i387,*")
5259    (set_attr "athlon_decode" "*,direct")
5260    (set_attr "amdfam10_decode" "*,double")
5261    (set_attr "fp_int_src" "true")])
5262
5263 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5264   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5265         (float:MODEF
5266           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5267   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5268   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5269    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5270   "#"
5271   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5272    (set_attr "mode" "<MODEF:MODE>")
5273    (set_attr "unit" "*,i387,*,*")
5274    (set_attr "athlon_decode" "*,*,double,direct")
5275    (set_attr "amdfam10_decode" "*,*,vector,double")
5276    (set_attr "fp_int_src" "true")])
5277
5278 (define_split
5279   [(set (match_operand:MODEF 0 "register_operand" "")
5280         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5281    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5282   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5283    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5284    && TARGET_INTER_UNIT_CONVERSIONS
5285    && reload_completed
5286    && (SSE_REG_P (operands[0])
5287        || (GET_CODE (operands[0]) == SUBREG
5288            && SSE_REG_P (operands[0])))"
5289   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5290   "")
5291
5292 (define_split
5293   [(set (match_operand:MODEF 0 "register_operand" "")
5294         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5295    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5296   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5297    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5298    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5299    && reload_completed
5300    && (SSE_REG_P (operands[0])
5301        || (GET_CODE (operands[0]) == SUBREG
5302            && SSE_REG_P (operands[0])))"
5303   [(set (match_dup 2) (match_dup 1))
5304    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5305   "")
5306
5307 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5308   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5309         (float:MODEF
5310           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5311   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5312    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5313    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5314   "@
5315    fild%Z1\t%1
5316    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5317    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5318   [(set_attr "type" "fmov,sseicvt,sseicvt")
5319    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5320    (set_attr "mode" "<MODEF:MODE>")
5321    (set_attr "unit" "i387,*,*")
5322    (set_attr "athlon_decode" "*,double,direct")
5323    (set_attr "amdfam10_decode" "*,vector,double")
5324    (set_attr "fp_int_src" "true")])
5325
5326 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5327   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5328         (float:MODEF
5329           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5330   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5331    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5332    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5333   "@
5334    fild%Z1\t%1
5335    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5336   [(set_attr "type" "fmov,sseicvt")
5337    (set_attr "prefix" "orig,maybe_vex")
5338    (set_attr "mode" "<MODEF:MODE>")
5339    (set_attr "athlon_decode" "*,direct")
5340    (set_attr "amdfam10_decode" "*,double")
5341    (set_attr "fp_int_src" "true")])
5342
5343 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5344   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5345         (float:MODEF
5346           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5347    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5348   "TARGET_SSE2 && TARGET_SSE_MATH
5349    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5350   "#"
5351   [(set_attr "type" "sseicvt")
5352    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5353    (set_attr "athlon_decode" "double,direct,double")
5354    (set_attr "amdfam10_decode" "vector,double,double")
5355    (set_attr "fp_int_src" "true")])
5356
5357 (define_insn "*floatsi<mode>2_vector_sse"
5358   [(set (match_operand:MODEF 0 "register_operand" "=x")
5359         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5360   "TARGET_SSE2 && TARGET_SSE_MATH
5361    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5362   "#"
5363   [(set_attr "type" "sseicvt")
5364    (set_attr "mode" "<MODE>")
5365    (set_attr "athlon_decode" "direct")
5366    (set_attr "amdfam10_decode" "double")
5367    (set_attr "fp_int_src" "true")])
5368
5369 (define_split
5370   [(set (match_operand:MODEF 0 "register_operand" "")
5371         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5372    (clobber (match_operand:SI 2 "memory_operand" ""))]
5373   "TARGET_SSE2 && TARGET_SSE_MATH
5374    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5375    && reload_completed
5376    && (SSE_REG_P (operands[0])
5377        || (GET_CODE (operands[0]) == SUBREG
5378            && SSE_REG_P (operands[0])))"
5379   [(const_int 0)]
5380 {
5381   rtx op1 = operands[1];
5382
5383   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5384                                      <MODE>mode, 0);
5385   if (GET_CODE (op1) == SUBREG)
5386     op1 = SUBREG_REG (op1);
5387
5388   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5389     {
5390       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5391       emit_insn (gen_sse2_loadld (operands[4],
5392                                   CONST0_RTX (V4SImode), operands[1]));
5393     }
5394   /* We can ignore possible trapping value in the
5395      high part of SSE register for non-trapping math. */
5396   else if (SSE_REG_P (op1) && !flag_trapping_math)
5397     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5398   else
5399     {
5400       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5401       emit_move_insn (operands[2], operands[1]);
5402       emit_insn (gen_sse2_loadld (operands[4],
5403                                   CONST0_RTX (V4SImode), operands[2]));
5404     }
5405   emit_insn
5406     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5407   DONE;
5408 })
5409
5410 (define_split
5411   [(set (match_operand:MODEF 0 "register_operand" "")
5412         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5413    (clobber (match_operand:SI 2 "memory_operand" ""))]
5414   "TARGET_SSE2 && TARGET_SSE_MATH
5415    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5416    && reload_completed
5417    && (SSE_REG_P (operands[0])
5418        || (GET_CODE (operands[0]) == SUBREG
5419            && SSE_REG_P (operands[0])))"
5420   [(const_int 0)]
5421 {
5422   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5423                                      <MODE>mode, 0);
5424   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5425
5426   emit_insn (gen_sse2_loadld (operands[4],
5427                               CONST0_RTX (V4SImode), operands[1]));
5428   emit_insn
5429     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5430   DONE;
5431 })
5432
5433 (define_split
5434   [(set (match_operand:MODEF 0 "register_operand" "")
5435         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5436   "TARGET_SSE2 && TARGET_SSE_MATH
5437    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5438    && reload_completed
5439    && (SSE_REG_P (operands[0])
5440        || (GET_CODE (operands[0]) == SUBREG
5441            && SSE_REG_P (operands[0])))"
5442   [(const_int 0)]
5443 {
5444   rtx op1 = operands[1];
5445
5446   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5447                                      <MODE>mode, 0);
5448   if (GET_CODE (op1) == SUBREG)
5449     op1 = SUBREG_REG (op1);
5450
5451   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5452     {
5453       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5454       emit_insn (gen_sse2_loadld (operands[4],
5455                                   CONST0_RTX (V4SImode), operands[1]));
5456     }
5457   /* We can ignore possible trapping value in the
5458      high part of SSE register for non-trapping math. */
5459   else if (SSE_REG_P (op1) && !flag_trapping_math)
5460     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5461   else
5462     gcc_unreachable ();
5463   emit_insn
5464     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5465   DONE;
5466 })
5467
5468 (define_split
5469   [(set (match_operand:MODEF 0 "register_operand" "")
5470         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5471   "TARGET_SSE2 && TARGET_SSE_MATH
5472    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5473    && reload_completed
5474    && (SSE_REG_P (operands[0])
5475        || (GET_CODE (operands[0]) == SUBREG
5476            && SSE_REG_P (operands[0])))"
5477   [(const_int 0)]
5478 {
5479   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5480                                      <MODE>mode, 0);
5481   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5482
5483   emit_insn (gen_sse2_loadld (operands[4],
5484                               CONST0_RTX (V4SImode), operands[1]));
5485   emit_insn
5486     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5487   DONE;
5488 })
5489
5490 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5491   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5492         (float:MODEF
5493           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5494   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5495   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5496    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5497   "#"
5498   [(set_attr "type" "sseicvt")
5499    (set_attr "mode" "<MODEF:MODE>")
5500    (set_attr "athlon_decode" "double,direct")
5501    (set_attr "amdfam10_decode" "vector,double")
5502    (set_attr "fp_int_src" "true")])
5503
5504 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5505   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5506         (float:MODEF
5507           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5508   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5509    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5510    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5511   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5512   [(set_attr "type" "sseicvt")
5513    (set_attr "prefix" "maybe_vex")
5514    (set_attr "mode" "<MODEF:MODE>")
5515    (set_attr "athlon_decode" "double,direct")
5516    (set_attr "amdfam10_decode" "vector,double")
5517    (set_attr "fp_int_src" "true")])
5518
5519 (define_split
5520   [(set (match_operand:MODEF 0 "register_operand" "")
5521         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5522    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5523   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5524    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5525    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5526    && reload_completed
5527    && (SSE_REG_P (operands[0])
5528        || (GET_CODE (operands[0]) == SUBREG
5529            && SSE_REG_P (operands[0])))"
5530   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5531   "")
5532
5533 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5534   [(set (match_operand:MODEF 0 "register_operand" "=x")
5535         (float:MODEF
5536           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5537   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5538    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5539    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5540   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5541   [(set_attr "type" "sseicvt")
5542    (set_attr "prefix" "maybe_vex")
5543    (set_attr "mode" "<MODEF:MODE>")
5544    (set_attr "athlon_decode" "direct")
5545    (set_attr "amdfam10_decode" "double")
5546    (set_attr "fp_int_src" "true")])
5547
5548 (define_split
5549   [(set (match_operand:MODEF 0 "register_operand" "")
5550         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5551    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5552   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5553    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5554    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5555    && reload_completed
5556    && (SSE_REG_P (operands[0])
5557        || (GET_CODE (operands[0]) == SUBREG
5558            && SSE_REG_P (operands[0])))"
5559   [(set (match_dup 2) (match_dup 1))
5560    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5561   "")
5562
5563 (define_split
5564   [(set (match_operand:MODEF 0 "register_operand" "")
5565         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5566    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5567   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5568    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5569    && reload_completed
5570    && (SSE_REG_P (operands[0])
5571        || (GET_CODE (operands[0]) == SUBREG
5572            && SSE_REG_P (operands[0])))"
5573   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5574   "")
5575
5576 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5577   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5578         (float:X87MODEF
5579           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5580   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5581   "TARGET_80387
5582    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5583   "@
5584    fild%Z1\t%1
5585    #"
5586   [(set_attr "type" "fmov,multi")
5587    (set_attr "mode" "<X87MODEF:MODE>")
5588    (set_attr "unit" "*,i387")
5589    (set_attr "fp_int_src" "true")])
5590
5591 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5592   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5593         (float:X87MODEF
5594           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5595   "TARGET_80387
5596    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5597   "fild%Z1\t%1"
5598   [(set_attr "type" "fmov")
5599    (set_attr "mode" "<X87MODEF:MODE>")
5600    (set_attr "fp_int_src" "true")])
5601
5602 (define_split
5603   [(set (match_operand:X87MODEF 0 "register_operand" "")
5604         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5605    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5606   "TARGET_80387
5607    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5608    && reload_completed
5609    && FP_REG_P (operands[0])"
5610   [(set (match_dup 2) (match_dup 1))
5611    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5612   "")
5613
5614 (define_split
5615   [(set (match_operand:X87MODEF 0 "register_operand" "")
5616         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5617    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5618   "TARGET_80387
5619    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5620    && reload_completed
5621    && FP_REG_P (operands[0])"
5622   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5623   "")
5624
5625 ;; Avoid store forwarding (partial memory) stall penalty
5626 ;; by passing DImode value through XMM registers.  */
5627
5628 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5629   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5630         (float:X87MODEF
5631           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5632    (clobber (match_scratch:V4SI 3 "=X,x"))
5633    (clobber (match_scratch:V4SI 4 "=X,x"))
5634    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5635   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5636    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5637    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5638   "#"
5639   [(set_attr "type" "multi")
5640    (set_attr "mode" "<X87MODEF:MODE>")
5641    (set_attr "unit" "i387")
5642    (set_attr "fp_int_src" "true")])
5643
5644 (define_split
5645   [(set (match_operand:X87MODEF 0 "register_operand" "")
5646         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5647    (clobber (match_scratch:V4SI 3 ""))
5648    (clobber (match_scratch:V4SI 4 ""))
5649    (clobber (match_operand:DI 2 "memory_operand" ""))]
5650   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5651    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5652    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5653    && reload_completed
5654    && FP_REG_P (operands[0])"
5655   [(set (match_dup 2) (match_dup 3))
5656    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5657 {
5658   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5659      Assemble the 64-bit DImode value in an xmm register.  */
5660   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5661                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5662   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5663                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5664   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5665
5666   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5667 })
5668
5669 (define_split
5670   [(set (match_operand:X87MODEF 0 "register_operand" "")
5671         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5672    (clobber (match_scratch:V4SI 3 ""))
5673    (clobber (match_scratch:V4SI 4 ""))
5674    (clobber (match_operand:DI 2 "memory_operand" ""))]
5675   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5676    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5677    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5678    && reload_completed
5679    && FP_REG_P (operands[0])"
5680   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5681   "")
5682
5683 ;; Avoid store forwarding (partial memory) stall penalty by extending
5684 ;; SImode value to DImode through XMM register instead of pushing two
5685 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5686 ;; targets benefit from this optimization. Also note that fild
5687 ;; loads from memory only.
5688
5689 (define_insn "*floatunssi<mode>2_1"
5690   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5691         (unsigned_float:X87MODEF
5692           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5693    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5694    (clobber (match_scratch:SI 3 "=X,x"))]
5695   "!TARGET_64BIT
5696    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5697    && TARGET_SSE"
5698   "#"
5699   [(set_attr "type" "multi")
5700    (set_attr "mode" "<MODE>")])
5701
5702 (define_split
5703   [(set (match_operand:X87MODEF 0 "register_operand" "")
5704         (unsigned_float:X87MODEF
5705           (match_operand:SI 1 "register_operand" "")))
5706    (clobber (match_operand:DI 2 "memory_operand" ""))
5707    (clobber (match_scratch:SI 3 ""))]
5708   "!TARGET_64BIT
5709    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5710    && TARGET_SSE
5711    && reload_completed"
5712   [(set (match_dup 2) (match_dup 1))
5713    (set (match_dup 0)
5714         (float:X87MODEF (match_dup 2)))]
5715   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5716
5717 (define_split
5718   [(set (match_operand:X87MODEF 0 "register_operand" "")
5719         (unsigned_float:X87MODEF
5720           (match_operand:SI 1 "memory_operand" "")))
5721    (clobber (match_operand:DI 2 "memory_operand" ""))
5722    (clobber (match_scratch:SI 3 ""))]
5723   "!TARGET_64BIT
5724    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5725    && TARGET_SSE
5726    && reload_completed"
5727   [(set (match_dup 2) (match_dup 3))
5728    (set (match_dup 0)
5729         (float:X87MODEF (match_dup 2)))]
5730 {
5731   emit_move_insn (operands[3], operands[1]);
5732   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5733 })
5734
5735 (define_expand "floatunssi<mode>2"
5736   [(parallel
5737      [(set (match_operand:X87MODEF 0 "register_operand" "")
5738            (unsigned_float:X87MODEF
5739              (match_operand:SI 1 "nonimmediate_operand" "")))
5740       (clobber (match_dup 2))
5741       (clobber (match_scratch:SI 3 ""))])]
5742   "!TARGET_64BIT
5743    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5744         && TARGET_SSE)
5745        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5746 {
5747   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5748     {
5749       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5750       DONE;
5751     }
5752   else
5753     {
5754       enum ix86_stack_slot slot = (virtuals_instantiated
5755                                    ? SLOT_TEMP
5756                                    : SLOT_VIRTUAL);
5757       operands[2] = assign_386_stack_local (DImode, slot);
5758     }
5759 })
5760
5761 (define_expand "floatunsdisf2"
5762   [(use (match_operand:SF 0 "register_operand" ""))
5763    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5764   "TARGET_64BIT && TARGET_SSE_MATH"
5765   "x86_emit_floatuns (operands); DONE;")
5766
5767 (define_expand "floatunsdidf2"
5768   [(use (match_operand:DF 0 "register_operand" ""))
5769    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5770   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5771    && TARGET_SSE2 && TARGET_SSE_MATH"
5772 {
5773   if (TARGET_64BIT)
5774     x86_emit_floatuns (operands);
5775   else
5776     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5777   DONE;
5778 })
5779 \f
5780 ;; Add instructions
5781
5782 ;; %%% splits for addditi3
5783
5784 (define_expand "addti3"
5785   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5786         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5787                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5788   "TARGET_64BIT"
5789   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5790
5791 (define_insn "*addti3_1"
5792   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5793         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5794                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5795    (clobber (reg:CC FLAGS_REG))]
5796   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5797   "#")
5798
5799 (define_split
5800   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5801         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5802                  (match_operand:TI 2 "x86_64_general_operand" "")))
5803    (clobber (reg:CC FLAGS_REG))]
5804   "TARGET_64BIT && reload_completed"
5805   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5806                                           UNSPEC_ADD_CARRY))
5807               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5808    (parallel [(set (match_dup 3)
5809                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5810                                      (match_dup 4))
5811                             (match_dup 5)))
5812               (clobber (reg:CC FLAGS_REG))])]
5813   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5814
5815 ;; %%% splits for addsidi3
5816 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5817 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5818 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5819
5820 (define_expand "adddi3"
5821   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5822         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5823                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5824   ""
5825   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5826
5827 (define_insn "*adddi3_1"
5828   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5829         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5830                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5831    (clobber (reg:CC FLAGS_REG))]
5832   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5833   "#")
5834
5835 (define_split
5836   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5837         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5838                  (match_operand:DI 2 "general_operand" "")))
5839    (clobber (reg:CC FLAGS_REG))]
5840   "!TARGET_64BIT && reload_completed"
5841   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5842                                           UNSPEC_ADD_CARRY))
5843               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5844    (parallel [(set (match_dup 3)
5845                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5846                                      (match_dup 4))
5847                             (match_dup 5)))
5848               (clobber (reg:CC FLAGS_REG))])]
5849   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5850
5851 (define_insn "adddi3_carry_rex64"
5852   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5853           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5854                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5855                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5856    (clobber (reg:CC FLAGS_REG))]
5857   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5858   "adc{q}\t{%2, %0|%0, %2}"
5859   [(set_attr "type" "alu")
5860    (set_attr "use_carry" "1")
5861    (set_attr "pent_pair" "pu")
5862    (set_attr "mode" "DI")])
5863
5864 (define_insn "*adddi3_cc_rex64"
5865   [(set (reg:CC FLAGS_REG)
5866         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5867                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5868                    UNSPEC_ADD_CARRY))
5869    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5870         (plus:DI (match_dup 1) (match_dup 2)))]
5871   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5872   "add{q}\t{%2, %0|%0, %2}"
5873   [(set_attr "type" "alu")
5874    (set_attr "mode" "DI")])
5875
5876 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5877   [(set (reg:CCC FLAGS_REG)
5878         (compare:CCC
5879             (plusminus:SWI
5880                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5881                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5882             (match_dup 1)))
5883    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5884         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5885   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5886   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5887   [(set_attr "type" "alu")
5888    (set_attr "mode" "<MODE>")])
5889
5890 (define_insn "*add<mode>3_cconly_overflow"
5891   [(set (reg:CCC FLAGS_REG)
5892         (compare:CCC
5893                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5894                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5895                 (match_dup 1)))
5896    (clobber (match_scratch:SWI 0 "=<r>"))]
5897   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5898   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5899   [(set_attr "type" "alu")
5900    (set_attr "mode" "<MODE>")])
5901
5902 (define_insn "*sub<mode>3_cconly_overflow"
5903   [(set (reg:CCC FLAGS_REG)
5904         (compare:CCC
5905              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5906                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5907              (match_dup 0)))]
5908   ""
5909   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5910   [(set_attr "type" "icmp")
5911    (set_attr "mode" "<MODE>")])
5912
5913 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5914   [(set (reg:CCC FLAGS_REG)
5915         (compare:CCC
5916             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5917                           (match_operand:SI 2 "general_operand" "g"))
5918             (match_dup 1)))
5919    (set (match_operand:DI 0 "register_operand" "=r")
5920         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5921   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5922   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5923   [(set_attr "type" "alu")
5924    (set_attr "mode" "SI")])
5925
5926 (define_insn "addqi3_carry"
5927   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5928           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5929                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5930                    (match_operand:QI 2 "general_operand" "qn,qm")))
5931    (clobber (reg:CC FLAGS_REG))]
5932   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5933   "adc{b}\t{%2, %0|%0, %2}"
5934   [(set_attr "type" "alu")
5935    (set_attr "use_carry" "1")
5936    (set_attr "pent_pair" "pu")
5937    (set_attr "mode" "QI")])
5938
5939 (define_insn "addhi3_carry"
5940   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5941           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5942                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5943                    (match_operand:HI 2 "general_operand" "rn,rm")))
5944    (clobber (reg:CC FLAGS_REG))]
5945   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5946   "adc{w}\t{%2, %0|%0, %2}"
5947   [(set_attr "type" "alu")
5948    (set_attr "use_carry" "1")
5949    (set_attr "pent_pair" "pu")
5950    (set_attr "mode" "HI")])
5951
5952 (define_insn "addsi3_carry"
5953   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5954           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5955                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5956                    (match_operand:SI 2 "general_operand" "ri,rm")))
5957    (clobber (reg:CC FLAGS_REG))]
5958   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5959   "adc{l}\t{%2, %0|%0, %2}"
5960   [(set_attr "type" "alu")
5961    (set_attr "use_carry" "1")
5962    (set_attr "pent_pair" "pu")
5963    (set_attr "mode" "SI")])
5964
5965 (define_insn "*addsi3_carry_zext"
5966   [(set (match_operand:DI 0 "register_operand" "=r")
5967           (zero_extend:DI
5968             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5969                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5970                      (match_operand:SI 2 "general_operand" "g"))))
5971    (clobber (reg:CC FLAGS_REG))]
5972   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5973   "adc{l}\t{%2, %k0|%k0, %2}"
5974   [(set_attr "type" "alu")
5975    (set_attr "use_carry" "1")
5976    (set_attr "pent_pair" "pu")
5977    (set_attr "mode" "SI")])
5978
5979 (define_insn "*addsi3_cc"
5980   [(set (reg:CC FLAGS_REG)
5981         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5982                     (match_operand:SI 2 "general_operand" "ri,rm")]
5983                    UNSPEC_ADD_CARRY))
5984    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5985         (plus:SI (match_dup 1) (match_dup 2)))]
5986   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5987   "add{l}\t{%2, %0|%0, %2}"
5988   [(set_attr "type" "alu")
5989    (set_attr "mode" "SI")])
5990
5991 (define_insn "addqi3_cc"
5992   [(set (reg:CC FLAGS_REG)
5993         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5994                     (match_operand:QI 2 "general_operand" "qn,qm")]
5995                    UNSPEC_ADD_CARRY))
5996    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5997         (plus:QI (match_dup 1) (match_dup 2)))]
5998   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5999   "add{b}\t{%2, %0|%0, %2}"
6000   [(set_attr "type" "alu")
6001    (set_attr "mode" "QI")])
6002
6003 (define_expand "addsi3"
6004   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6005         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6006                  (match_operand:SI 2 "general_operand" "")))]
6007   ""
6008   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
6009
6010 (define_insn "*lea_1"
6011   [(set (match_operand:SI 0 "register_operand" "=r")
6012         (match_operand:SI 1 "no_seg_address_operand" "p"))]
6013   "!TARGET_64BIT"
6014   "lea{l}\t{%a1, %0|%0, %a1}"
6015   [(set_attr "type" "lea")
6016    (set_attr "mode" "SI")])
6017
6018 (define_insn "*lea_1_rex64"
6019   [(set (match_operand:SI 0 "register_operand" "=r")
6020         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6021   "TARGET_64BIT"
6022   "lea{l}\t{%a1, %0|%0, %a1}"
6023   [(set_attr "type" "lea")
6024    (set_attr "mode" "SI")])
6025
6026 (define_insn "*lea_1_zext"
6027   [(set (match_operand:DI 0 "register_operand" "=r")
6028         (zero_extend:DI
6029          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6030   "TARGET_64BIT"
6031   "lea{l}\t{%a1, %k0|%k0, %a1}"
6032   [(set_attr "type" "lea")
6033    (set_attr "mode" "SI")])
6034
6035 (define_insn "*lea_2_rex64"
6036   [(set (match_operand:DI 0 "register_operand" "=r")
6037         (match_operand:DI 1 "no_seg_address_operand" "p"))]
6038   "TARGET_64BIT"
6039   "lea{q}\t{%a1, %0|%0, %a1}"
6040   [(set_attr "type" "lea")
6041    (set_attr "mode" "DI")])
6042
6043 ;; The lea patterns for non-Pmodes needs to be matched by several
6044 ;; insns converted to real lea by splitters.
6045
6046 (define_insn_and_split "*lea_general_1"
6047   [(set (match_operand 0 "register_operand" "=r")
6048         (plus (plus (match_operand 1 "index_register_operand" "l")
6049                     (match_operand 2 "register_operand" "r"))
6050               (match_operand 3 "immediate_operand" "i")))]
6051   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6052     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6053    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6054    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6055    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6056    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6057        || GET_MODE (operands[3]) == VOIDmode)"
6058   "#"
6059   "&& reload_completed"
6060   [(const_int 0)]
6061 {
6062   rtx pat;
6063   operands[0] = gen_lowpart (SImode, operands[0]);
6064   operands[1] = gen_lowpart (Pmode, operands[1]);
6065   operands[2] = gen_lowpart (Pmode, operands[2]);
6066   operands[3] = gen_lowpart (Pmode, operands[3]);
6067   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6068                       operands[3]);
6069   if (Pmode != SImode)
6070     pat = gen_rtx_SUBREG (SImode, pat, 0);
6071   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6072   DONE;
6073 }
6074   [(set_attr "type" "lea")
6075    (set_attr "mode" "SI")])
6076
6077 (define_insn_and_split "*lea_general_1_zext"
6078   [(set (match_operand:DI 0 "register_operand" "=r")
6079         (zero_extend:DI
6080           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6081                             (match_operand:SI 2 "register_operand" "r"))
6082                    (match_operand:SI 3 "immediate_operand" "i"))))]
6083   "TARGET_64BIT"
6084   "#"
6085   "&& reload_completed"
6086   [(set (match_dup 0)
6087         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6088                                                      (match_dup 2))
6089                                             (match_dup 3)) 0)))]
6090 {
6091   operands[1] = gen_lowpart (Pmode, operands[1]);
6092   operands[2] = gen_lowpart (Pmode, operands[2]);
6093   operands[3] = gen_lowpart (Pmode, operands[3]);
6094 }
6095   [(set_attr "type" "lea")
6096    (set_attr "mode" "SI")])
6097
6098 (define_insn_and_split "*lea_general_2"
6099   [(set (match_operand 0 "register_operand" "=r")
6100         (plus (mult (match_operand 1 "index_register_operand" "l")
6101                     (match_operand 2 "const248_operand" "i"))
6102               (match_operand 3 "nonmemory_operand" "ri")))]
6103   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6104     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6105    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6106    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6107    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6108        || GET_MODE (operands[3]) == VOIDmode)"
6109   "#"
6110   "&& reload_completed"
6111   [(const_int 0)]
6112 {
6113   rtx pat;
6114   operands[0] = gen_lowpart (SImode, operands[0]);
6115   operands[1] = gen_lowpart (Pmode, operands[1]);
6116   operands[3] = gen_lowpart (Pmode, operands[3]);
6117   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6118                       operands[3]);
6119   if (Pmode != SImode)
6120     pat = gen_rtx_SUBREG (SImode, pat, 0);
6121   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6122   DONE;
6123 }
6124   [(set_attr "type" "lea")
6125    (set_attr "mode" "SI")])
6126
6127 (define_insn_and_split "*lea_general_2_zext"
6128   [(set (match_operand:DI 0 "register_operand" "=r")
6129         (zero_extend:DI
6130           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6131                             (match_operand:SI 2 "const248_operand" "n"))
6132                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6133   "TARGET_64BIT"
6134   "#"
6135   "&& reload_completed"
6136   [(set (match_dup 0)
6137         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6138                                                      (match_dup 2))
6139                                             (match_dup 3)) 0)))]
6140 {
6141   operands[1] = gen_lowpart (Pmode, operands[1]);
6142   operands[3] = gen_lowpart (Pmode, operands[3]);
6143 }
6144   [(set_attr "type" "lea")
6145    (set_attr "mode" "SI")])
6146
6147 (define_insn_and_split "*lea_general_3"
6148   [(set (match_operand 0 "register_operand" "=r")
6149         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6150                           (match_operand 2 "const248_operand" "i"))
6151                     (match_operand 3 "register_operand" "r"))
6152               (match_operand 4 "immediate_operand" "i")))]
6153   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6154     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6155    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6156    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6157    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6158   "#"
6159   "&& reload_completed"
6160   [(const_int 0)]
6161 {
6162   rtx pat;
6163   operands[0] = gen_lowpart (SImode, operands[0]);
6164   operands[1] = gen_lowpart (Pmode, operands[1]);
6165   operands[3] = gen_lowpart (Pmode, operands[3]);
6166   operands[4] = gen_lowpart (Pmode, operands[4]);
6167   pat = gen_rtx_PLUS (Pmode,
6168                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6169                                                          operands[2]),
6170                                     operands[3]),
6171                       operands[4]);
6172   if (Pmode != SImode)
6173     pat = gen_rtx_SUBREG (SImode, pat, 0);
6174   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6175   DONE;
6176 }
6177   [(set_attr "type" "lea")
6178    (set_attr "mode" "SI")])
6179
6180 (define_insn_and_split "*lea_general_3_zext"
6181   [(set (match_operand:DI 0 "register_operand" "=r")
6182         (zero_extend:DI
6183           (plus:SI (plus:SI (mult:SI
6184                               (match_operand:SI 1 "index_register_operand" "l")
6185                               (match_operand:SI 2 "const248_operand" "n"))
6186                             (match_operand:SI 3 "register_operand" "r"))
6187                    (match_operand:SI 4 "immediate_operand" "i"))))]
6188   "TARGET_64BIT"
6189   "#"
6190   "&& reload_completed"
6191   [(set (match_dup 0)
6192         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6193                                                               (match_dup 2))
6194                                                      (match_dup 3))
6195                                             (match_dup 4)) 0)))]
6196 {
6197   operands[1] = gen_lowpart (Pmode, operands[1]);
6198   operands[3] = gen_lowpart (Pmode, operands[3]);
6199   operands[4] = gen_lowpart (Pmode, operands[4]);
6200 }
6201   [(set_attr "type" "lea")
6202    (set_attr "mode" "SI")])
6203
6204 (define_insn "*adddi_1_rex64"
6205   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
6206         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
6207                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
6208    (clobber (reg:CC FLAGS_REG))]
6209   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6210 {
6211   switch (get_attr_type (insn))
6212     {
6213     case TYPE_LEA:
6214       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6215       return "lea{q}\t{%a2, %0|%0, %a2}";
6216
6217     case TYPE_INCDEC:
6218       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6219       if (operands[2] == const1_rtx)
6220         return "inc{q}\t%0";
6221       else
6222         {
6223           gcc_assert (operands[2] == constm1_rtx);
6224           return "dec{q}\t%0";
6225         }
6226
6227     default:
6228       /* Use add as much as possible to replace lea for AGU optimization. */
6229       if (which_alternative == 2 && TARGET_OPT_AGU)
6230         return "add{q}\t{%1, %0|%0, %1}";
6231         
6232       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6233
6234       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6235          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6236       if (CONST_INT_P (operands[2])
6237           /* Avoid overflows.  */
6238           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6239           && (INTVAL (operands[2]) == 128
6240               || (INTVAL (operands[2]) < 0
6241                   && INTVAL (operands[2]) != -128)))
6242         {
6243           operands[2] = GEN_INT (-INTVAL (operands[2]));
6244           return "sub{q}\t{%2, %0|%0, %2}";
6245         }
6246       return "add{q}\t{%2, %0|%0, %2}";
6247     }
6248 }
6249   [(set (attr "type")
6250      (cond [(and (eq_attr "alternative" "2") 
6251                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6252               (const_string "lea")
6253             (eq_attr "alternative" "3")
6254               (const_string "lea")
6255             ; Current assemblers are broken and do not allow @GOTOFF in
6256             ; ought but a memory context.
6257             (match_operand:DI 2 "pic_symbolic_operand" "")
6258               (const_string "lea")
6259             (match_operand:DI 2 "incdec_operand" "")
6260               (const_string "incdec")
6261            ]
6262            (const_string "alu")))
6263    (set_attr "mode" "DI")])
6264
6265 ;; Convert lea to the lea pattern to avoid flags dependency.
6266 (define_split
6267   [(set (match_operand:DI 0 "register_operand" "")
6268         (plus:DI (match_operand:DI 1 "register_operand" "")
6269                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6270    (clobber (reg:CC FLAGS_REG))]
6271   "TARGET_64BIT && reload_completed 
6272    && ix86_lea_for_add_ok (PLUS, insn, operands)"
6273   [(set (match_dup 0)
6274         (plus:DI (match_dup 1)
6275                  (match_dup 2)))]
6276   "")
6277
6278 (define_insn "*adddi_2_rex64"
6279   [(set (reg FLAGS_REG)
6280         (compare
6281           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6282                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6283           (const_int 0)))
6284    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6285         (plus:DI (match_dup 1) (match_dup 2)))]
6286   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6287    && ix86_binary_operator_ok (PLUS, DImode, operands)
6288    /* Current assemblers are broken and do not allow @GOTOFF in
6289       ought but a memory context.  */
6290    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6291 {
6292   switch (get_attr_type (insn))
6293     {
6294     case TYPE_INCDEC:
6295       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6296       if (operands[2] == const1_rtx)
6297         return "inc{q}\t%0";
6298       else
6299         {
6300           gcc_assert (operands[2] == constm1_rtx);
6301           return "dec{q}\t%0";
6302         }
6303
6304     default:
6305       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6306       /* ???? We ought to handle there the 32bit case too
6307          - do we need new constraint?  */
6308       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6309          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6310       if (CONST_INT_P (operands[2])
6311           /* Avoid overflows.  */
6312           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6313           && (INTVAL (operands[2]) == 128
6314               || (INTVAL (operands[2]) < 0
6315                   && INTVAL (operands[2]) != -128)))
6316         {
6317           operands[2] = GEN_INT (-INTVAL (operands[2]));
6318           return "sub{q}\t{%2, %0|%0, %2}";
6319         }
6320       return "add{q}\t{%2, %0|%0, %2}";
6321     }
6322 }
6323   [(set (attr "type")
6324      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6325         (const_string "incdec")
6326         (const_string "alu")))
6327    (set_attr "mode" "DI")])
6328
6329 (define_insn "*adddi_3_rex64"
6330   [(set (reg FLAGS_REG)
6331         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6332                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6333    (clobber (match_scratch:DI 0 "=r"))]
6334   "TARGET_64BIT
6335    && ix86_match_ccmode (insn, CCZmode)
6336    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6337    /* Current assemblers are broken and do not allow @GOTOFF in
6338       ought but a memory context.  */
6339    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6340 {
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6345       if (operands[2] == const1_rtx)
6346         return "inc{q}\t%0";
6347       else
6348         {
6349           gcc_assert (operands[2] == constm1_rtx);
6350           return "dec{q}\t%0";
6351         }
6352
6353     default:
6354       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6355       /* ???? We ought to handle there the 32bit case too
6356          - do we need new constraint?  */
6357       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6358          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6359       if (CONST_INT_P (operands[2])
6360           /* Avoid overflows.  */
6361           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6362           && (INTVAL (operands[2]) == 128
6363               || (INTVAL (operands[2]) < 0
6364                   && INTVAL (operands[2]) != -128)))
6365         {
6366           operands[2] = GEN_INT (-INTVAL (operands[2]));
6367           return "sub{q}\t{%2, %0|%0, %2}";
6368         }
6369       return "add{q}\t{%2, %0|%0, %2}";
6370     }
6371 }
6372   [(set (attr "type")
6373      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6374         (const_string "incdec")
6375         (const_string "alu")))
6376    (set_attr "mode" "DI")])
6377
6378 ; For comparisons against 1, -1 and 128, we may generate better code
6379 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6380 ; is matched then.  We can't accept general immediate, because for
6381 ; case of overflows,  the result is messed up.
6382 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6383 ; when negated.
6384 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6385 ; only for comparisons not depending on it.
6386 (define_insn "*adddi_4_rex64"
6387   [(set (reg FLAGS_REG)
6388         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6389                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6390    (clobber (match_scratch:DI 0 "=rm"))]
6391   "TARGET_64BIT
6392    &&  ix86_match_ccmode (insn, CCGCmode)"
6393 {
6394   switch (get_attr_type (insn))
6395     {
6396     case TYPE_INCDEC:
6397       if (operands[2] == constm1_rtx)
6398         return "inc{q}\t%0";
6399       else
6400         {
6401           gcc_assert (operands[2] == const1_rtx);
6402           return "dec{q}\t%0";
6403         }
6404
6405     default:
6406       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6407       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6408          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6409       if ((INTVAL (operands[2]) == -128
6410            || (INTVAL (operands[2]) > 0
6411                && INTVAL (operands[2]) != 128))
6412           /* Avoid overflows.  */
6413           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6414         return "sub{q}\t{%2, %0|%0, %2}";
6415       operands[2] = GEN_INT (-INTVAL (operands[2]));
6416       return "add{q}\t{%2, %0|%0, %2}";
6417     }
6418 }
6419   [(set (attr "type")
6420      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6421         (const_string "incdec")
6422         (const_string "alu")))
6423    (set_attr "mode" "DI")])
6424
6425 (define_insn "*adddi_5_rex64"
6426   [(set (reg FLAGS_REG)
6427         (compare
6428           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6429                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6430           (const_int 0)))
6431    (clobber (match_scratch:DI 0 "=r"))]
6432   "TARGET_64BIT
6433    && ix86_match_ccmode (insn, CCGOCmode)
6434    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6435    /* Current assemblers are broken and do not allow @GOTOFF in
6436       ought but a memory context.  */
6437    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6438 {
6439   switch (get_attr_type (insn))
6440     {
6441     case TYPE_INCDEC:
6442       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6443       if (operands[2] == const1_rtx)
6444         return "inc{q}\t%0";
6445       else
6446         {
6447           gcc_assert (operands[2] == constm1_rtx);
6448           return "dec{q}\t%0";
6449         }
6450
6451     default:
6452       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6453       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6454          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6455       if (CONST_INT_P (operands[2])
6456           /* Avoid overflows.  */
6457           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6458           && (INTVAL (operands[2]) == 128
6459               || (INTVAL (operands[2]) < 0
6460                   && INTVAL (operands[2]) != -128)))
6461         {
6462           operands[2] = GEN_INT (-INTVAL (operands[2]));
6463           return "sub{q}\t{%2, %0|%0, %2}";
6464         }
6465       return "add{q}\t{%2, %0|%0, %2}";
6466     }
6467 }
6468   [(set (attr "type")
6469      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6470         (const_string "incdec")
6471         (const_string "alu")))
6472    (set_attr "mode" "DI")])
6473
6474
6475 (define_insn "*addsi_1"
6476   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
6477         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
6478                  (match_operand:SI 2 "general_operand" "g,ri,0,li")))
6479    (clobber (reg:CC FLAGS_REG))]
6480   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6481 {
6482   switch (get_attr_type (insn))
6483     {
6484     case TYPE_LEA:
6485       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6486       return "lea{l}\t{%a2, %0|%0, %a2}";
6487
6488     case TYPE_INCDEC:
6489       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6490       if (operands[2] == const1_rtx)
6491         return "inc{l}\t%0";
6492       else
6493         {
6494           gcc_assert (operands[2] == constm1_rtx);
6495           return "dec{l}\t%0";
6496         }
6497
6498     default:
6499       /* Use add as much as possible to replace lea for AGU optimization. */
6500       if (which_alternative == 2 && TARGET_OPT_AGU)
6501         return "add{l}\t{%1, %0|%0, %1}";
6502
6503       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6504
6505       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6506          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6507       if (CONST_INT_P (operands[2])
6508           && (INTVAL (operands[2]) == 128
6509               || (INTVAL (operands[2]) < 0
6510                   && INTVAL (operands[2]) != -128)))
6511         {
6512           operands[2] = GEN_INT (-INTVAL (operands[2]));
6513           return "sub{l}\t{%2, %0|%0, %2}";
6514         }
6515       return "add{l}\t{%2, %0|%0, %2}";
6516     }
6517 }
6518   [(set (attr "type")
6519      (cond [(and (eq_attr "alternative" "2") 
6520                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6521                (const_string "lea")
6522             (eq_attr "alternative" "3")
6523               (const_string "lea")
6524             ; Current assemblers are broken and do not allow @GOTOFF in
6525             ; ought but a memory context.
6526             (match_operand:SI 2 "pic_symbolic_operand" "")
6527               (const_string "lea")
6528             (match_operand:SI 2 "incdec_operand" "")
6529               (const_string "incdec")
6530            ]
6531            (const_string "alu")))
6532    (set_attr "mode" "SI")])
6533
6534 ;; Convert lea to the lea pattern to avoid flags dependency.
6535 (define_split
6536   [(set (match_operand 0 "register_operand" "")
6537         (plus (match_operand 1 "register_operand" "")
6538               (match_operand 2 "nonmemory_operand" "")))
6539    (clobber (reg:CC FLAGS_REG))]
6540   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
6541   [(const_int 0)]
6542 {
6543   rtx pat;
6544   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6545      may confuse gen_lowpart.  */
6546   if (GET_MODE (operands[0]) != Pmode)
6547     {
6548       operands[1] = gen_lowpart (Pmode, operands[1]);
6549       operands[2] = gen_lowpart (Pmode, operands[2]);
6550     }
6551   operands[0] = gen_lowpart (SImode, operands[0]);
6552   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6553   if (Pmode != SImode)
6554     pat = gen_rtx_SUBREG (SImode, pat, 0);
6555   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6556   DONE;
6557 })
6558
6559 ;; It may seem that nonimmediate operand is proper one for operand 1.
6560 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6561 ;; we take care in ix86_binary_operator_ok to not allow two memory
6562 ;; operands so proper swapping will be done in reload.  This allow
6563 ;; patterns constructed from addsi_1 to match.
6564 (define_insn "addsi_1_zext"
6565   [(set (match_operand:DI 0 "register_operand" "=r,r")
6566         (zero_extend:DI
6567           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6568                    (match_operand:SI 2 "general_operand" "g,li"))))
6569    (clobber (reg:CC FLAGS_REG))]
6570   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6571 {
6572   switch (get_attr_type (insn))
6573     {
6574     case TYPE_LEA:
6575       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6576       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6577
6578     case TYPE_INCDEC:
6579       if (operands[2] == const1_rtx)
6580         return "inc{l}\t%k0";
6581       else
6582         {
6583           gcc_assert (operands[2] == constm1_rtx);
6584           return "dec{l}\t%k0";
6585         }
6586
6587     default:
6588       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6589          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6590       if (CONST_INT_P (operands[2])
6591           && (INTVAL (operands[2]) == 128
6592               || (INTVAL (operands[2]) < 0
6593                   && INTVAL (operands[2]) != -128)))
6594         {
6595           operands[2] = GEN_INT (-INTVAL (operands[2]));
6596           return "sub{l}\t{%2, %k0|%k0, %2}";
6597         }
6598       return "add{l}\t{%2, %k0|%k0, %2}";
6599     }
6600 }
6601   [(set (attr "type")
6602      (cond [(eq_attr "alternative" "1")
6603               (const_string "lea")
6604             ; Current assemblers are broken and do not allow @GOTOFF in
6605             ; ought but a memory context.
6606             (match_operand:SI 2 "pic_symbolic_operand" "")
6607               (const_string "lea")
6608             (match_operand:SI 2 "incdec_operand" "")
6609               (const_string "incdec")
6610            ]
6611            (const_string "alu")))
6612    (set_attr "mode" "SI")])
6613
6614 ;; Convert lea to the lea pattern to avoid flags dependency.
6615 (define_split
6616   [(set (match_operand:DI 0 "register_operand" "")
6617         (zero_extend:DI
6618           (plus:SI (match_operand:SI 1 "register_operand" "")
6619                    (match_operand:SI 2 "nonmemory_operand" ""))))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "TARGET_64BIT && reload_completed
6622    && true_regnum (operands[0]) != true_regnum (operands[1])"
6623   [(set (match_dup 0)
6624         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6625 {
6626   operands[1] = gen_lowpart (Pmode, operands[1]);
6627   operands[2] = gen_lowpart (Pmode, operands[2]);
6628 })
6629
6630 (define_insn "*addsi_2"
6631   [(set (reg FLAGS_REG)
6632         (compare
6633           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6634                    (match_operand:SI 2 "general_operand" "g,ri"))
6635           (const_int 0)))
6636    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6637         (plus:SI (match_dup 1) (match_dup 2)))]
6638   "ix86_match_ccmode (insn, CCGOCmode)
6639    && ix86_binary_operator_ok (PLUS, SImode, operands)
6640    /* Current assemblers are broken and do not allow @GOTOFF in
6641       ought but a memory context.  */
6642    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6643 {
6644   switch (get_attr_type (insn))
6645     {
6646     case TYPE_INCDEC:
6647       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6648       if (operands[2] == const1_rtx)
6649         return "inc{l}\t%0";
6650       else
6651         {
6652           gcc_assert (operands[2] == constm1_rtx);
6653           return "dec{l}\t%0";
6654         }
6655
6656     default:
6657       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6658       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6659          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6660       if (CONST_INT_P (operands[2])
6661           && (INTVAL (operands[2]) == 128
6662               || (INTVAL (operands[2]) < 0
6663                   && INTVAL (operands[2]) != -128)))
6664         {
6665           operands[2] = GEN_INT (-INTVAL (operands[2]));
6666           return "sub{l}\t{%2, %0|%0, %2}";
6667         }
6668       return "add{l}\t{%2, %0|%0, %2}";
6669     }
6670 }
6671   [(set (attr "type")
6672      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6673         (const_string "incdec")
6674         (const_string "alu")))
6675    (set_attr "mode" "SI")])
6676
6677 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6678 (define_insn "*addsi_2_zext"
6679   [(set (reg FLAGS_REG)
6680         (compare
6681           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6682                    (match_operand:SI 2 "general_operand" "g"))
6683           (const_int 0)))
6684    (set (match_operand:DI 0 "register_operand" "=r")
6685         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6686   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6687    && ix86_binary_operator_ok (PLUS, SImode, operands)
6688    /* Current assemblers are broken and do not allow @GOTOFF in
6689       ought but a memory context.  */
6690    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6691 {
6692   switch (get_attr_type (insn))
6693     {
6694     case TYPE_INCDEC:
6695       if (operands[2] == const1_rtx)
6696         return "inc{l}\t%k0";
6697       else
6698         {
6699           gcc_assert (operands[2] == constm1_rtx);
6700           return "dec{l}\t%k0";
6701         }
6702
6703     default:
6704       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6705          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6706       if (CONST_INT_P (operands[2])
6707           && (INTVAL (operands[2]) == 128
6708               || (INTVAL (operands[2]) < 0
6709                   && INTVAL (operands[2]) != -128)))
6710         {
6711           operands[2] = GEN_INT (-INTVAL (operands[2]));
6712           return "sub{l}\t{%2, %k0|%k0, %2}";
6713         }
6714       return "add{l}\t{%2, %k0|%k0, %2}";
6715     }
6716 }
6717   [(set (attr "type")
6718      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6719         (const_string "incdec")
6720         (const_string "alu")))
6721    (set_attr "mode" "SI")])
6722
6723 (define_insn "*addsi_3"
6724   [(set (reg FLAGS_REG)
6725         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6726                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6727    (clobber (match_scratch:SI 0 "=r"))]
6728   "ix86_match_ccmode (insn, CCZmode)
6729    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6730    /* Current assemblers are broken and do not allow @GOTOFF in
6731       ought but a memory context.  */
6732    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6733 {
6734   switch (get_attr_type (insn))
6735     {
6736     case TYPE_INCDEC:
6737       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6738       if (operands[2] == const1_rtx)
6739         return "inc{l}\t%0";
6740       else
6741         {
6742           gcc_assert (operands[2] == constm1_rtx);
6743           return "dec{l}\t%0";
6744         }
6745
6746     default:
6747       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6748       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6749          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6750       if (CONST_INT_P (operands[2])
6751           && (INTVAL (operands[2]) == 128
6752               || (INTVAL (operands[2]) < 0
6753                   && INTVAL (operands[2]) != -128)))
6754         {
6755           operands[2] = GEN_INT (-INTVAL (operands[2]));
6756           return "sub{l}\t{%2, %0|%0, %2}";
6757         }
6758       return "add{l}\t{%2, %0|%0, %2}";
6759     }
6760 }
6761   [(set (attr "type")
6762      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6763         (const_string "incdec")
6764         (const_string "alu")))
6765    (set_attr "mode" "SI")])
6766
6767 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6768 (define_insn "*addsi_3_zext"
6769   [(set (reg FLAGS_REG)
6770         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6771                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6772    (set (match_operand:DI 0 "register_operand" "=r")
6773         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6774   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6775    && ix86_binary_operator_ok (PLUS, SImode, operands)
6776    /* Current assemblers are broken and do not allow @GOTOFF in
6777       ought but a memory context.  */
6778    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6779 {
6780   switch (get_attr_type (insn))
6781     {
6782     case TYPE_INCDEC:
6783       if (operands[2] == const1_rtx)
6784         return "inc{l}\t%k0";
6785       else
6786         {
6787           gcc_assert (operands[2] == constm1_rtx);
6788           return "dec{l}\t%k0";
6789         }
6790
6791     default:
6792       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6793          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6794       if (CONST_INT_P (operands[2])
6795           && (INTVAL (operands[2]) == 128
6796               || (INTVAL (operands[2]) < 0
6797                   && INTVAL (operands[2]) != -128)))
6798         {
6799           operands[2] = GEN_INT (-INTVAL (operands[2]));
6800           return "sub{l}\t{%2, %k0|%k0, %2}";
6801         }
6802       return "add{l}\t{%2, %k0|%k0, %2}";
6803     }
6804 }
6805   [(set (attr "type")
6806      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6807         (const_string "incdec")
6808         (const_string "alu")))
6809    (set_attr "mode" "SI")])
6810
6811 ; For comparisons against 1, -1 and 128, we may generate better code
6812 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6813 ; is matched then.  We can't accept general immediate, because for
6814 ; case of overflows,  the result is messed up.
6815 ; This pattern also don't hold of 0x80000000, since the value overflows
6816 ; when negated.
6817 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6818 ; only for comparisons not depending on it.
6819 (define_insn "*addsi_4"
6820   [(set (reg FLAGS_REG)
6821         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6822                  (match_operand:SI 2 "const_int_operand" "n")))
6823    (clobber (match_scratch:SI 0 "=rm"))]
6824   "ix86_match_ccmode (insn, CCGCmode)
6825    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6826 {
6827   switch (get_attr_type (insn))
6828     {
6829     case TYPE_INCDEC:
6830       if (operands[2] == constm1_rtx)
6831         return "inc{l}\t%0";
6832       else
6833         {
6834           gcc_assert (operands[2] == const1_rtx);
6835           return "dec{l}\t%0";
6836         }
6837
6838     default:
6839       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6840       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6841          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6842       if ((INTVAL (operands[2]) == -128
6843            || (INTVAL (operands[2]) > 0
6844                && INTVAL (operands[2]) != 128)))
6845         return "sub{l}\t{%2, %0|%0, %2}";
6846       operands[2] = GEN_INT (-INTVAL (operands[2]));
6847       return "add{l}\t{%2, %0|%0, %2}";
6848     }
6849 }
6850   [(set (attr "type")
6851      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6852         (const_string "incdec")
6853         (const_string "alu")))
6854    (set_attr "mode" "SI")])
6855
6856 (define_insn "*addsi_5"
6857   [(set (reg FLAGS_REG)
6858         (compare
6859           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6860                    (match_operand:SI 2 "general_operand" "g"))
6861           (const_int 0)))
6862    (clobber (match_scratch:SI 0 "=r"))]
6863   "ix86_match_ccmode (insn, CCGOCmode)
6864    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6865    /* Current assemblers are broken and do not allow @GOTOFF in
6866       ought but a memory context.  */
6867    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6868 {
6869   switch (get_attr_type (insn))
6870     {
6871     case TYPE_INCDEC:
6872       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6873       if (operands[2] == const1_rtx)
6874         return "inc{l}\t%0";
6875       else
6876         {
6877           gcc_assert (operands[2] == constm1_rtx);
6878           return "dec{l}\t%0";
6879         }
6880
6881     default:
6882       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6883       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6884          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6885       if (CONST_INT_P (operands[2])
6886           && (INTVAL (operands[2]) == 128
6887               || (INTVAL (operands[2]) < 0
6888                   && INTVAL (operands[2]) != -128)))
6889         {
6890           operands[2] = GEN_INT (-INTVAL (operands[2]));
6891           return "sub{l}\t{%2, %0|%0, %2}";
6892         }
6893       return "add{l}\t{%2, %0|%0, %2}";
6894     }
6895 }
6896   [(set (attr "type")
6897      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6898         (const_string "incdec")
6899         (const_string "alu")))
6900    (set_attr "mode" "SI")])
6901
6902 (define_expand "addhi3"
6903   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6904         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6905                  (match_operand:HI 2 "general_operand" "")))]
6906   "TARGET_HIMODE_MATH"
6907   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6908
6909 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6910 ;; type optimizations enabled by define-splits.  This is not important
6911 ;; for PII, and in fact harmful because of partial register stalls.
6912
6913 (define_insn "*addhi_1_lea"
6914   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6915         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6916                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6917    (clobber (reg:CC FLAGS_REG))]
6918   "!TARGET_PARTIAL_REG_STALL
6919    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6920 {
6921   switch (get_attr_type (insn))
6922     {
6923     case TYPE_LEA:
6924       return "#";
6925     case TYPE_INCDEC:
6926       if (operands[2] == const1_rtx)
6927         return "inc{w}\t%0";
6928       else
6929         {
6930           gcc_assert (operands[2] == constm1_rtx);
6931           return "dec{w}\t%0";
6932         }
6933
6934     default:
6935       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6936          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6937       if (CONST_INT_P (operands[2])
6938           && (INTVAL (operands[2]) == 128
6939               || (INTVAL (operands[2]) < 0
6940                   && INTVAL (operands[2]) != -128)))
6941         {
6942           operands[2] = GEN_INT (-INTVAL (operands[2]));
6943           return "sub{w}\t{%2, %0|%0, %2}";
6944         }
6945       return "add{w}\t{%2, %0|%0, %2}";
6946     }
6947 }
6948   [(set (attr "type")
6949      (if_then_else (eq_attr "alternative" "2")
6950         (const_string "lea")
6951         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6952            (const_string "incdec")
6953            (const_string "alu"))))
6954    (set_attr "mode" "HI,HI,SI")])
6955
6956 (define_insn "*addhi_1"
6957   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6958         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6959                  (match_operand:HI 2 "general_operand" "rn,rm")))
6960    (clobber (reg:CC FLAGS_REG))]
6961   "TARGET_PARTIAL_REG_STALL
6962    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6963 {
6964   switch (get_attr_type (insn))
6965     {
6966     case TYPE_INCDEC:
6967       if (operands[2] == const1_rtx)
6968         return "inc{w}\t%0";
6969       else
6970         {
6971           gcc_assert (operands[2] == constm1_rtx);
6972           return "dec{w}\t%0";
6973         }
6974
6975     default:
6976       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6977          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6978       if (CONST_INT_P (operands[2])
6979           && (INTVAL (operands[2]) == 128
6980               || (INTVAL (operands[2]) < 0
6981                   && INTVAL (operands[2]) != -128)))
6982         {
6983           operands[2] = GEN_INT (-INTVAL (operands[2]));
6984           return "sub{w}\t{%2, %0|%0, %2}";
6985         }
6986       return "add{w}\t{%2, %0|%0, %2}";
6987     }
6988 }
6989   [(set (attr "type")
6990      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6991         (const_string "incdec")
6992         (const_string "alu")))
6993    (set_attr "mode" "HI")])
6994
6995 (define_insn "*addhi_2"
6996   [(set (reg FLAGS_REG)
6997         (compare
6998           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6999                    (match_operand:HI 2 "general_operand" "rmn,rn"))
7000           (const_int 0)))
7001    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7002         (plus:HI (match_dup 1) (match_dup 2)))]
7003   "ix86_match_ccmode (insn, CCGOCmode)
7004    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7005 {
7006   switch (get_attr_type (insn))
7007     {
7008     case TYPE_INCDEC:
7009       if (operands[2] == const1_rtx)
7010         return "inc{w}\t%0";
7011       else
7012         {
7013           gcc_assert (operands[2] == constm1_rtx);
7014           return "dec{w}\t%0";
7015         }
7016
7017     default:
7018       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7019          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7020       if (CONST_INT_P (operands[2])
7021           && (INTVAL (operands[2]) == 128
7022               || (INTVAL (operands[2]) < 0
7023                   && INTVAL (operands[2]) != -128)))
7024         {
7025           operands[2] = GEN_INT (-INTVAL (operands[2]));
7026           return "sub{w}\t{%2, %0|%0, %2}";
7027         }
7028       return "add{w}\t{%2, %0|%0, %2}";
7029     }
7030 }
7031   [(set (attr "type")
7032      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7033         (const_string "incdec")
7034         (const_string "alu")))
7035    (set_attr "mode" "HI")])
7036
7037 (define_insn "*addhi_3"
7038   [(set (reg FLAGS_REG)
7039         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
7040                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
7041    (clobber (match_scratch:HI 0 "=r"))]
7042   "ix86_match_ccmode (insn, CCZmode)
7043    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7044 {
7045   switch (get_attr_type (insn))
7046     {
7047     case TYPE_INCDEC:
7048       if (operands[2] == const1_rtx)
7049         return "inc{w}\t%0";
7050       else
7051         {
7052           gcc_assert (operands[2] == constm1_rtx);
7053           return "dec{w}\t%0";
7054         }
7055
7056     default:
7057       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7058          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7059       if (CONST_INT_P (operands[2])
7060           && (INTVAL (operands[2]) == 128
7061               || (INTVAL (operands[2]) < 0
7062                   && INTVAL (operands[2]) != -128)))
7063         {
7064           operands[2] = GEN_INT (-INTVAL (operands[2]));
7065           return "sub{w}\t{%2, %0|%0, %2}";
7066         }
7067       return "add{w}\t{%2, %0|%0, %2}";
7068     }
7069 }
7070   [(set (attr "type")
7071      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7072         (const_string "incdec")
7073         (const_string "alu")))
7074    (set_attr "mode" "HI")])
7075
7076 ; See comments above addsi_4 for details.
7077 (define_insn "*addhi_4"
7078   [(set (reg FLAGS_REG)
7079         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7080                  (match_operand:HI 2 "const_int_operand" "n")))
7081    (clobber (match_scratch:HI 0 "=rm"))]
7082   "ix86_match_ccmode (insn, CCGCmode)
7083    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7084 {
7085   switch (get_attr_type (insn))
7086     {
7087     case TYPE_INCDEC:
7088       if (operands[2] == constm1_rtx)
7089         return "inc{w}\t%0";
7090       else
7091         {
7092           gcc_assert (operands[2] == const1_rtx);
7093           return "dec{w}\t%0";
7094         }
7095
7096     default:
7097       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7098       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7099          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7100       if ((INTVAL (operands[2]) == -128
7101            || (INTVAL (operands[2]) > 0
7102                && INTVAL (operands[2]) != 128)))
7103         return "sub{w}\t{%2, %0|%0, %2}";
7104       operands[2] = GEN_INT (-INTVAL (operands[2]));
7105       return "add{w}\t{%2, %0|%0, %2}";
7106     }
7107 }
7108   [(set (attr "type")
7109      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7110         (const_string "incdec")
7111         (const_string "alu")))
7112    (set_attr "mode" "SI")])
7113
7114
7115 (define_insn "*addhi_5"
7116   [(set (reg FLAGS_REG)
7117         (compare
7118           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7119                    (match_operand:HI 2 "general_operand" "rmn"))
7120           (const_int 0)))
7121    (clobber (match_scratch:HI 0 "=r"))]
7122   "ix86_match_ccmode (insn, CCGOCmode)
7123    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7124 {
7125   switch (get_attr_type (insn))
7126     {
7127     case TYPE_INCDEC:
7128       if (operands[2] == const1_rtx)
7129         return "inc{w}\t%0";
7130       else
7131         {
7132           gcc_assert (operands[2] == constm1_rtx);
7133           return "dec{w}\t%0";
7134         }
7135
7136     default:
7137       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7138          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7139       if (CONST_INT_P (operands[2])
7140           && (INTVAL (operands[2]) == 128
7141               || (INTVAL (operands[2]) < 0
7142                   && INTVAL (operands[2]) != -128)))
7143         {
7144           operands[2] = GEN_INT (-INTVAL (operands[2]));
7145           return "sub{w}\t{%2, %0|%0, %2}";
7146         }
7147       return "add{w}\t{%2, %0|%0, %2}";
7148     }
7149 }
7150   [(set (attr "type")
7151      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7152         (const_string "incdec")
7153         (const_string "alu")))
7154    (set_attr "mode" "HI")])
7155
7156 (define_expand "addqi3"
7157   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7158         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7159                  (match_operand:QI 2 "general_operand" "")))]
7160   "TARGET_QIMODE_MATH"
7161   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7162
7163 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7164 (define_insn "*addqi_1_lea"
7165   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7166         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7167                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7168    (clobber (reg:CC FLAGS_REG))]
7169   "!TARGET_PARTIAL_REG_STALL
7170    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7171 {
7172   int widen = (which_alternative == 2);
7173   switch (get_attr_type (insn))
7174     {
7175     case TYPE_LEA:
7176       return "#";
7177     case TYPE_INCDEC:
7178       if (operands[2] == const1_rtx)
7179         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7180       else
7181         {
7182           gcc_assert (operands[2] == constm1_rtx);
7183           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7184         }
7185
7186     default:
7187       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7188          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7189       if (CONST_INT_P (operands[2])
7190           && (INTVAL (operands[2]) == 128
7191               || (INTVAL (operands[2]) < 0
7192                   && INTVAL (operands[2]) != -128)))
7193         {
7194           operands[2] = GEN_INT (-INTVAL (operands[2]));
7195           if (widen)
7196             return "sub{l}\t{%2, %k0|%k0, %2}";
7197           else
7198             return "sub{b}\t{%2, %0|%0, %2}";
7199         }
7200       if (widen)
7201         return "add{l}\t{%k2, %k0|%k0, %k2}";
7202       else
7203         return "add{b}\t{%2, %0|%0, %2}";
7204     }
7205 }
7206   [(set (attr "type")
7207      (if_then_else (eq_attr "alternative" "3")
7208         (const_string "lea")
7209         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7210            (const_string "incdec")
7211            (const_string "alu"))))
7212    (set_attr "mode" "QI,QI,SI,SI")])
7213
7214 (define_insn "*addqi_1"
7215   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7216         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7217                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7218    (clobber (reg:CC FLAGS_REG))]
7219   "TARGET_PARTIAL_REG_STALL
7220    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7221 {
7222   int widen = (which_alternative == 2);
7223   switch (get_attr_type (insn))
7224     {
7225     case TYPE_INCDEC:
7226       if (operands[2] == const1_rtx)
7227         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7228       else
7229         {
7230           gcc_assert (operands[2] == constm1_rtx);
7231           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7232         }
7233
7234     default:
7235       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7236          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7237       if (CONST_INT_P (operands[2])
7238           && (INTVAL (operands[2]) == 128
7239               || (INTVAL (operands[2]) < 0
7240                   && INTVAL (operands[2]) != -128)))
7241         {
7242           operands[2] = GEN_INT (-INTVAL (operands[2]));
7243           if (widen)
7244             return "sub{l}\t{%2, %k0|%k0, %2}";
7245           else
7246             return "sub{b}\t{%2, %0|%0, %2}";
7247         }
7248       if (widen)
7249         return "add{l}\t{%k2, %k0|%k0, %k2}";
7250       else
7251         return "add{b}\t{%2, %0|%0, %2}";
7252     }
7253 }
7254   [(set (attr "type")
7255      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7256         (const_string "incdec")
7257         (const_string "alu")))
7258    (set_attr "mode" "QI,QI,SI")])
7259
7260 (define_insn "*addqi_1_slp"
7261   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7262         (plus:QI (match_dup 0)
7263                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7264    (clobber (reg:CC FLAGS_REG))]
7265   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7266    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7267 {
7268   switch (get_attr_type (insn))
7269     {
7270     case TYPE_INCDEC:
7271       if (operands[1] == const1_rtx)
7272         return "inc{b}\t%0";
7273       else
7274         {
7275           gcc_assert (operands[1] == constm1_rtx);
7276           return "dec{b}\t%0";
7277         }
7278
7279     default:
7280       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7281       if (CONST_INT_P (operands[1])
7282           && INTVAL (operands[1]) < 0)
7283         {
7284           operands[1] = GEN_INT (-INTVAL (operands[1]));
7285           return "sub{b}\t{%1, %0|%0, %1}";
7286         }
7287       return "add{b}\t{%1, %0|%0, %1}";
7288     }
7289 }
7290   [(set (attr "type")
7291      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7292         (const_string "incdec")
7293         (const_string "alu1")))
7294    (set (attr "memory")
7295      (if_then_else (match_operand 1 "memory_operand" "")
7296         (const_string "load")
7297         (const_string "none")))
7298    (set_attr "mode" "QI")])
7299
7300 (define_insn "*addqi_2"
7301   [(set (reg FLAGS_REG)
7302         (compare
7303           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7304                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7305           (const_int 0)))
7306    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7307         (plus:QI (match_dup 1) (match_dup 2)))]
7308   "ix86_match_ccmode (insn, CCGOCmode)
7309    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7310 {
7311   switch (get_attr_type (insn))
7312     {
7313     case TYPE_INCDEC:
7314       if (operands[2] == const1_rtx)
7315         return "inc{b}\t%0";
7316       else
7317         {
7318           gcc_assert (operands[2] == constm1_rtx
7319                       || (CONST_INT_P (operands[2])
7320                           && INTVAL (operands[2]) == 255));
7321           return "dec{b}\t%0";
7322         }
7323
7324     default:
7325       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7326       if (CONST_INT_P (operands[2])
7327           && INTVAL (operands[2]) < 0)
7328         {
7329           operands[2] = GEN_INT (-INTVAL (operands[2]));
7330           return "sub{b}\t{%2, %0|%0, %2}";
7331         }
7332       return "add{b}\t{%2, %0|%0, %2}";
7333     }
7334 }
7335   [(set (attr "type")
7336      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7337         (const_string "incdec")
7338         (const_string "alu")))
7339    (set_attr "mode" "QI")])
7340
7341 (define_insn "*addqi_3"
7342   [(set (reg FLAGS_REG)
7343         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7344                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7345    (clobber (match_scratch:QI 0 "=q"))]
7346   "ix86_match_ccmode (insn, CCZmode)
7347    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7348 {
7349   switch (get_attr_type (insn))
7350     {
7351     case TYPE_INCDEC:
7352       if (operands[2] == const1_rtx)
7353         return "inc{b}\t%0";
7354       else
7355         {
7356           gcc_assert (operands[2] == constm1_rtx
7357                       || (CONST_INT_P (operands[2])
7358                           && INTVAL (operands[2]) == 255));
7359           return "dec{b}\t%0";
7360         }
7361
7362     default:
7363       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7364       if (CONST_INT_P (operands[2])
7365           && INTVAL (operands[2]) < 0)
7366         {
7367           operands[2] = GEN_INT (-INTVAL (operands[2]));
7368           return "sub{b}\t{%2, %0|%0, %2}";
7369         }
7370       return "add{b}\t{%2, %0|%0, %2}";
7371     }
7372 }
7373   [(set (attr "type")
7374      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7375         (const_string "incdec")
7376         (const_string "alu")))
7377    (set_attr "mode" "QI")])
7378
7379 ; See comments above addsi_4 for details.
7380 (define_insn "*addqi_4"
7381   [(set (reg FLAGS_REG)
7382         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7383                  (match_operand:QI 2 "const_int_operand" "n")))
7384    (clobber (match_scratch:QI 0 "=qm"))]
7385   "ix86_match_ccmode (insn, CCGCmode)
7386    && (INTVAL (operands[2]) & 0xff) != 0x80"
7387 {
7388   switch (get_attr_type (insn))
7389     {
7390     case TYPE_INCDEC:
7391       if (operands[2] == constm1_rtx
7392           || (CONST_INT_P (operands[2])
7393               && INTVAL (operands[2]) == 255))
7394         return "inc{b}\t%0";
7395       else
7396         {
7397           gcc_assert (operands[2] == const1_rtx);
7398           return "dec{b}\t%0";
7399         }
7400
7401     default:
7402       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7403       if (INTVAL (operands[2]) < 0)
7404         {
7405           operands[2] = GEN_INT (-INTVAL (operands[2]));
7406           return "add{b}\t{%2, %0|%0, %2}";
7407         }
7408       return "sub{b}\t{%2, %0|%0, %2}";
7409     }
7410 }
7411   [(set (attr "type")
7412      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7413         (const_string "incdec")
7414         (const_string "alu")))
7415    (set_attr "mode" "QI")])
7416
7417
7418 (define_insn "*addqi_5"
7419   [(set (reg FLAGS_REG)
7420         (compare
7421           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7422                    (match_operand:QI 2 "general_operand" "qmn"))
7423           (const_int 0)))
7424    (clobber (match_scratch:QI 0 "=q"))]
7425   "ix86_match_ccmode (insn, CCGOCmode)
7426    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7427 {
7428   switch (get_attr_type (insn))
7429     {
7430     case TYPE_INCDEC:
7431       if (operands[2] == const1_rtx)
7432         return "inc{b}\t%0";
7433       else
7434         {
7435           gcc_assert (operands[2] == constm1_rtx
7436                       || (CONST_INT_P (operands[2])
7437                           && INTVAL (operands[2]) == 255));
7438           return "dec{b}\t%0";
7439         }
7440
7441     default:
7442       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7443       if (CONST_INT_P (operands[2])
7444           && INTVAL (operands[2]) < 0)
7445         {
7446           operands[2] = GEN_INT (-INTVAL (operands[2]));
7447           return "sub{b}\t{%2, %0|%0, %2}";
7448         }
7449       return "add{b}\t{%2, %0|%0, %2}";
7450     }
7451 }
7452   [(set (attr "type")
7453      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7454         (const_string "incdec")
7455         (const_string "alu")))
7456    (set_attr "mode" "QI")])
7457
7458
7459 (define_insn "addqi_ext_1"
7460   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7461                          (const_int 8)
7462                          (const_int 8))
7463         (plus:SI
7464           (zero_extract:SI
7465             (match_operand 1 "ext_register_operand" "0")
7466             (const_int 8)
7467             (const_int 8))
7468           (match_operand:QI 2 "general_operand" "Qmn")))
7469    (clobber (reg:CC FLAGS_REG))]
7470   "!TARGET_64BIT"
7471 {
7472   switch (get_attr_type (insn))
7473     {
7474     case TYPE_INCDEC:
7475       if (operands[2] == const1_rtx)
7476         return "inc{b}\t%h0";
7477       else
7478         {
7479           gcc_assert (operands[2] == constm1_rtx
7480                       || (CONST_INT_P (operands[2])
7481                           && INTVAL (operands[2]) == 255));
7482           return "dec{b}\t%h0";
7483         }
7484
7485     default:
7486       return "add{b}\t{%2, %h0|%h0, %2}";
7487     }
7488 }
7489   [(set (attr "type")
7490      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7491         (const_string "incdec")
7492         (const_string "alu")))
7493    (set_attr "mode" "QI")])
7494
7495 (define_insn "*addqi_ext_1_rex64"
7496   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7497                          (const_int 8)
7498                          (const_int 8))
7499         (plus:SI
7500           (zero_extract:SI
7501             (match_operand 1 "ext_register_operand" "0")
7502             (const_int 8)
7503             (const_int 8))
7504           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "TARGET_64BIT"
7507 {
7508   switch (get_attr_type (insn))
7509     {
7510     case TYPE_INCDEC:
7511       if (operands[2] == const1_rtx)
7512         return "inc{b}\t%h0";
7513       else
7514         {
7515           gcc_assert (operands[2] == constm1_rtx
7516                       || (CONST_INT_P (operands[2])
7517                           && INTVAL (operands[2]) == 255));
7518           return "dec{b}\t%h0";
7519         }
7520
7521     default:
7522       return "add{b}\t{%2, %h0|%h0, %2}";
7523     }
7524 }
7525   [(set (attr "type")
7526      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7527         (const_string "incdec")
7528         (const_string "alu")))
7529    (set_attr "mode" "QI")])
7530
7531 (define_insn "*addqi_ext_2"
7532   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7533                          (const_int 8)
7534                          (const_int 8))
7535         (plus:SI
7536           (zero_extract:SI
7537             (match_operand 1 "ext_register_operand" "%0")
7538             (const_int 8)
7539             (const_int 8))
7540           (zero_extract:SI
7541             (match_operand 2 "ext_register_operand" "Q")
7542             (const_int 8)
7543             (const_int 8))))
7544    (clobber (reg:CC FLAGS_REG))]
7545   ""
7546   "add{b}\t{%h2, %h0|%h0, %h2}"
7547   [(set_attr "type" "alu")
7548    (set_attr "mode" "QI")])
7549
7550 ;; The patterns that match these are at the end of this file.
7551
7552 (define_expand "addxf3"
7553   [(set (match_operand:XF 0 "register_operand" "")
7554         (plus:XF (match_operand:XF 1 "register_operand" "")
7555                  (match_operand:XF 2 "register_operand" "")))]
7556   "TARGET_80387"
7557   "")
7558
7559 (define_expand "add<mode>3"
7560   [(set (match_operand:MODEF 0 "register_operand" "")
7561         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7562                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7563   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7564     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7565   "")
7566 \f
7567 ;; Subtract instructions
7568
7569 ;; %%% splits for subditi3
7570
7571 (define_expand "subti3"
7572   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7573         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7574                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7575   "TARGET_64BIT"
7576   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7577
7578 (define_insn "*subti3_1"
7579   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7580         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7581                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7582    (clobber (reg:CC FLAGS_REG))]
7583   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7584   "#")
7585
7586 (define_split
7587   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7588         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7589                   (match_operand:TI 2 "x86_64_general_operand" "")))
7590    (clobber (reg:CC FLAGS_REG))]
7591   "TARGET_64BIT && reload_completed"
7592   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7593               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7594    (parallel [(set (match_dup 3)
7595                    (minus:DI (match_dup 4)
7596                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7597                                       (match_dup 5))))
7598               (clobber (reg:CC FLAGS_REG))])]
7599   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7600
7601 ;; %%% splits for subsidi3
7602
7603 (define_expand "subdi3"
7604   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7605         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7606                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7607   ""
7608   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7609
7610 (define_insn "*subdi3_1"
7611   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7612         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7613                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7614    (clobber (reg:CC FLAGS_REG))]
7615   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7616   "#")
7617
7618 (define_split
7619   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7620         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7621                   (match_operand:DI 2 "general_operand" "")))
7622    (clobber (reg:CC FLAGS_REG))]
7623   "!TARGET_64BIT && reload_completed"
7624   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7625               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7626    (parallel [(set (match_dup 3)
7627                    (minus:SI (match_dup 4)
7628                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7629                                       (match_dup 5))))
7630               (clobber (reg:CC FLAGS_REG))])]
7631   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7632
7633 (define_insn "subdi3_carry_rex64"
7634   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7635           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7636             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7637                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7638    (clobber (reg:CC FLAGS_REG))]
7639   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7640   "sbb{q}\t{%2, %0|%0, %2}"
7641   [(set_attr "type" "alu")
7642    (set_attr "use_carry" "1")
7643    (set_attr "pent_pair" "pu")
7644    (set_attr "mode" "DI")])
7645
7646 (define_insn "*subdi_1_rex64"
7647   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7648         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7649                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7650    (clobber (reg:CC FLAGS_REG))]
7651   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7652   "sub{q}\t{%2, %0|%0, %2}"
7653   [(set_attr "type" "alu")
7654    (set_attr "mode" "DI")])
7655
7656 (define_insn "*subdi_2_rex64"
7657   [(set (reg FLAGS_REG)
7658         (compare
7659           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7660                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7661           (const_int 0)))
7662    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7663         (minus:DI (match_dup 1) (match_dup 2)))]
7664   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7665    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7666   "sub{q}\t{%2, %0|%0, %2}"
7667   [(set_attr "type" "alu")
7668    (set_attr "mode" "DI")])
7669
7670 (define_insn "*subdi_3_rex63"
7671   [(set (reg FLAGS_REG)
7672         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7673                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7674    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7675         (minus:DI (match_dup 1) (match_dup 2)))]
7676   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7677    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7678   "sub{q}\t{%2, %0|%0, %2}"
7679   [(set_attr "type" "alu")
7680    (set_attr "mode" "DI")])
7681
7682 (define_insn "subqi3_carry"
7683   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7684           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7685             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7686                (match_operand:QI 2 "general_operand" "qn,qm"))))
7687    (clobber (reg:CC FLAGS_REG))]
7688   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7689   "sbb{b}\t{%2, %0|%0, %2}"
7690   [(set_attr "type" "alu")
7691    (set_attr "use_carry" "1")
7692    (set_attr "pent_pair" "pu")
7693    (set_attr "mode" "QI")])
7694
7695 (define_insn "subhi3_carry"
7696   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7697           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7698             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7699                (match_operand:HI 2 "general_operand" "rn,rm"))))
7700    (clobber (reg:CC FLAGS_REG))]
7701   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7702   "sbb{w}\t{%2, %0|%0, %2}"
7703   [(set_attr "type" "alu")
7704    (set_attr "use_carry" "1")
7705    (set_attr "pent_pair" "pu")
7706    (set_attr "mode" "HI")])
7707
7708 (define_insn "subsi3_carry"
7709   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7710           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7711             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7712                (match_operand:SI 2 "general_operand" "ri,rm"))))
7713    (clobber (reg:CC FLAGS_REG))]
7714   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7715   "sbb{l}\t{%2, %0|%0, %2}"
7716   [(set_attr "type" "alu")
7717    (set_attr "use_carry" "1")
7718    (set_attr "pent_pair" "pu")
7719    (set_attr "mode" "SI")])
7720
7721 (define_insn "subsi3_carry_zext"
7722   [(set (match_operand:DI 0 "register_operand" "=r")
7723           (zero_extend:DI
7724             (minus:SI (match_operand:SI 1 "register_operand" "0")
7725               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7726                  (match_operand:SI 2 "general_operand" "g")))))
7727    (clobber (reg:CC FLAGS_REG))]
7728   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7729   "sbb{l}\t{%2, %k0|%k0, %2}"
7730   [(set_attr "type" "alu")
7731    (set_attr "pent_pair" "pu")
7732    (set_attr "mode" "SI")])
7733
7734 (define_expand "subsi3"
7735   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7736         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7737                   (match_operand:SI 2 "general_operand" "")))]
7738   ""
7739   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7740
7741 (define_insn "*subsi_1"
7742   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7743         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7744                   (match_operand:SI 2 "general_operand" "ri,rm")))
7745    (clobber (reg:CC FLAGS_REG))]
7746   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7747   "sub{l}\t{%2, %0|%0, %2}"
7748   [(set_attr "type" "alu")
7749    (set_attr "mode" "SI")])
7750
7751 (define_insn "*subsi_1_zext"
7752   [(set (match_operand:DI 0 "register_operand" "=r")
7753         (zero_extend:DI
7754           (minus:SI (match_operand:SI 1 "register_operand" "0")
7755                     (match_operand:SI 2 "general_operand" "g"))))
7756    (clobber (reg:CC FLAGS_REG))]
7757   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7758   "sub{l}\t{%2, %k0|%k0, %2}"
7759   [(set_attr "type" "alu")
7760    (set_attr "mode" "SI")])
7761
7762 (define_insn "*subsi_2"
7763   [(set (reg FLAGS_REG)
7764         (compare
7765           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7766                     (match_operand:SI 2 "general_operand" "ri,rm"))
7767           (const_int 0)))
7768    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7769         (minus:SI (match_dup 1) (match_dup 2)))]
7770   "ix86_match_ccmode (insn, CCGOCmode)
7771    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7772   "sub{l}\t{%2, %0|%0, %2}"
7773   [(set_attr "type" "alu")
7774    (set_attr "mode" "SI")])
7775
7776 (define_insn "*subsi_2_zext"
7777   [(set (reg FLAGS_REG)
7778         (compare
7779           (minus:SI (match_operand:SI 1 "register_operand" "0")
7780                     (match_operand:SI 2 "general_operand" "g"))
7781           (const_int 0)))
7782    (set (match_operand:DI 0 "register_operand" "=r")
7783         (zero_extend:DI
7784           (minus:SI (match_dup 1)
7785                     (match_dup 2))))]
7786   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7787    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7788   "sub{l}\t{%2, %k0|%k0, %2}"
7789   [(set_attr "type" "alu")
7790    (set_attr "mode" "SI")])
7791
7792 (define_insn "*subsi_3"
7793   [(set (reg FLAGS_REG)
7794         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7795                  (match_operand:SI 2 "general_operand" "ri,rm")))
7796    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7797         (minus:SI (match_dup 1) (match_dup 2)))]
7798   "ix86_match_ccmode (insn, CCmode)
7799    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7800   "sub{l}\t{%2, %0|%0, %2}"
7801   [(set_attr "type" "alu")
7802    (set_attr "mode" "SI")])
7803
7804 (define_insn "*subsi_3_zext"
7805   [(set (reg FLAGS_REG)
7806         (compare (match_operand:SI 1 "register_operand" "0")
7807                  (match_operand:SI 2 "general_operand" "g")))
7808    (set (match_operand:DI 0 "register_operand" "=r")
7809         (zero_extend:DI
7810           (minus:SI (match_dup 1)
7811                     (match_dup 2))))]
7812   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7813    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7814   "sub{l}\t{%2, %1|%1, %2}"
7815   [(set_attr "type" "alu")
7816    (set_attr "mode" "DI")])
7817
7818 (define_expand "subhi3"
7819   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7820         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7821                   (match_operand:HI 2 "general_operand" "")))]
7822   "TARGET_HIMODE_MATH"
7823   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7824
7825 (define_insn "*subhi_1"
7826   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7827         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7828                   (match_operand:HI 2 "general_operand" "rn,rm")))
7829    (clobber (reg:CC FLAGS_REG))]
7830   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7831   "sub{w}\t{%2, %0|%0, %2}"
7832   [(set_attr "type" "alu")
7833    (set_attr "mode" "HI")])
7834
7835 (define_insn "*subhi_2"
7836   [(set (reg FLAGS_REG)
7837         (compare
7838           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7839                     (match_operand:HI 2 "general_operand" "rn,rm"))
7840           (const_int 0)))
7841    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7842         (minus:HI (match_dup 1) (match_dup 2)))]
7843   "ix86_match_ccmode (insn, CCGOCmode)
7844    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7845   "sub{w}\t{%2, %0|%0, %2}"
7846   [(set_attr "type" "alu")
7847    (set_attr "mode" "HI")])
7848
7849 (define_insn "*subhi_3"
7850   [(set (reg FLAGS_REG)
7851         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7852                  (match_operand:HI 2 "general_operand" "rn,rm")))
7853    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7854         (minus:HI (match_dup 1) (match_dup 2)))]
7855   "ix86_match_ccmode (insn, CCmode)
7856    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7857   "sub{w}\t{%2, %0|%0, %2}"
7858   [(set_attr "type" "alu")
7859    (set_attr "mode" "HI")])
7860
7861 (define_expand "subqi3"
7862   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7863         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7864                   (match_operand:QI 2 "general_operand" "")))]
7865   "TARGET_QIMODE_MATH"
7866   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7867
7868 (define_insn "*subqi_1"
7869   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7870         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7871                   (match_operand:QI 2 "general_operand" "qn,qm")))
7872    (clobber (reg:CC FLAGS_REG))]
7873   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7874   "sub{b}\t{%2, %0|%0, %2}"
7875   [(set_attr "type" "alu")
7876    (set_attr "mode" "QI")])
7877
7878 (define_insn "*subqi_1_slp"
7879   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7880         (minus:QI (match_dup 0)
7881                   (match_operand:QI 1 "general_operand" "qn,qm")))
7882    (clobber (reg:CC FLAGS_REG))]
7883   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7884    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7885   "sub{b}\t{%1, %0|%0, %1}"
7886   [(set_attr "type" "alu1")
7887    (set_attr "mode" "QI")])
7888
7889 (define_insn "*subqi_2"
7890   [(set (reg FLAGS_REG)
7891         (compare
7892           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7893                     (match_operand:QI 2 "general_operand" "qn,qm"))
7894           (const_int 0)))
7895    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7896         (minus:QI (match_dup 1) (match_dup 2)))]
7897   "ix86_match_ccmode (insn, CCGOCmode)
7898    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7899   "sub{b}\t{%2, %0|%0, %2}"
7900   [(set_attr "type" "alu")
7901    (set_attr "mode" "QI")])
7902
7903 (define_insn "*subqi_3"
7904   [(set (reg FLAGS_REG)
7905         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7906                  (match_operand:QI 2 "general_operand" "qn,qm")))
7907    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7908         (minus:QI (match_dup 1) (match_dup 2)))]
7909   "ix86_match_ccmode (insn, CCmode)
7910    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7911   "sub{b}\t{%2, %0|%0, %2}"
7912   [(set_attr "type" "alu")
7913    (set_attr "mode" "QI")])
7914
7915 ;; The patterns that match these are at the end of this file.
7916
7917 (define_expand "subxf3"
7918   [(set (match_operand:XF 0 "register_operand" "")
7919         (minus:XF (match_operand:XF 1 "register_operand" "")
7920                   (match_operand:XF 2 "register_operand" "")))]
7921   "TARGET_80387"
7922   "")
7923
7924 (define_expand "sub<mode>3"
7925   [(set (match_operand:MODEF 0 "register_operand" "")
7926         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7927                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7928   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7929     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7930   "")
7931 \f
7932 ;; Multiply instructions
7933
7934 (define_expand "muldi3"
7935   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7936                    (mult:DI (match_operand:DI 1 "register_operand" "")
7937                             (match_operand:DI 2 "x86_64_general_operand" "")))
7938               (clobber (reg:CC FLAGS_REG))])]
7939   "TARGET_64BIT"
7940   "")
7941
7942 ;; On AMDFAM10
7943 ;; IMUL reg64, reg64, imm8      Direct
7944 ;; IMUL reg64, mem64, imm8      VectorPath
7945 ;; IMUL reg64, reg64, imm32     Direct
7946 ;; IMUL reg64, mem64, imm32     VectorPath
7947 ;; IMUL reg64, reg64            Direct
7948 ;; IMUL reg64, mem64            Direct
7949
7950 (define_insn "*muldi3_1_rex64"
7951   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7952         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7953                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7954    (clobber (reg:CC FLAGS_REG))]
7955   "TARGET_64BIT
7956    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7957   "@
7958    imul{q}\t{%2, %1, %0|%0, %1, %2}
7959    imul{q}\t{%2, %1, %0|%0, %1, %2}
7960    imul{q}\t{%2, %0|%0, %2}"
7961   [(set_attr "type" "imul")
7962    (set_attr "prefix_0f" "0,0,1")
7963    (set (attr "athlon_decode")
7964         (cond [(eq_attr "cpu" "athlon")
7965                   (const_string "vector")
7966                (eq_attr "alternative" "1")
7967                   (const_string "vector")
7968                (and (eq_attr "alternative" "2")
7969                     (match_operand 1 "memory_operand" ""))
7970                   (const_string "vector")]
7971               (const_string "direct")))
7972    (set (attr "amdfam10_decode")
7973         (cond [(and (eq_attr "alternative" "0,1")
7974                     (match_operand 1 "memory_operand" ""))
7975                   (const_string "vector")]
7976               (const_string "direct")))
7977    (set_attr "mode" "DI")])
7978
7979 (define_expand "mulsi3"
7980   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7981                    (mult:SI (match_operand:SI 1 "register_operand" "")
7982                             (match_operand:SI 2 "general_operand" "")))
7983               (clobber (reg:CC FLAGS_REG))])]
7984   ""
7985   "")
7986
7987 ;; On AMDFAM10
7988 ;; IMUL reg32, reg32, imm8      Direct
7989 ;; IMUL reg32, mem32, imm8      VectorPath
7990 ;; IMUL reg32, reg32, imm32     Direct
7991 ;; IMUL reg32, mem32, imm32     VectorPath
7992 ;; IMUL reg32, reg32            Direct
7993 ;; IMUL reg32, mem32            Direct
7994
7995 (define_insn "*mulsi3_1"
7996   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7997         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7998                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7999    (clobber (reg:CC FLAGS_REG))]
8000   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8001   "@
8002    imul{l}\t{%2, %1, %0|%0, %1, %2}
8003    imul{l}\t{%2, %1, %0|%0, %1, %2}
8004    imul{l}\t{%2, %0|%0, %2}"
8005   [(set_attr "type" "imul")
8006    (set_attr "prefix_0f" "0,0,1")
8007    (set (attr "athlon_decode")
8008         (cond [(eq_attr "cpu" "athlon")
8009                   (const_string "vector")
8010                (eq_attr "alternative" "1")
8011                   (const_string "vector")
8012                (and (eq_attr "alternative" "2")
8013                     (match_operand 1 "memory_operand" ""))
8014                   (const_string "vector")]
8015               (const_string "direct")))
8016    (set (attr "amdfam10_decode")
8017         (cond [(and (eq_attr "alternative" "0,1")
8018                     (match_operand 1 "memory_operand" ""))
8019                   (const_string "vector")]
8020               (const_string "direct")))
8021    (set_attr "mode" "SI")])
8022
8023 (define_insn "*mulsi3_1_zext"
8024   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8025         (zero_extend:DI
8026           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8027                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
8028    (clobber (reg:CC FLAGS_REG))]
8029   "TARGET_64BIT
8030    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8031   "@
8032    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8033    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8034    imul{l}\t{%2, %k0|%k0, %2}"
8035   [(set_attr "type" "imul")
8036    (set_attr "prefix_0f" "0,0,1")
8037    (set (attr "athlon_decode")
8038         (cond [(eq_attr "cpu" "athlon")
8039                   (const_string "vector")
8040                (eq_attr "alternative" "1")
8041                   (const_string "vector")
8042                (and (eq_attr "alternative" "2")
8043                     (match_operand 1 "memory_operand" ""))
8044                   (const_string "vector")]
8045               (const_string "direct")))
8046    (set (attr "amdfam10_decode")
8047         (cond [(and (eq_attr "alternative" "0,1")
8048                     (match_operand 1 "memory_operand" ""))
8049                   (const_string "vector")]
8050               (const_string "direct")))
8051    (set_attr "mode" "SI")])
8052
8053 (define_expand "mulhi3"
8054   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8055                    (mult:HI (match_operand:HI 1 "register_operand" "")
8056                             (match_operand:HI 2 "general_operand" "")))
8057               (clobber (reg:CC FLAGS_REG))])]
8058   "TARGET_HIMODE_MATH"
8059   "")
8060
8061 ;; On AMDFAM10
8062 ;; IMUL reg16, reg16, imm8      VectorPath
8063 ;; IMUL reg16, mem16, imm8      VectorPath
8064 ;; IMUL reg16, reg16, imm16     VectorPath
8065 ;; IMUL reg16, mem16, imm16     VectorPath
8066 ;; IMUL reg16, reg16            Direct
8067 ;; IMUL reg16, mem16            Direct
8068 (define_insn "*mulhi3_1"
8069   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8070         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8071                  (match_operand:HI 2 "general_operand" "K,n,mr")))
8072    (clobber (reg:CC FLAGS_REG))]
8073   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8074   "@
8075    imul{w}\t{%2, %1, %0|%0, %1, %2}
8076    imul{w}\t{%2, %1, %0|%0, %1, %2}
8077    imul{w}\t{%2, %0|%0, %2}"
8078   [(set_attr "type" "imul")
8079    (set_attr "prefix_0f" "0,0,1")
8080    (set (attr "athlon_decode")
8081         (cond [(eq_attr "cpu" "athlon")
8082                   (const_string "vector")
8083                (eq_attr "alternative" "1,2")
8084                   (const_string "vector")]
8085               (const_string "direct")))
8086    (set (attr "amdfam10_decode")
8087         (cond [(eq_attr "alternative" "0,1")
8088                   (const_string "vector")]
8089               (const_string "direct")))
8090    (set_attr "mode" "HI")])
8091
8092 (define_expand "mulqi3"
8093   [(parallel [(set (match_operand:QI 0 "register_operand" "")
8094                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8095                             (match_operand:QI 2 "register_operand" "")))
8096               (clobber (reg:CC FLAGS_REG))])]
8097   "TARGET_QIMODE_MATH"
8098   "")
8099
8100 ;;On AMDFAM10
8101 ;; MUL reg8     Direct
8102 ;; MUL mem8     Direct
8103
8104 (define_insn "*mulqi3_1"
8105   [(set (match_operand:QI 0 "register_operand" "=a")
8106         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8107                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8108    (clobber (reg:CC FLAGS_REG))]
8109   "TARGET_QIMODE_MATH
8110    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8111   "mul{b}\t%2"
8112   [(set_attr "type" "imul")
8113    (set_attr "length_immediate" "0")
8114    (set (attr "athlon_decode")
8115      (if_then_else (eq_attr "cpu" "athlon")
8116         (const_string "vector")
8117         (const_string "direct")))
8118    (set_attr "amdfam10_decode" "direct")
8119    (set_attr "mode" "QI")])
8120
8121 (define_expand "umulqihi3"
8122   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8123                    (mult:HI (zero_extend:HI
8124                               (match_operand:QI 1 "nonimmediate_operand" ""))
8125                             (zero_extend:HI
8126                               (match_operand:QI 2 "register_operand" ""))))
8127               (clobber (reg:CC FLAGS_REG))])]
8128   "TARGET_QIMODE_MATH"
8129   "")
8130
8131 (define_insn "*umulqihi3_1"
8132   [(set (match_operand:HI 0 "register_operand" "=a")
8133         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8134                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8135    (clobber (reg:CC FLAGS_REG))]
8136   "TARGET_QIMODE_MATH
8137    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8138   "mul{b}\t%2"
8139   [(set_attr "type" "imul")
8140    (set_attr "length_immediate" "0")
8141    (set (attr "athlon_decode")
8142      (if_then_else (eq_attr "cpu" "athlon")
8143         (const_string "vector")
8144         (const_string "direct")))
8145    (set_attr "amdfam10_decode" "direct")
8146    (set_attr "mode" "QI")])
8147
8148 (define_expand "mulqihi3"
8149   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8150                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8151                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8152               (clobber (reg:CC FLAGS_REG))])]
8153   "TARGET_QIMODE_MATH"
8154   "")
8155
8156 (define_insn "*mulqihi3_insn"
8157   [(set (match_operand:HI 0 "register_operand" "=a")
8158         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8159                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8160    (clobber (reg:CC FLAGS_REG))]
8161   "TARGET_QIMODE_MATH
8162    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8163   "imul{b}\t%2"
8164   [(set_attr "type" "imul")
8165    (set_attr "length_immediate" "0")
8166    (set (attr "athlon_decode")
8167      (if_then_else (eq_attr "cpu" "athlon")
8168         (const_string "vector")
8169         (const_string "direct")))
8170    (set_attr "amdfam10_decode" "direct")
8171    (set_attr "mode" "QI")])
8172
8173 (define_expand "umulditi3"
8174   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8175                    (mult:TI (zero_extend:TI
8176                               (match_operand:DI 1 "nonimmediate_operand" ""))
8177                             (zero_extend:TI
8178                               (match_operand:DI 2 "register_operand" ""))))
8179               (clobber (reg:CC FLAGS_REG))])]
8180   "TARGET_64BIT"
8181   "")
8182
8183 (define_insn "*umulditi3_insn"
8184   [(set (match_operand:TI 0 "register_operand" "=A")
8185         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8186                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8187    (clobber (reg:CC FLAGS_REG))]
8188   "TARGET_64BIT
8189    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8190   "mul{q}\t%2"
8191   [(set_attr "type" "imul")
8192    (set_attr "length_immediate" "0")
8193    (set (attr "athlon_decode")
8194      (if_then_else (eq_attr "cpu" "athlon")
8195         (const_string "vector")
8196         (const_string "double")))
8197    (set_attr "amdfam10_decode" "double")
8198    (set_attr "mode" "DI")])
8199
8200 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8201 (define_expand "umulsidi3"
8202   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8203                    (mult:DI (zero_extend:DI
8204                               (match_operand:SI 1 "nonimmediate_operand" ""))
8205                             (zero_extend:DI
8206                               (match_operand:SI 2 "register_operand" ""))))
8207               (clobber (reg:CC FLAGS_REG))])]
8208   "!TARGET_64BIT"
8209   "")
8210
8211 (define_insn "*umulsidi3_insn"
8212   [(set (match_operand:DI 0 "register_operand" "=A")
8213         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8214                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8215    (clobber (reg:CC FLAGS_REG))]
8216   "!TARGET_64BIT
8217    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8218   "mul{l}\t%2"
8219   [(set_attr "type" "imul")
8220    (set_attr "length_immediate" "0")
8221    (set (attr "athlon_decode")
8222      (if_then_else (eq_attr "cpu" "athlon")
8223         (const_string "vector")
8224         (const_string "double")))
8225    (set_attr "amdfam10_decode" "double")
8226    (set_attr "mode" "SI")])
8227
8228 (define_expand "mulditi3"
8229   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8230                    (mult:TI (sign_extend:TI
8231                               (match_operand:DI 1 "nonimmediate_operand" ""))
8232                             (sign_extend:TI
8233                               (match_operand:DI 2 "register_operand" ""))))
8234               (clobber (reg:CC FLAGS_REG))])]
8235   "TARGET_64BIT"
8236   "")
8237
8238 (define_insn "*mulditi3_insn"
8239   [(set (match_operand:TI 0 "register_operand" "=A")
8240         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8241                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "TARGET_64BIT
8244    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8245   "imul{q}\t%2"
8246   [(set_attr "type" "imul")
8247    (set_attr "length_immediate" "0")
8248    (set (attr "athlon_decode")
8249      (if_then_else (eq_attr "cpu" "athlon")
8250         (const_string "vector")
8251         (const_string "double")))
8252    (set_attr "amdfam10_decode" "double")
8253    (set_attr "mode" "DI")])
8254
8255 (define_expand "mulsidi3"
8256   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8257                    (mult:DI (sign_extend:DI
8258                               (match_operand:SI 1 "nonimmediate_operand" ""))
8259                             (sign_extend:DI
8260                               (match_operand:SI 2 "register_operand" ""))))
8261               (clobber (reg:CC FLAGS_REG))])]
8262   "!TARGET_64BIT"
8263   "")
8264
8265 (define_insn "*mulsidi3_insn"
8266   [(set (match_operand:DI 0 "register_operand" "=A")
8267         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8268                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8269    (clobber (reg:CC FLAGS_REG))]
8270   "!TARGET_64BIT
8271    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8272   "imul{l}\t%2"
8273   [(set_attr "type" "imul")
8274    (set_attr "length_immediate" "0")
8275    (set (attr "athlon_decode")
8276      (if_then_else (eq_attr "cpu" "athlon")
8277         (const_string "vector")
8278         (const_string "double")))
8279    (set_attr "amdfam10_decode" "double")
8280    (set_attr "mode" "SI")])
8281
8282 (define_expand "umuldi3_highpart"
8283   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8284                    (truncate:DI
8285                      (lshiftrt:TI
8286                        (mult:TI (zero_extend:TI
8287                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8288                                 (zero_extend:TI
8289                                   (match_operand:DI 2 "register_operand" "")))
8290                        (const_int 64))))
8291               (clobber (match_scratch:DI 3 ""))
8292               (clobber (reg:CC FLAGS_REG))])]
8293   "TARGET_64BIT"
8294   "")
8295
8296 (define_insn "*umuldi3_highpart_rex64"
8297   [(set (match_operand:DI 0 "register_operand" "=d")
8298         (truncate:DI
8299           (lshiftrt:TI
8300             (mult:TI (zero_extend:TI
8301                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8302                      (zero_extend:TI
8303                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8304             (const_int 64))))
8305    (clobber (match_scratch:DI 3 "=1"))
8306    (clobber (reg:CC FLAGS_REG))]
8307   "TARGET_64BIT
8308    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8309   "mul{q}\t%2"
8310   [(set_attr "type" "imul")
8311    (set_attr "length_immediate" "0")
8312    (set (attr "athlon_decode")
8313      (if_then_else (eq_attr "cpu" "athlon")
8314         (const_string "vector")
8315         (const_string "double")))
8316    (set_attr "amdfam10_decode" "double")
8317    (set_attr "mode" "DI")])
8318
8319 (define_expand "umulsi3_highpart"
8320   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8321                    (truncate:SI
8322                      (lshiftrt:DI
8323                        (mult:DI (zero_extend:DI
8324                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8325                                 (zero_extend:DI
8326                                   (match_operand:SI 2 "register_operand" "")))
8327                        (const_int 32))))
8328               (clobber (match_scratch:SI 3 ""))
8329               (clobber (reg:CC FLAGS_REG))])]
8330   ""
8331   "")
8332
8333 (define_insn "*umulsi3_highpart_insn"
8334   [(set (match_operand:SI 0 "register_operand" "=d")
8335         (truncate:SI
8336           (lshiftrt:DI
8337             (mult:DI (zero_extend:DI
8338                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8339                      (zero_extend:DI
8340                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8341             (const_int 32))))
8342    (clobber (match_scratch:SI 3 "=1"))
8343    (clobber (reg:CC FLAGS_REG))]
8344   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8345   "mul{l}\t%2"
8346   [(set_attr "type" "imul")
8347    (set_attr "length_immediate" "0")
8348    (set (attr "athlon_decode")
8349      (if_then_else (eq_attr "cpu" "athlon")
8350         (const_string "vector")
8351         (const_string "double")))
8352    (set_attr "amdfam10_decode" "double")
8353    (set_attr "mode" "SI")])
8354
8355 (define_insn "*umulsi3_highpart_zext"
8356   [(set (match_operand:DI 0 "register_operand" "=d")
8357         (zero_extend:DI (truncate:SI
8358           (lshiftrt:DI
8359             (mult:DI (zero_extend:DI
8360                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8361                      (zero_extend:DI
8362                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8363             (const_int 32)))))
8364    (clobber (match_scratch:SI 3 "=1"))
8365    (clobber (reg:CC FLAGS_REG))]
8366   "TARGET_64BIT
8367    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8368   "mul{l}\t%2"
8369   [(set_attr "type" "imul")
8370    (set_attr "length_immediate" "0")
8371    (set (attr "athlon_decode")
8372      (if_then_else (eq_attr "cpu" "athlon")
8373         (const_string "vector")
8374         (const_string "double")))
8375    (set_attr "amdfam10_decode" "double")
8376    (set_attr "mode" "SI")])
8377
8378 (define_expand "smuldi3_highpart"
8379   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8380                    (truncate:DI
8381                      (lshiftrt:TI
8382                        (mult:TI (sign_extend:TI
8383                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8384                                 (sign_extend:TI
8385                                   (match_operand:DI 2 "register_operand" "")))
8386                        (const_int 64))))
8387               (clobber (match_scratch:DI 3 ""))
8388               (clobber (reg:CC FLAGS_REG))])]
8389   "TARGET_64BIT"
8390   "")
8391
8392 (define_insn "*smuldi3_highpart_rex64"
8393   [(set (match_operand:DI 0 "register_operand" "=d")
8394         (truncate:DI
8395           (lshiftrt:TI
8396             (mult:TI (sign_extend:TI
8397                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8398                      (sign_extend:TI
8399                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8400             (const_int 64))))
8401    (clobber (match_scratch:DI 3 "=1"))
8402    (clobber (reg:CC FLAGS_REG))]
8403   "TARGET_64BIT
8404    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8405   "imul{q}\t%2"
8406   [(set_attr "type" "imul")
8407    (set (attr "athlon_decode")
8408      (if_then_else (eq_attr "cpu" "athlon")
8409         (const_string "vector")
8410         (const_string "double")))
8411    (set_attr "amdfam10_decode" "double")
8412    (set_attr "mode" "DI")])
8413
8414 (define_expand "smulsi3_highpart"
8415   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8416                    (truncate:SI
8417                      (lshiftrt:DI
8418                        (mult:DI (sign_extend:DI
8419                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8420                                 (sign_extend:DI
8421                                   (match_operand:SI 2 "register_operand" "")))
8422                        (const_int 32))))
8423               (clobber (match_scratch:SI 3 ""))
8424               (clobber (reg:CC FLAGS_REG))])]
8425   ""
8426   "")
8427
8428 (define_insn "*smulsi3_highpart_insn"
8429   [(set (match_operand:SI 0 "register_operand" "=d")
8430         (truncate:SI
8431           (lshiftrt:DI
8432             (mult:DI (sign_extend:DI
8433                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8434                      (sign_extend:DI
8435                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8436             (const_int 32))))
8437    (clobber (match_scratch:SI 3 "=1"))
8438    (clobber (reg:CC FLAGS_REG))]
8439   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8440   "imul{l}\t%2"
8441   [(set_attr "type" "imul")
8442    (set (attr "athlon_decode")
8443      (if_then_else (eq_attr "cpu" "athlon")
8444         (const_string "vector")
8445         (const_string "double")))
8446    (set_attr "amdfam10_decode" "double")
8447    (set_attr "mode" "SI")])
8448
8449 (define_insn "*smulsi3_highpart_zext"
8450   [(set (match_operand:DI 0 "register_operand" "=d")
8451         (zero_extend:DI (truncate:SI
8452           (lshiftrt:DI
8453             (mult:DI (sign_extend:DI
8454                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8455                      (sign_extend:DI
8456                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8457             (const_int 32)))))
8458    (clobber (match_scratch:SI 3 "=1"))
8459    (clobber (reg:CC FLAGS_REG))]
8460   "TARGET_64BIT
8461    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8462   "imul{l}\t%2"
8463   [(set_attr "type" "imul")
8464    (set (attr "athlon_decode")
8465      (if_then_else (eq_attr "cpu" "athlon")
8466         (const_string "vector")
8467         (const_string "double")))
8468    (set_attr "amdfam10_decode" "double")
8469    (set_attr "mode" "SI")])
8470
8471 ;; The patterns that match these are at the end of this file.
8472
8473 (define_expand "mulxf3"
8474   [(set (match_operand:XF 0 "register_operand" "")
8475         (mult:XF (match_operand:XF 1 "register_operand" "")
8476                  (match_operand:XF 2 "register_operand" "")))]
8477   "TARGET_80387"
8478   "")
8479
8480 (define_expand "mul<mode>3"
8481   [(set (match_operand:MODEF 0 "register_operand" "")
8482         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8483                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8484   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8485     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8486   "")
8487
8488 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8489
8490 \f
8491 ;; Divide instructions
8492
8493 (define_insn "divqi3"
8494   [(set (match_operand:QI 0 "register_operand" "=a")
8495         (div:QI (match_operand:HI 1 "register_operand" "0")
8496                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8497    (clobber (reg:CC FLAGS_REG))]
8498   "TARGET_QIMODE_MATH"
8499   "idiv{b}\t%2"
8500   [(set_attr "type" "idiv")
8501    (set_attr "mode" "QI")])
8502
8503 (define_insn "udivqi3"
8504   [(set (match_operand:QI 0 "register_operand" "=a")
8505         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8506                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8507    (clobber (reg:CC FLAGS_REG))]
8508   "TARGET_QIMODE_MATH"
8509   "div{b}\t%2"
8510   [(set_attr "type" "idiv")
8511    (set_attr "mode" "QI")])
8512
8513 ;; The patterns that match these are at the end of this file.
8514
8515 (define_expand "divxf3"
8516   [(set (match_operand:XF 0 "register_operand" "")
8517         (div:XF (match_operand:XF 1 "register_operand" "")
8518                 (match_operand:XF 2 "register_operand" "")))]
8519   "TARGET_80387"
8520   "")
8521
8522 (define_expand "divdf3"
8523   [(set (match_operand:DF 0 "register_operand" "")
8524         (div:DF (match_operand:DF 1 "register_operand" "")
8525                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8526    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8527     || (TARGET_SSE2 && TARGET_SSE_MATH)"
8528    "")
8529
8530 (define_expand "divsf3"
8531   [(set (match_operand:SF 0 "register_operand" "")
8532         (div:SF (match_operand:SF 1 "register_operand" "")
8533                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8534   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8535     || TARGET_SSE_MATH"
8536 {
8537   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8538       && flag_finite_math_only && !flag_trapping_math
8539       && flag_unsafe_math_optimizations)
8540     {
8541       ix86_emit_swdivsf (operands[0], operands[1],
8542                          operands[2], SFmode);
8543       DONE;
8544     }
8545 })
8546 \f
8547 ;; Remainder instructions.
8548
8549 (define_expand "divmoddi4"
8550   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8551                    (div:DI (match_operand:DI 1 "register_operand" "")
8552                            (match_operand:DI 2 "nonimmediate_operand" "")))
8553               (set (match_operand:DI 3 "register_operand" "")
8554                    (mod:DI (match_dup 1) (match_dup 2)))
8555               (clobber (reg:CC FLAGS_REG))])]
8556   "TARGET_64BIT"
8557   "")
8558
8559 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8560 ;; Penalize eax case slightly because it results in worse scheduling
8561 ;; of code.
8562 (define_insn "*divmoddi4_nocltd_rex64"
8563   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8564         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8565                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8566    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8567         (mod:DI (match_dup 2) (match_dup 3)))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8570   "#"
8571   [(set_attr "type" "multi")])
8572
8573 (define_insn "*divmoddi4_cltd_rex64"
8574   [(set (match_operand:DI 0 "register_operand" "=a")
8575         (div:DI (match_operand:DI 2 "register_operand" "a")
8576                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8577    (set (match_operand:DI 1 "register_operand" "=&d")
8578         (mod:DI (match_dup 2) (match_dup 3)))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8581   "#"
8582   [(set_attr "type" "multi")])
8583
8584 (define_insn "*divmoddi_noext_rex64"
8585   [(set (match_operand:DI 0 "register_operand" "=a")
8586         (div:DI (match_operand:DI 1 "register_operand" "0")
8587                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8588    (set (match_operand:DI 3 "register_operand" "=d")
8589         (mod:DI (match_dup 1) (match_dup 2)))
8590    (use (match_operand:DI 4 "register_operand" "3"))
8591    (clobber (reg:CC FLAGS_REG))]
8592   "TARGET_64BIT"
8593   "idiv{q}\t%2"
8594   [(set_attr "type" "idiv")
8595    (set_attr "mode" "DI")])
8596
8597 (define_split
8598   [(set (match_operand:DI 0 "register_operand" "")
8599         (div:DI (match_operand:DI 1 "register_operand" "")
8600                 (match_operand:DI 2 "nonimmediate_operand" "")))
8601    (set (match_operand:DI 3 "register_operand" "")
8602         (mod:DI (match_dup 1) (match_dup 2)))
8603    (clobber (reg:CC FLAGS_REG))]
8604   "TARGET_64BIT && reload_completed"
8605   [(parallel [(set (match_dup 3)
8606                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8607               (clobber (reg:CC FLAGS_REG))])
8608    (parallel [(set (match_dup 0)
8609                    (div:DI (reg:DI 0) (match_dup 2)))
8610               (set (match_dup 3)
8611                    (mod:DI (reg:DI 0) (match_dup 2)))
8612               (use (match_dup 3))
8613               (clobber (reg:CC FLAGS_REG))])]
8614 {
8615   /* Avoid use of cltd in favor of a mov+shift.  */
8616   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8617     {
8618       if (true_regnum (operands[1]))
8619         emit_move_insn (operands[0], operands[1]);
8620       else
8621         emit_move_insn (operands[3], operands[1]);
8622       operands[4] = operands[3];
8623     }
8624   else
8625     {
8626       gcc_assert (!true_regnum (operands[1]));
8627       operands[4] = operands[1];
8628     }
8629 })
8630
8631
8632 (define_expand "divmodsi4"
8633   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8634                    (div:SI (match_operand:SI 1 "register_operand" "")
8635                            (match_operand:SI 2 "nonimmediate_operand" "")))
8636               (set (match_operand:SI 3 "register_operand" "")
8637                    (mod:SI (match_dup 1) (match_dup 2)))
8638               (clobber (reg:CC FLAGS_REG))])]
8639   ""
8640   "")
8641
8642 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8643 ;; Penalize eax case slightly because it results in worse scheduling
8644 ;; of code.
8645 (define_insn "*divmodsi4_nocltd"
8646   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8647         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8648                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8649    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8650         (mod:SI (match_dup 2) (match_dup 3)))
8651    (clobber (reg:CC FLAGS_REG))]
8652   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8653   "#"
8654   [(set_attr "type" "multi")])
8655
8656 (define_insn "*divmodsi4_cltd"
8657   [(set (match_operand:SI 0 "register_operand" "=a")
8658         (div:SI (match_operand:SI 2 "register_operand" "a")
8659                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8660    (set (match_operand:SI 1 "register_operand" "=&d")
8661         (mod:SI (match_dup 2) (match_dup 3)))
8662    (clobber (reg:CC FLAGS_REG))]
8663   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8664   "#"
8665   [(set_attr "type" "multi")])
8666
8667 (define_insn "*divmodsi_noext"
8668   [(set (match_operand:SI 0 "register_operand" "=a")
8669         (div:SI (match_operand:SI 1 "register_operand" "0")
8670                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8671    (set (match_operand:SI 3 "register_operand" "=d")
8672         (mod:SI (match_dup 1) (match_dup 2)))
8673    (use (match_operand:SI 4 "register_operand" "3"))
8674    (clobber (reg:CC FLAGS_REG))]
8675   ""
8676   "idiv{l}\t%2"
8677   [(set_attr "type" "idiv")
8678    (set_attr "mode" "SI")])
8679
8680 (define_split
8681   [(set (match_operand:SI 0 "register_operand" "")
8682         (div:SI (match_operand:SI 1 "register_operand" "")
8683                 (match_operand:SI 2 "nonimmediate_operand" "")))
8684    (set (match_operand:SI 3 "register_operand" "")
8685         (mod:SI (match_dup 1) (match_dup 2)))
8686    (clobber (reg:CC FLAGS_REG))]
8687   "reload_completed"
8688   [(parallel [(set (match_dup 3)
8689                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8690               (clobber (reg:CC FLAGS_REG))])
8691    (parallel [(set (match_dup 0)
8692                    (div:SI (reg:SI 0) (match_dup 2)))
8693               (set (match_dup 3)
8694                    (mod:SI (reg:SI 0) (match_dup 2)))
8695               (use (match_dup 3))
8696               (clobber (reg:CC FLAGS_REG))])]
8697 {
8698   /* Avoid use of cltd in favor of a mov+shift.  */
8699   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8700     {
8701       if (true_regnum (operands[1]))
8702         emit_move_insn (operands[0], operands[1]);
8703       else
8704         emit_move_insn (operands[3], operands[1]);
8705       operands[4] = operands[3];
8706     }
8707   else
8708     {
8709       gcc_assert (!true_regnum (operands[1]));
8710       operands[4] = operands[1];
8711     }
8712 })
8713 ;; %%% Split me.
8714 (define_insn "divmodhi4"
8715   [(set (match_operand:HI 0 "register_operand" "=a")
8716         (div:HI (match_operand:HI 1 "register_operand" "0")
8717                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8718    (set (match_operand:HI 3 "register_operand" "=&d")
8719         (mod:HI (match_dup 1) (match_dup 2)))
8720    (clobber (reg:CC FLAGS_REG))]
8721   "TARGET_HIMODE_MATH"
8722   "cwtd\;idiv{w}\t%2"
8723   [(set_attr "type" "multi")
8724    (set_attr "length_immediate" "0")
8725    (set_attr "mode" "SI")])
8726
8727 (define_insn "udivmoddi4"
8728   [(set (match_operand:DI 0 "register_operand" "=a")
8729         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8730                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8731    (set (match_operand:DI 3 "register_operand" "=&d")
8732         (umod:DI (match_dup 1) (match_dup 2)))
8733    (clobber (reg:CC FLAGS_REG))]
8734   "TARGET_64BIT"
8735   "xor{q}\t%3, %3\;div{q}\t%2"
8736   [(set_attr "type" "multi")
8737    (set_attr "length_immediate" "0")
8738    (set_attr "mode" "DI")])
8739
8740 (define_insn "*udivmoddi4_noext"
8741   [(set (match_operand:DI 0 "register_operand" "=a")
8742         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8743                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8744    (set (match_operand:DI 3 "register_operand" "=d")
8745         (umod:DI (match_dup 1) (match_dup 2)))
8746    (use (match_dup 3))
8747    (clobber (reg:CC FLAGS_REG))]
8748   "TARGET_64BIT"
8749   "div{q}\t%2"
8750   [(set_attr "type" "idiv")
8751    (set_attr "mode" "DI")])
8752
8753 (define_split
8754   [(set (match_operand:DI 0 "register_operand" "")
8755         (udiv:DI (match_operand:DI 1 "register_operand" "")
8756                  (match_operand:DI 2 "nonimmediate_operand" "")))
8757    (set (match_operand:DI 3 "register_operand" "")
8758         (umod:DI (match_dup 1) (match_dup 2)))
8759    (clobber (reg:CC FLAGS_REG))]
8760   "TARGET_64BIT && reload_completed"
8761   [(set (match_dup 3) (const_int 0))
8762    (parallel [(set (match_dup 0)
8763                    (udiv:DI (match_dup 1) (match_dup 2)))
8764               (set (match_dup 3)
8765                    (umod:DI (match_dup 1) (match_dup 2)))
8766               (use (match_dup 3))
8767               (clobber (reg:CC FLAGS_REG))])]
8768   "")
8769
8770 (define_insn "udivmodsi4"
8771   [(set (match_operand:SI 0 "register_operand" "=a")
8772         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8773                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8774    (set (match_operand:SI 3 "register_operand" "=&d")
8775         (umod:SI (match_dup 1) (match_dup 2)))
8776    (clobber (reg:CC FLAGS_REG))]
8777   ""
8778   "xor{l}\t%3, %3\;div{l}\t%2"
8779   [(set_attr "type" "multi")
8780    (set_attr "length_immediate" "0")
8781    (set_attr "mode" "SI")])
8782
8783 (define_insn "*udivmodsi4_noext"
8784   [(set (match_operand:SI 0 "register_operand" "=a")
8785         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8786                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8787    (set (match_operand:SI 3 "register_operand" "=d")
8788         (umod:SI (match_dup 1) (match_dup 2)))
8789    (use (match_dup 3))
8790    (clobber (reg:CC FLAGS_REG))]
8791   ""
8792   "div{l}\t%2"
8793   [(set_attr "type" "idiv")
8794    (set_attr "mode" "SI")])
8795
8796 (define_split
8797   [(set (match_operand:SI 0 "register_operand" "")
8798         (udiv:SI (match_operand:SI 1 "register_operand" "")
8799                  (match_operand:SI 2 "nonimmediate_operand" "")))
8800    (set (match_operand:SI 3 "register_operand" "")
8801         (umod:SI (match_dup 1) (match_dup 2)))
8802    (clobber (reg:CC FLAGS_REG))]
8803   "reload_completed"
8804   [(set (match_dup 3) (const_int 0))
8805    (parallel [(set (match_dup 0)
8806                    (udiv:SI (match_dup 1) (match_dup 2)))
8807               (set (match_dup 3)
8808                    (umod:SI (match_dup 1) (match_dup 2)))
8809               (use (match_dup 3))
8810               (clobber (reg:CC FLAGS_REG))])]
8811   "")
8812
8813 (define_expand "udivmodhi4"
8814   [(set (match_dup 4) (const_int 0))
8815    (parallel [(set (match_operand:HI 0 "register_operand" "")
8816                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8817                             (match_operand:HI 2 "nonimmediate_operand" "")))
8818               (set (match_operand:HI 3 "register_operand" "")
8819                    (umod:HI (match_dup 1) (match_dup 2)))
8820               (use (match_dup 4))
8821               (clobber (reg:CC FLAGS_REG))])]
8822   "TARGET_HIMODE_MATH"
8823   "operands[4] = gen_reg_rtx (HImode);")
8824
8825 (define_insn "*udivmodhi_noext"
8826   [(set (match_operand:HI 0 "register_operand" "=a")
8827         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8828                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8829    (set (match_operand:HI 3 "register_operand" "=d")
8830         (umod:HI (match_dup 1) (match_dup 2)))
8831    (use (match_operand:HI 4 "register_operand" "3"))
8832    (clobber (reg:CC FLAGS_REG))]
8833   ""
8834   "div{w}\t%2"
8835   [(set_attr "type" "idiv")
8836    (set_attr "mode" "HI")])
8837
8838 ;; We cannot use div/idiv for double division, because it causes
8839 ;; "division by zero" on the overflow and that's not what we expect
8840 ;; from truncate.  Because true (non truncating) double division is
8841 ;; never generated, we can't create this insn anyway.
8842 ;
8843 ;(define_insn ""
8844 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8845 ;       (truncate:SI
8846 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8847 ;                  (zero_extend:DI
8848 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8849 ;   (set (match_operand:SI 3 "register_operand" "=d")
8850 ;       (truncate:SI
8851 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8852 ;   (clobber (reg:CC FLAGS_REG))]
8853 ;  ""
8854 ;  "div{l}\t{%2, %0|%0, %2}"
8855 ;  [(set_attr "type" "idiv")])
8856 \f
8857 ;;- Logical AND instructions
8858
8859 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8860 ;; Note that this excludes ah.
8861
8862 (define_insn "*testdi_1_rex64"
8863   [(set (reg FLAGS_REG)
8864         (compare
8865           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8866                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8867           (const_int 0)))]
8868   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8869    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8870   "@
8871    test{l}\t{%k1, %k0|%k0, %k1}
8872    test{l}\t{%k1, %k0|%k0, %k1}
8873    test{q}\t{%1, %0|%0, %1}
8874    test{q}\t{%1, %0|%0, %1}
8875    test{q}\t{%1, %0|%0, %1}"
8876   [(set_attr "type" "test")
8877    (set_attr "modrm" "0,1,0,1,1")
8878    (set_attr "mode" "SI,SI,DI,DI,DI")
8879    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8880
8881 (define_insn "testsi_1"
8882   [(set (reg FLAGS_REG)
8883         (compare
8884           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8885                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8886           (const_int 0)))]
8887   "ix86_match_ccmode (insn, CCNOmode)
8888    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8889   "test{l}\t{%1, %0|%0, %1}"
8890   [(set_attr "type" "test")
8891    (set_attr "modrm" "0,1,1")
8892    (set_attr "mode" "SI")
8893    (set_attr "pent_pair" "uv,np,uv")])
8894
8895 (define_expand "testsi_ccno_1"
8896   [(set (reg:CCNO FLAGS_REG)
8897         (compare:CCNO
8898           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8899                   (match_operand:SI 1 "nonmemory_operand" ""))
8900           (const_int 0)))]
8901   ""
8902   "")
8903
8904 (define_insn "*testhi_1"
8905   [(set (reg FLAGS_REG)
8906         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8907                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8908                  (const_int 0)))]
8909   "ix86_match_ccmode (insn, CCNOmode)
8910    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8911   "test{w}\t{%1, %0|%0, %1}"
8912   [(set_attr "type" "test")
8913    (set_attr "modrm" "0,1,1")
8914    (set_attr "mode" "HI")
8915    (set_attr "pent_pair" "uv,np,uv")])
8916
8917 (define_expand "testqi_ccz_1"
8918   [(set (reg:CCZ FLAGS_REG)
8919         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8920                              (match_operand:QI 1 "nonmemory_operand" ""))
8921                  (const_int 0)))]
8922   ""
8923   "")
8924
8925 (define_insn "*testqi_1_maybe_si"
8926   [(set (reg FLAGS_REG)
8927         (compare
8928           (and:QI
8929             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8930             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8931           (const_int 0)))]
8932    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8933     && ix86_match_ccmode (insn,
8934                          CONST_INT_P (operands[1])
8935                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8936 {
8937   if (which_alternative == 3)
8938     {
8939       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8940         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8941       return "test{l}\t{%1, %k0|%k0, %1}";
8942     }
8943   return "test{b}\t{%1, %0|%0, %1}";
8944 }
8945   [(set_attr "type" "test")
8946    (set_attr "modrm" "0,1,1,1")
8947    (set_attr "mode" "QI,QI,QI,SI")
8948    (set_attr "pent_pair" "uv,np,uv,np")])
8949
8950 (define_insn "*testqi_1"
8951   [(set (reg FLAGS_REG)
8952         (compare
8953           (and:QI
8954             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8955             (match_operand:QI 1 "general_operand" "n,n,qn"))
8956           (const_int 0)))]
8957   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8958    && ix86_match_ccmode (insn, CCNOmode)"
8959   "test{b}\t{%1, %0|%0, %1}"
8960   [(set_attr "type" "test")
8961    (set_attr "modrm" "0,1,1")
8962    (set_attr "mode" "QI")
8963    (set_attr "pent_pair" "uv,np,uv")])
8964
8965 (define_expand "testqi_ext_ccno_0"
8966   [(set (reg:CCNO FLAGS_REG)
8967         (compare:CCNO
8968           (and:SI
8969             (zero_extract:SI
8970               (match_operand 0 "ext_register_operand" "")
8971               (const_int 8)
8972               (const_int 8))
8973             (match_operand 1 "const_int_operand" ""))
8974           (const_int 0)))]
8975   ""
8976   "")
8977
8978 (define_insn "*testqi_ext_0"
8979   [(set (reg FLAGS_REG)
8980         (compare
8981           (and:SI
8982             (zero_extract:SI
8983               (match_operand 0 "ext_register_operand" "Q")
8984               (const_int 8)
8985               (const_int 8))
8986             (match_operand 1 "const_int_operand" "n"))
8987           (const_int 0)))]
8988   "ix86_match_ccmode (insn, CCNOmode)"
8989   "test{b}\t{%1, %h0|%h0, %1}"
8990   [(set_attr "type" "test")
8991    (set_attr "mode" "QI")
8992    (set_attr "length_immediate" "1")
8993    (set_attr "pent_pair" "np")])
8994
8995 (define_insn "*testqi_ext_1"
8996   [(set (reg FLAGS_REG)
8997         (compare
8998           (and:SI
8999             (zero_extract:SI
9000               (match_operand 0 "ext_register_operand" "Q")
9001               (const_int 8)
9002               (const_int 8))
9003             (zero_extend:SI
9004               (match_operand:QI 1 "general_operand" "Qm")))
9005           (const_int 0)))]
9006   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9007    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9008   "test{b}\t{%1, %h0|%h0, %1}"
9009   [(set_attr "type" "test")
9010    (set_attr "mode" "QI")])
9011
9012 (define_insn "*testqi_ext_1_rex64"
9013   [(set (reg FLAGS_REG)
9014         (compare
9015           (and:SI
9016             (zero_extract:SI
9017               (match_operand 0 "ext_register_operand" "Q")
9018               (const_int 8)
9019               (const_int 8))
9020             (zero_extend:SI
9021               (match_operand:QI 1 "register_operand" "Q")))
9022           (const_int 0)))]
9023   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9024   "test{b}\t{%1, %h0|%h0, %1}"
9025   [(set_attr "type" "test")
9026    (set_attr "mode" "QI")])
9027
9028 (define_insn "*testqi_ext_2"
9029   [(set (reg FLAGS_REG)
9030         (compare
9031           (and:SI
9032             (zero_extract:SI
9033               (match_operand 0 "ext_register_operand" "Q")
9034               (const_int 8)
9035               (const_int 8))
9036             (zero_extract:SI
9037               (match_operand 1 "ext_register_operand" "Q")
9038               (const_int 8)
9039               (const_int 8)))
9040           (const_int 0)))]
9041   "ix86_match_ccmode (insn, CCNOmode)"
9042   "test{b}\t{%h1, %h0|%h0, %h1}"
9043   [(set_attr "type" "test")
9044    (set_attr "mode" "QI")])
9045
9046 ;; Combine likes to form bit extractions for some tests.  Humor it.
9047 (define_insn "*testqi_ext_3"
9048   [(set (reg FLAGS_REG)
9049         (compare (zero_extract:SI
9050                    (match_operand 0 "nonimmediate_operand" "rm")
9051                    (match_operand:SI 1 "const_int_operand" "")
9052                    (match_operand:SI 2 "const_int_operand" ""))
9053                  (const_int 0)))]
9054   "ix86_match_ccmode (insn, CCNOmode)
9055    && INTVAL (operands[1]) > 0
9056    && INTVAL (operands[2]) >= 0
9057    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9058    && (GET_MODE (operands[0]) == SImode
9059        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
9060        || GET_MODE (operands[0]) == HImode
9061        || GET_MODE (operands[0]) == QImode)"
9062   "#")
9063
9064 (define_insn "*testqi_ext_3_rex64"
9065   [(set (reg FLAGS_REG)
9066         (compare (zero_extract:DI
9067                    (match_operand 0 "nonimmediate_operand" "rm")
9068                    (match_operand:DI 1 "const_int_operand" "")
9069                    (match_operand:DI 2 "const_int_operand" ""))
9070                  (const_int 0)))]
9071   "TARGET_64BIT
9072    && ix86_match_ccmode (insn, CCNOmode)
9073    && INTVAL (operands[1]) > 0
9074    && INTVAL (operands[2]) >= 0
9075    /* Ensure that resulting mask is zero or sign extended operand.  */
9076    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9077        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9078            && INTVAL (operands[1]) > 32))
9079    && (GET_MODE (operands[0]) == SImode
9080        || GET_MODE (operands[0]) == DImode
9081        || GET_MODE (operands[0]) == HImode
9082        || GET_MODE (operands[0]) == QImode)"
9083   "#")
9084
9085 (define_split
9086   [(set (match_operand 0 "flags_reg_operand" "")
9087         (match_operator 1 "compare_operator"
9088           [(zero_extract
9089              (match_operand 2 "nonimmediate_operand" "")
9090              (match_operand 3 "const_int_operand" "")
9091              (match_operand 4 "const_int_operand" ""))
9092            (const_int 0)]))]
9093   "ix86_match_ccmode (insn, CCNOmode)"
9094   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9095 {
9096   rtx val = operands[2];
9097   HOST_WIDE_INT len = INTVAL (operands[3]);
9098   HOST_WIDE_INT pos = INTVAL (operands[4]);
9099   HOST_WIDE_INT mask;
9100   enum machine_mode mode, submode;
9101
9102   mode = GET_MODE (val);
9103   if (MEM_P (val))
9104     {
9105       /* ??? Combine likes to put non-volatile mem extractions in QImode
9106          no matter the size of the test.  So find a mode that works.  */
9107       if (! MEM_VOLATILE_P (val))
9108         {
9109           mode = smallest_mode_for_size (pos + len, MODE_INT);
9110           val = adjust_address (val, mode, 0);
9111         }
9112     }
9113   else if (GET_CODE (val) == SUBREG
9114            && (submode = GET_MODE (SUBREG_REG (val)),
9115                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9116            && pos + len <= GET_MODE_BITSIZE (submode))
9117     {
9118       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9119       mode = submode;
9120       val = SUBREG_REG (val);
9121     }
9122   else if (mode == HImode && pos + len <= 8)
9123     {
9124       /* Small HImode tests can be converted to QImode.  */
9125       mode = QImode;
9126       val = gen_lowpart (QImode, val);
9127     }
9128
9129   if (len == HOST_BITS_PER_WIDE_INT)
9130     mask = -1;
9131   else
9132     mask = ((HOST_WIDE_INT)1 << len) - 1;
9133   mask <<= pos;
9134
9135   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9136 })
9137
9138 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9139 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9140 ;; this is relatively important trick.
9141 ;; Do the conversion only post-reload to avoid limiting of the register class
9142 ;; to QI regs.
9143 (define_split
9144   [(set (match_operand 0 "flags_reg_operand" "")
9145         (match_operator 1 "compare_operator"
9146           [(and (match_operand 2 "register_operand" "")
9147                 (match_operand 3 "const_int_operand" ""))
9148            (const_int 0)]))]
9149    "reload_completed
9150     && QI_REG_P (operands[2])
9151     && GET_MODE (operands[2]) != QImode
9152     && ((ix86_match_ccmode (insn, CCZmode)
9153          && !(INTVAL (operands[3]) & ~(255 << 8)))
9154         || (ix86_match_ccmode (insn, CCNOmode)
9155             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9156   [(set (match_dup 0)
9157         (match_op_dup 1
9158           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9159                    (match_dup 3))
9160            (const_int 0)]))]
9161   "operands[2] = gen_lowpart (SImode, operands[2]);
9162    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9163
9164 (define_split
9165   [(set (match_operand 0 "flags_reg_operand" "")
9166         (match_operator 1 "compare_operator"
9167           [(and (match_operand 2 "nonimmediate_operand" "")
9168                 (match_operand 3 "const_int_operand" ""))
9169            (const_int 0)]))]
9170    "reload_completed
9171     && GET_MODE (operands[2]) != QImode
9172     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9173     && ((ix86_match_ccmode (insn, CCZmode)
9174          && !(INTVAL (operands[3]) & ~255))
9175         || (ix86_match_ccmode (insn, CCNOmode)
9176             && !(INTVAL (operands[3]) & ~127)))"
9177   [(set (match_dup 0)
9178         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9179                          (const_int 0)]))]
9180   "operands[2] = gen_lowpart (QImode, operands[2]);
9181    operands[3] = gen_lowpart (QImode, operands[3]);")
9182
9183
9184 ;; %%% This used to optimize known byte-wide and operations to memory,
9185 ;; and sometimes to QImode registers.  If this is considered useful,
9186 ;; it should be done with splitters.
9187
9188 (define_expand "anddi3"
9189   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9190         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9191                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9192   "TARGET_64BIT"
9193   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9194
9195 (define_insn "*anddi_1_rex64"
9196   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9197         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9198                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9199    (clobber (reg:CC FLAGS_REG))]
9200   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9201 {
9202   switch (get_attr_type (insn))
9203     {
9204     case TYPE_IMOVX:
9205       {
9206         enum machine_mode mode;
9207
9208         gcc_assert (CONST_INT_P (operands[2]));
9209         if (INTVAL (operands[2]) == 0xff)
9210           mode = QImode;
9211         else
9212           {
9213             gcc_assert (INTVAL (operands[2]) == 0xffff);
9214             mode = HImode;
9215           }
9216
9217         operands[1] = gen_lowpart (mode, operands[1]);
9218         if (mode == QImode)
9219           return "movz{bq|x}\t{%1,%0|%0, %1}";
9220         else
9221           return "movz{wq|x}\t{%1,%0|%0, %1}";
9222       }
9223
9224     default:
9225       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9226       if (get_attr_mode (insn) == MODE_SI)
9227         return "and{l}\t{%k2, %k0|%k0, %k2}";
9228       else
9229         return "and{q}\t{%2, %0|%0, %2}";
9230     }
9231 }
9232   [(set_attr "type" "alu,alu,alu,imovx")
9233    (set_attr "length_immediate" "*,*,*,0")
9234    (set_attr "mode" "SI,DI,DI,DI")])
9235
9236 (define_insn "*anddi_2"
9237   [(set (reg FLAGS_REG)
9238         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9239                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9240                  (const_int 0)))
9241    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9242         (and:DI (match_dup 1) (match_dup 2)))]
9243   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9244    && ix86_binary_operator_ok (AND, DImode, operands)"
9245   "@
9246    and{l}\t{%k2, %k0|%k0, %k2}
9247    and{q}\t{%2, %0|%0, %2}
9248    and{q}\t{%2, %0|%0, %2}"
9249   [(set_attr "type" "alu")
9250    (set_attr "mode" "SI,DI,DI")])
9251
9252 (define_expand "andsi3"
9253   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9254         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9255                 (match_operand:SI 2 "general_operand" "")))]
9256   ""
9257   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9258
9259 (define_insn "*andsi_1"
9260   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9261         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9262                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9263    (clobber (reg:CC FLAGS_REG))]
9264   "ix86_binary_operator_ok (AND, SImode, operands)"
9265 {
9266   switch (get_attr_type (insn))
9267     {
9268     case TYPE_IMOVX:
9269       {
9270         enum machine_mode mode;
9271
9272         gcc_assert (CONST_INT_P (operands[2]));
9273         if (INTVAL (operands[2]) == 0xff)
9274           mode = QImode;
9275         else
9276           {
9277             gcc_assert (INTVAL (operands[2]) == 0xffff);
9278             mode = HImode;
9279           }
9280
9281         operands[1] = gen_lowpart (mode, operands[1]);
9282         if (mode == QImode)
9283           return "movz{bl|x}\t{%1,%0|%0, %1}";
9284         else
9285           return "movz{wl|x}\t{%1,%0|%0, %1}";
9286       }
9287
9288     default:
9289       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9290       return "and{l}\t{%2, %0|%0, %2}";
9291     }
9292 }
9293   [(set_attr "type" "alu,alu,imovx")
9294    (set_attr "length_immediate" "*,*,0")
9295    (set_attr "mode" "SI")])
9296
9297 (define_split
9298   [(set (match_operand 0 "register_operand" "")
9299         (and (match_dup 0)
9300              (const_int -65536)))
9301    (clobber (reg:CC FLAGS_REG))]
9302   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9303   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9304   "operands[1] = gen_lowpart (HImode, operands[0]);")
9305
9306 (define_split
9307   [(set (match_operand 0 "ext_register_operand" "")
9308         (and (match_dup 0)
9309              (const_int -256)))
9310    (clobber (reg:CC FLAGS_REG))]
9311   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9312   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9313   "operands[1] = gen_lowpart (QImode, operands[0]);")
9314
9315 (define_split
9316   [(set (match_operand 0 "ext_register_operand" "")
9317         (and (match_dup 0)
9318              (const_int -65281)))
9319    (clobber (reg:CC FLAGS_REG))]
9320   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9321   [(parallel [(set (zero_extract:SI (match_dup 0)
9322                                     (const_int 8)
9323                                     (const_int 8))
9324                    (xor:SI
9325                      (zero_extract:SI (match_dup 0)
9326                                       (const_int 8)
9327                                       (const_int 8))
9328                      (zero_extract:SI (match_dup 0)
9329                                       (const_int 8)
9330                                       (const_int 8))))
9331               (clobber (reg:CC FLAGS_REG))])]
9332   "operands[0] = gen_lowpart (SImode, operands[0]);")
9333
9334 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9335 (define_insn "*andsi_1_zext"
9336   [(set (match_operand:DI 0 "register_operand" "=r")
9337         (zero_extend:DI
9338           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9339                   (match_operand:SI 2 "general_operand" "g"))))
9340    (clobber (reg:CC FLAGS_REG))]
9341   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9342   "and{l}\t{%2, %k0|%k0, %2}"
9343   [(set_attr "type" "alu")
9344    (set_attr "mode" "SI")])
9345
9346 (define_insn "*andsi_2"
9347   [(set (reg FLAGS_REG)
9348         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9349                          (match_operand:SI 2 "general_operand" "g,ri"))
9350                  (const_int 0)))
9351    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9352         (and:SI (match_dup 1) (match_dup 2)))]
9353   "ix86_match_ccmode (insn, CCNOmode)
9354    && ix86_binary_operator_ok (AND, SImode, operands)"
9355   "and{l}\t{%2, %0|%0, %2}"
9356   [(set_attr "type" "alu")
9357    (set_attr "mode" "SI")])
9358
9359 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9360 (define_insn "*andsi_2_zext"
9361   [(set (reg FLAGS_REG)
9362         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9363                          (match_operand:SI 2 "general_operand" "g"))
9364                  (const_int 0)))
9365    (set (match_operand:DI 0 "register_operand" "=r")
9366         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9367   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9368    && ix86_binary_operator_ok (AND, SImode, operands)"
9369   "and{l}\t{%2, %k0|%k0, %2}"
9370   [(set_attr "type" "alu")
9371    (set_attr "mode" "SI")])
9372
9373 (define_expand "andhi3"
9374   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9375         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9376                 (match_operand:HI 2 "general_operand" "")))]
9377   "TARGET_HIMODE_MATH"
9378   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9379
9380 (define_insn "*andhi_1"
9381   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9382         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9383                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9384    (clobber (reg:CC FLAGS_REG))]
9385   "ix86_binary_operator_ok (AND, HImode, operands)"
9386 {
9387   switch (get_attr_type (insn))
9388     {
9389     case TYPE_IMOVX:
9390       gcc_assert (CONST_INT_P (operands[2]));
9391       gcc_assert (INTVAL (operands[2]) == 0xff);
9392       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9393
9394     default:
9395       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9396
9397       return "and{w}\t{%2, %0|%0, %2}";
9398     }
9399 }
9400   [(set_attr "type" "alu,alu,imovx")
9401    (set_attr "length_immediate" "*,*,0")
9402    (set_attr "mode" "HI,HI,SI")])
9403
9404 (define_insn "*andhi_2"
9405   [(set (reg FLAGS_REG)
9406         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9407                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9408                  (const_int 0)))
9409    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9410         (and:HI (match_dup 1) (match_dup 2)))]
9411   "ix86_match_ccmode (insn, CCNOmode)
9412    && ix86_binary_operator_ok (AND, HImode, operands)"
9413   "and{w}\t{%2, %0|%0, %2}"
9414   [(set_attr "type" "alu")
9415    (set_attr "mode" "HI")])
9416
9417 (define_expand "andqi3"
9418   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9419         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9420                 (match_operand:QI 2 "general_operand" "")))]
9421   "TARGET_QIMODE_MATH"
9422   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9423
9424 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9425 (define_insn "*andqi_1"
9426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9427         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9428                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9429    (clobber (reg:CC FLAGS_REG))]
9430   "ix86_binary_operator_ok (AND, QImode, operands)"
9431   "@
9432    and{b}\t{%2, %0|%0, %2}
9433    and{b}\t{%2, %0|%0, %2}
9434    and{l}\t{%k2, %k0|%k0, %k2}"
9435   [(set_attr "type" "alu")
9436    (set_attr "mode" "QI,QI,SI")])
9437
9438 (define_insn "*andqi_1_slp"
9439   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9440         (and:QI (match_dup 0)
9441                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9442    (clobber (reg:CC FLAGS_REG))]
9443   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9444    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9445   "and{b}\t{%1, %0|%0, %1}"
9446   [(set_attr "type" "alu1")
9447    (set_attr "mode" "QI")])
9448
9449 (define_insn "*andqi_2_maybe_si"
9450   [(set (reg FLAGS_REG)
9451         (compare (and:QI
9452                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9453                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9454                  (const_int 0)))
9455    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9456         (and:QI (match_dup 1) (match_dup 2)))]
9457   "ix86_binary_operator_ok (AND, QImode, operands)
9458    && ix86_match_ccmode (insn,
9459                          CONST_INT_P (operands[2])
9460                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9461 {
9462   if (which_alternative == 2)
9463     {
9464       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9465         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9466       return "and{l}\t{%2, %k0|%k0, %2}";
9467     }
9468   return "and{b}\t{%2, %0|%0, %2}";
9469 }
9470   [(set_attr "type" "alu")
9471    (set_attr "mode" "QI,QI,SI")])
9472
9473 (define_insn "*andqi_2"
9474   [(set (reg FLAGS_REG)
9475         (compare (and:QI
9476                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9477                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9478                  (const_int 0)))
9479    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9480         (and:QI (match_dup 1) (match_dup 2)))]
9481   "ix86_match_ccmode (insn, CCNOmode)
9482    && ix86_binary_operator_ok (AND, QImode, operands)"
9483   "and{b}\t{%2, %0|%0, %2}"
9484   [(set_attr "type" "alu")
9485    (set_attr "mode" "QI")])
9486
9487 (define_insn "*andqi_2_slp"
9488   [(set (reg FLAGS_REG)
9489         (compare (and:QI
9490                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9491                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9492                  (const_int 0)))
9493    (set (strict_low_part (match_dup 0))
9494         (and:QI (match_dup 0) (match_dup 1)))]
9495   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9496    && ix86_match_ccmode (insn, CCNOmode)
9497    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9498   "and{b}\t{%1, %0|%0, %1}"
9499   [(set_attr "type" "alu1")
9500    (set_attr "mode" "QI")])
9501
9502 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9503 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9504 ;; for a QImode operand, which of course failed.
9505
9506 (define_insn "andqi_ext_0"
9507   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9508                          (const_int 8)
9509                          (const_int 8))
9510         (and:SI
9511           (zero_extract:SI
9512             (match_operand 1 "ext_register_operand" "0")
9513             (const_int 8)
9514             (const_int 8))
9515           (match_operand 2 "const_int_operand" "n")))
9516    (clobber (reg:CC FLAGS_REG))]
9517   ""
9518   "and{b}\t{%2, %h0|%h0, %2}"
9519   [(set_attr "type" "alu")
9520    (set_attr "length_immediate" "1")
9521    (set_attr "mode" "QI")])
9522
9523 ;; Generated by peephole translating test to and.  This shows up
9524 ;; often in fp comparisons.
9525
9526 (define_insn "*andqi_ext_0_cc"
9527   [(set (reg FLAGS_REG)
9528         (compare
9529           (and:SI
9530             (zero_extract:SI
9531               (match_operand 1 "ext_register_operand" "0")
9532               (const_int 8)
9533               (const_int 8))
9534             (match_operand 2 "const_int_operand" "n"))
9535           (const_int 0)))
9536    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9537                          (const_int 8)
9538                          (const_int 8))
9539         (and:SI
9540           (zero_extract:SI
9541             (match_dup 1)
9542             (const_int 8)
9543             (const_int 8))
9544           (match_dup 2)))]
9545   "ix86_match_ccmode (insn, CCNOmode)"
9546   "and{b}\t{%2, %h0|%h0, %2}"
9547   [(set_attr "type" "alu")
9548    (set_attr "length_immediate" "1")
9549    (set_attr "mode" "QI")])
9550
9551 (define_insn "*andqi_ext_1"
9552   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9553                          (const_int 8)
9554                          (const_int 8))
9555         (and:SI
9556           (zero_extract:SI
9557             (match_operand 1 "ext_register_operand" "0")
9558             (const_int 8)
9559             (const_int 8))
9560           (zero_extend:SI
9561             (match_operand:QI 2 "general_operand" "Qm"))))
9562    (clobber (reg:CC FLAGS_REG))]
9563   "!TARGET_64BIT"
9564   "and{b}\t{%2, %h0|%h0, %2}"
9565   [(set_attr "type" "alu")
9566    (set_attr "length_immediate" "0")
9567    (set_attr "mode" "QI")])
9568
9569 (define_insn "*andqi_ext_1_rex64"
9570   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9571                          (const_int 8)
9572                          (const_int 8))
9573         (and:SI
9574           (zero_extract:SI
9575             (match_operand 1 "ext_register_operand" "0")
9576             (const_int 8)
9577             (const_int 8))
9578           (zero_extend:SI
9579             (match_operand 2 "ext_register_operand" "Q"))))
9580    (clobber (reg:CC FLAGS_REG))]
9581   "TARGET_64BIT"
9582   "and{b}\t{%2, %h0|%h0, %2}"
9583   [(set_attr "type" "alu")
9584    (set_attr "length_immediate" "0")
9585    (set_attr "mode" "QI")])
9586
9587 (define_insn "*andqi_ext_2"
9588   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9589                          (const_int 8)
9590                          (const_int 8))
9591         (and:SI
9592           (zero_extract:SI
9593             (match_operand 1 "ext_register_operand" "%0")
9594             (const_int 8)
9595             (const_int 8))
9596           (zero_extract:SI
9597             (match_operand 2 "ext_register_operand" "Q")
9598             (const_int 8)
9599             (const_int 8))))
9600    (clobber (reg:CC FLAGS_REG))]
9601   ""
9602   "and{b}\t{%h2, %h0|%h0, %h2}"
9603   [(set_attr "type" "alu")
9604    (set_attr "length_immediate" "0")
9605    (set_attr "mode" "QI")])
9606
9607 ;; Convert wide AND instructions with immediate operand to shorter QImode
9608 ;; equivalents when possible.
9609 ;; Don't do the splitting with memory operands, since it introduces risk
9610 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9611 ;; for size, but that can (should?) be handled by generic code instead.
9612 (define_split
9613   [(set (match_operand 0 "register_operand" "")
9614         (and (match_operand 1 "register_operand" "")
9615              (match_operand 2 "const_int_operand" "")))
9616    (clobber (reg:CC FLAGS_REG))]
9617    "reload_completed
9618     && QI_REG_P (operands[0])
9619     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9620     && !(~INTVAL (operands[2]) & ~(255 << 8))
9621     && GET_MODE (operands[0]) != QImode"
9622   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9623                    (and:SI (zero_extract:SI (match_dup 1)
9624                                             (const_int 8) (const_int 8))
9625                            (match_dup 2)))
9626               (clobber (reg:CC FLAGS_REG))])]
9627   "operands[0] = gen_lowpart (SImode, operands[0]);
9628    operands[1] = gen_lowpart (SImode, operands[1]);
9629    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9630
9631 ;; Since AND can be encoded with sign extended immediate, this is only
9632 ;; profitable when 7th bit is not set.
9633 (define_split
9634   [(set (match_operand 0 "register_operand" "")
9635         (and (match_operand 1 "general_operand" "")
9636              (match_operand 2 "const_int_operand" "")))
9637    (clobber (reg:CC FLAGS_REG))]
9638    "reload_completed
9639     && ANY_QI_REG_P (operands[0])
9640     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9641     && !(~INTVAL (operands[2]) & ~255)
9642     && !(INTVAL (operands[2]) & 128)
9643     && GET_MODE (operands[0]) != QImode"
9644   [(parallel [(set (strict_low_part (match_dup 0))
9645                    (and:QI (match_dup 1)
9646                            (match_dup 2)))
9647               (clobber (reg:CC FLAGS_REG))])]
9648   "operands[0] = gen_lowpart (QImode, operands[0]);
9649    operands[1] = gen_lowpart (QImode, operands[1]);
9650    operands[2] = gen_lowpart (QImode, operands[2]);")
9651 \f
9652 ;; Logical inclusive OR instructions
9653
9654 ;; %%% This used to optimize known byte-wide and operations to memory.
9655 ;; If this is considered useful, it should be done with splitters.
9656
9657 (define_expand "iordi3"
9658   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9659         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9660                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9661   "TARGET_64BIT"
9662   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9663
9664 (define_insn "*iordi_1_rex64"
9665   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9666         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9667                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9668    (clobber (reg:CC FLAGS_REG))]
9669   "TARGET_64BIT
9670    && ix86_binary_operator_ok (IOR, DImode, operands)"
9671   "or{q}\t{%2, %0|%0, %2}"
9672   [(set_attr "type" "alu")
9673    (set_attr "mode" "DI")])
9674
9675 (define_insn "*iordi_2_rex64"
9676   [(set (reg FLAGS_REG)
9677         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9678                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9679                  (const_int 0)))
9680    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9681         (ior:DI (match_dup 1) (match_dup 2)))]
9682   "TARGET_64BIT
9683    && ix86_match_ccmode (insn, CCNOmode)
9684    && ix86_binary_operator_ok (IOR, DImode, operands)"
9685   "or{q}\t{%2, %0|%0, %2}"
9686   [(set_attr "type" "alu")
9687    (set_attr "mode" "DI")])
9688
9689 (define_insn "*iordi_3_rex64"
9690   [(set (reg FLAGS_REG)
9691         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9692                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9693                  (const_int 0)))
9694    (clobber (match_scratch:DI 0 "=r"))]
9695   "TARGET_64BIT
9696    && ix86_match_ccmode (insn, CCNOmode)
9697    && ix86_binary_operator_ok (IOR, DImode, operands)"
9698   "or{q}\t{%2, %0|%0, %2}"
9699   [(set_attr "type" "alu")
9700    (set_attr "mode" "DI")])
9701
9702
9703 (define_expand "iorsi3"
9704   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9705         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9706                 (match_operand:SI 2 "general_operand" "")))]
9707   ""
9708   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9709
9710 (define_insn "*iorsi_1"
9711   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9712         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9713                 (match_operand:SI 2 "general_operand" "ri,g")))
9714    (clobber (reg:CC FLAGS_REG))]
9715   "ix86_binary_operator_ok (IOR, SImode, operands)"
9716   "or{l}\t{%2, %0|%0, %2}"
9717   [(set_attr "type" "alu")
9718    (set_attr "mode" "SI")])
9719
9720 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9721 (define_insn "*iorsi_1_zext"
9722   [(set (match_operand:DI 0 "register_operand" "=r")
9723         (zero_extend:DI
9724           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9725                   (match_operand:SI 2 "general_operand" "g"))))
9726    (clobber (reg:CC FLAGS_REG))]
9727   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9728   "or{l}\t{%2, %k0|%k0, %2}"
9729   [(set_attr "type" "alu")
9730    (set_attr "mode" "SI")])
9731
9732 (define_insn "*iorsi_1_zext_imm"
9733   [(set (match_operand:DI 0 "register_operand" "=r")
9734         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9735                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9736    (clobber (reg:CC FLAGS_REG))]
9737   "TARGET_64BIT"
9738   "or{l}\t{%2, %k0|%k0, %2}"
9739   [(set_attr "type" "alu")
9740    (set_attr "mode" "SI")])
9741
9742 (define_insn "*iorsi_2"
9743   [(set (reg FLAGS_REG)
9744         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9745                          (match_operand:SI 2 "general_operand" "g,ri"))
9746                  (const_int 0)))
9747    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9748         (ior:SI (match_dup 1) (match_dup 2)))]
9749   "ix86_match_ccmode (insn, CCNOmode)
9750    && ix86_binary_operator_ok (IOR, SImode, operands)"
9751   "or{l}\t{%2, %0|%0, %2}"
9752   [(set_attr "type" "alu")
9753    (set_attr "mode" "SI")])
9754
9755 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9756 ;; ??? Special case for immediate operand is missing - it is tricky.
9757 (define_insn "*iorsi_2_zext"
9758   [(set (reg FLAGS_REG)
9759         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9760                          (match_operand:SI 2 "general_operand" "g"))
9761                  (const_int 0)))
9762    (set (match_operand:DI 0 "register_operand" "=r")
9763         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9764   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9765    && ix86_binary_operator_ok (IOR, SImode, operands)"
9766   "or{l}\t{%2, %k0|%k0, %2}"
9767   [(set_attr "type" "alu")
9768    (set_attr "mode" "SI")])
9769
9770 (define_insn "*iorsi_2_zext_imm"
9771   [(set (reg FLAGS_REG)
9772         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9773                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9774                  (const_int 0)))
9775    (set (match_operand:DI 0 "register_operand" "=r")
9776         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9777   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9778    && ix86_binary_operator_ok (IOR, SImode, operands)"
9779   "or{l}\t{%2, %k0|%k0, %2}"
9780   [(set_attr "type" "alu")
9781    (set_attr "mode" "SI")])
9782
9783 (define_insn "*iorsi_3"
9784   [(set (reg FLAGS_REG)
9785         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9786                          (match_operand:SI 2 "general_operand" "g"))
9787                  (const_int 0)))
9788    (clobber (match_scratch:SI 0 "=r"))]
9789   "ix86_match_ccmode (insn, CCNOmode)
9790    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9791   "or{l}\t{%2, %0|%0, %2}"
9792   [(set_attr "type" "alu")
9793    (set_attr "mode" "SI")])
9794
9795 (define_expand "iorhi3"
9796   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9797         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9798                 (match_operand:HI 2 "general_operand" "")))]
9799   "TARGET_HIMODE_MATH"
9800   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9801
9802 (define_insn "*iorhi_1"
9803   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9804         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9805                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9806    (clobber (reg:CC FLAGS_REG))]
9807   "ix86_binary_operator_ok (IOR, HImode, operands)"
9808   "or{w}\t{%2, %0|%0, %2}"
9809   [(set_attr "type" "alu")
9810    (set_attr "mode" "HI")])
9811
9812 (define_insn "*iorhi_2"
9813   [(set (reg FLAGS_REG)
9814         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9815                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9816                  (const_int 0)))
9817    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9818         (ior:HI (match_dup 1) (match_dup 2)))]
9819   "ix86_match_ccmode (insn, CCNOmode)
9820    && ix86_binary_operator_ok (IOR, HImode, operands)"
9821   "or{w}\t{%2, %0|%0, %2}"
9822   [(set_attr "type" "alu")
9823    (set_attr "mode" "HI")])
9824
9825 (define_insn "*iorhi_3"
9826   [(set (reg FLAGS_REG)
9827         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9828                          (match_operand:HI 2 "general_operand" "rmn"))
9829                  (const_int 0)))
9830    (clobber (match_scratch:HI 0 "=r"))]
9831   "ix86_match_ccmode (insn, CCNOmode)
9832    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9833   "or{w}\t{%2, %0|%0, %2}"
9834   [(set_attr "type" "alu")
9835    (set_attr "mode" "HI")])
9836
9837 (define_expand "iorqi3"
9838   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9839         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9840                 (match_operand:QI 2 "general_operand" "")))]
9841   "TARGET_QIMODE_MATH"
9842   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9843
9844 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9845 (define_insn "*iorqi_1"
9846   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9847         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9848                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9849    (clobber (reg:CC FLAGS_REG))]
9850   "ix86_binary_operator_ok (IOR, QImode, operands)"
9851   "@
9852    or{b}\t{%2, %0|%0, %2}
9853    or{b}\t{%2, %0|%0, %2}
9854    or{l}\t{%k2, %k0|%k0, %k2}"
9855   [(set_attr "type" "alu")
9856    (set_attr "mode" "QI,QI,SI")])
9857
9858 (define_insn "*iorqi_1_slp"
9859   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9860         (ior:QI (match_dup 0)
9861                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9862    (clobber (reg:CC FLAGS_REG))]
9863   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9864    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9865   "or{b}\t{%1, %0|%0, %1}"
9866   [(set_attr "type" "alu1")
9867    (set_attr "mode" "QI")])
9868
9869 (define_insn "*iorqi_2"
9870   [(set (reg FLAGS_REG)
9871         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9872                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9873                  (const_int 0)))
9874    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9875         (ior:QI (match_dup 1) (match_dup 2)))]
9876   "ix86_match_ccmode (insn, CCNOmode)
9877    && ix86_binary_operator_ok (IOR, QImode, operands)"
9878   "or{b}\t{%2, %0|%0, %2}"
9879   [(set_attr "type" "alu")
9880    (set_attr "mode" "QI")])
9881
9882 (define_insn "*iorqi_2_slp"
9883   [(set (reg FLAGS_REG)
9884         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9885                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9886                  (const_int 0)))
9887    (set (strict_low_part (match_dup 0))
9888         (ior:QI (match_dup 0) (match_dup 1)))]
9889   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9890    && ix86_match_ccmode (insn, CCNOmode)
9891    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9892   "or{b}\t{%1, %0|%0, %1}"
9893   [(set_attr "type" "alu1")
9894    (set_attr "mode" "QI")])
9895
9896 (define_insn "*iorqi_3"
9897   [(set (reg FLAGS_REG)
9898         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9899                          (match_operand:QI 2 "general_operand" "qmn"))
9900                  (const_int 0)))
9901    (clobber (match_scratch:QI 0 "=q"))]
9902   "ix86_match_ccmode (insn, CCNOmode)
9903    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9904   "or{b}\t{%2, %0|%0, %2}"
9905   [(set_attr "type" "alu")
9906    (set_attr "mode" "QI")])
9907
9908 (define_insn "*iorqi_ext_0"
9909   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9910                          (const_int 8)
9911                          (const_int 8))
9912         (ior:SI
9913           (zero_extract:SI
9914             (match_operand 1 "ext_register_operand" "0")
9915             (const_int 8)
9916             (const_int 8))
9917           (match_operand 2 "const_int_operand" "n")))
9918    (clobber (reg:CC FLAGS_REG))]
9919   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9920   "or{b}\t{%2, %h0|%h0, %2}"
9921   [(set_attr "type" "alu")
9922    (set_attr "length_immediate" "1")
9923    (set_attr "mode" "QI")])
9924
9925 (define_insn "*iorqi_ext_1"
9926   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9927                          (const_int 8)
9928                          (const_int 8))
9929         (ior:SI
9930           (zero_extract:SI
9931             (match_operand 1 "ext_register_operand" "0")
9932             (const_int 8)
9933             (const_int 8))
9934           (zero_extend:SI
9935             (match_operand:QI 2 "general_operand" "Qm"))))
9936    (clobber (reg:CC FLAGS_REG))]
9937   "!TARGET_64BIT
9938    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9939   "or{b}\t{%2, %h0|%h0, %2}"
9940   [(set_attr "type" "alu")
9941    (set_attr "length_immediate" "0")
9942    (set_attr "mode" "QI")])
9943
9944 (define_insn "*iorqi_ext_1_rex64"
9945   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9946                          (const_int 8)
9947                          (const_int 8))
9948         (ior:SI
9949           (zero_extract:SI
9950             (match_operand 1 "ext_register_operand" "0")
9951             (const_int 8)
9952             (const_int 8))
9953           (zero_extend:SI
9954             (match_operand 2 "ext_register_operand" "Q"))))
9955    (clobber (reg:CC FLAGS_REG))]
9956   "TARGET_64BIT
9957    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9958   "or{b}\t{%2, %h0|%h0, %2}"
9959   [(set_attr "type" "alu")
9960    (set_attr "length_immediate" "0")
9961    (set_attr "mode" "QI")])
9962
9963 (define_insn "*iorqi_ext_2"
9964   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9965                          (const_int 8)
9966                          (const_int 8))
9967         (ior:SI
9968           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9969                            (const_int 8)
9970                            (const_int 8))
9971           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9972                            (const_int 8)
9973                            (const_int 8))))
9974    (clobber (reg:CC FLAGS_REG))]
9975   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9976   "ior{b}\t{%h2, %h0|%h0, %h2}"
9977   [(set_attr "type" "alu")
9978    (set_attr "length_immediate" "0")
9979    (set_attr "mode" "QI")])
9980
9981 (define_split
9982   [(set (match_operand 0 "register_operand" "")
9983         (ior (match_operand 1 "register_operand" "")
9984              (match_operand 2 "const_int_operand" "")))
9985    (clobber (reg:CC FLAGS_REG))]
9986    "reload_completed
9987     && QI_REG_P (operands[0])
9988     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9989     && !(INTVAL (operands[2]) & ~(255 << 8))
9990     && GET_MODE (operands[0]) != QImode"
9991   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9992                    (ior:SI (zero_extract:SI (match_dup 1)
9993                                             (const_int 8) (const_int 8))
9994                            (match_dup 2)))
9995               (clobber (reg:CC FLAGS_REG))])]
9996   "operands[0] = gen_lowpart (SImode, operands[0]);
9997    operands[1] = gen_lowpart (SImode, operands[1]);
9998    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9999
10000 ;; Since OR can be encoded with sign extended immediate, this is only
10001 ;; profitable when 7th bit is set.
10002 (define_split
10003   [(set (match_operand 0 "register_operand" "")
10004         (ior (match_operand 1 "general_operand" "")
10005              (match_operand 2 "const_int_operand" "")))
10006    (clobber (reg:CC FLAGS_REG))]
10007    "reload_completed
10008     && ANY_QI_REG_P (operands[0])
10009     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10010     && !(INTVAL (operands[2]) & ~255)
10011     && (INTVAL (operands[2]) & 128)
10012     && GET_MODE (operands[0]) != QImode"
10013   [(parallel [(set (strict_low_part (match_dup 0))
10014                    (ior:QI (match_dup 1)
10015                            (match_dup 2)))
10016               (clobber (reg:CC FLAGS_REG))])]
10017   "operands[0] = gen_lowpart (QImode, operands[0]);
10018    operands[1] = gen_lowpart (QImode, operands[1]);
10019    operands[2] = gen_lowpart (QImode, operands[2]);")
10020 \f
10021 ;; Logical XOR instructions
10022
10023 ;; %%% This used to optimize known byte-wide and operations to memory.
10024 ;; If this is considered useful, it should be done with splitters.
10025
10026 (define_expand "xordi3"
10027   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10028         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
10029                 (match_operand:DI 2 "x86_64_general_operand" "")))]
10030   "TARGET_64BIT"
10031   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
10032
10033 (define_insn "*xordi_1_rex64"
10034   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10035         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10036                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
10037    (clobber (reg:CC FLAGS_REG))]
10038   "TARGET_64BIT
10039    && ix86_binary_operator_ok (XOR, DImode, operands)"
10040   "xor{q}\t{%2, %0|%0, %2}"
10041   [(set_attr "type" "alu")
10042    (set_attr "mode" "DI")])
10043
10044 (define_insn "*xordi_2_rex64"
10045   [(set (reg FLAGS_REG)
10046         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10047                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10048                  (const_int 0)))
10049    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10050         (xor:DI (match_dup 1) (match_dup 2)))]
10051   "TARGET_64BIT
10052    && ix86_match_ccmode (insn, CCNOmode)
10053    && ix86_binary_operator_ok (XOR, DImode, operands)"
10054   "xor{q}\t{%2, %0|%0, %2}"
10055   [(set_attr "type" "alu")
10056    (set_attr "mode" "DI")])
10057
10058 (define_insn "*xordi_3_rex64"
10059   [(set (reg FLAGS_REG)
10060         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10061                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
10062                  (const_int 0)))
10063    (clobber (match_scratch:DI 0 "=r"))]
10064   "TARGET_64BIT
10065    && ix86_match_ccmode (insn, CCNOmode)
10066    && ix86_binary_operator_ok (XOR, DImode, operands)"
10067   "xor{q}\t{%2, %0|%0, %2}"
10068   [(set_attr "type" "alu")
10069    (set_attr "mode" "DI")])
10070
10071 (define_expand "xorsi3"
10072   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10073         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10074                 (match_operand:SI 2 "general_operand" "")))]
10075   ""
10076   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10077
10078 (define_insn "*xorsi_1"
10079   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10080         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10081                 (match_operand:SI 2 "general_operand" "ri,rm")))
10082    (clobber (reg:CC FLAGS_REG))]
10083   "ix86_binary_operator_ok (XOR, SImode, operands)"
10084   "xor{l}\t{%2, %0|%0, %2}"
10085   [(set_attr "type" "alu")
10086    (set_attr "mode" "SI")])
10087
10088 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10089 ;; Add speccase for immediates
10090 (define_insn "*xorsi_1_zext"
10091   [(set (match_operand:DI 0 "register_operand" "=r")
10092         (zero_extend:DI
10093           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10094                   (match_operand:SI 2 "general_operand" "g"))))
10095    (clobber (reg:CC FLAGS_REG))]
10096   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10097   "xor{l}\t{%2, %k0|%k0, %2}"
10098   [(set_attr "type" "alu")
10099    (set_attr "mode" "SI")])
10100
10101 (define_insn "*xorsi_1_zext_imm"
10102   [(set (match_operand:DI 0 "register_operand" "=r")
10103         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10104                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10105    (clobber (reg:CC FLAGS_REG))]
10106   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10107   "xor{l}\t{%2, %k0|%k0, %2}"
10108   [(set_attr "type" "alu")
10109    (set_attr "mode" "SI")])
10110
10111 (define_insn "*xorsi_2"
10112   [(set (reg FLAGS_REG)
10113         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10114                          (match_operand:SI 2 "general_operand" "g,ri"))
10115                  (const_int 0)))
10116    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10117         (xor:SI (match_dup 1) (match_dup 2)))]
10118   "ix86_match_ccmode (insn, CCNOmode)
10119    && ix86_binary_operator_ok (XOR, SImode, operands)"
10120   "xor{l}\t{%2, %0|%0, %2}"
10121   [(set_attr "type" "alu")
10122    (set_attr "mode" "SI")])
10123
10124 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10125 ;; ??? Special case for immediate operand is missing - it is tricky.
10126 (define_insn "*xorsi_2_zext"
10127   [(set (reg FLAGS_REG)
10128         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10129                          (match_operand:SI 2 "general_operand" "g"))
10130                  (const_int 0)))
10131    (set (match_operand:DI 0 "register_operand" "=r")
10132         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10133   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10134    && ix86_binary_operator_ok (XOR, SImode, operands)"
10135   "xor{l}\t{%2, %k0|%k0, %2}"
10136   [(set_attr "type" "alu")
10137    (set_attr "mode" "SI")])
10138
10139 (define_insn "*xorsi_2_zext_imm"
10140   [(set (reg FLAGS_REG)
10141         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10142                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10143                  (const_int 0)))
10144    (set (match_operand:DI 0 "register_operand" "=r")
10145         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10146   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10147    && ix86_binary_operator_ok (XOR, SImode, operands)"
10148   "xor{l}\t{%2, %k0|%k0, %2}"
10149   [(set_attr "type" "alu")
10150    (set_attr "mode" "SI")])
10151
10152 (define_insn "*xorsi_3"
10153   [(set (reg FLAGS_REG)
10154         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10155                          (match_operand:SI 2 "general_operand" "g"))
10156                  (const_int 0)))
10157    (clobber (match_scratch:SI 0 "=r"))]
10158   "ix86_match_ccmode (insn, CCNOmode)
10159    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10160   "xor{l}\t{%2, %0|%0, %2}"
10161   [(set_attr "type" "alu")
10162    (set_attr "mode" "SI")])
10163
10164 (define_expand "xorhi3"
10165   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10166         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10167                 (match_operand:HI 2 "general_operand" "")))]
10168   "TARGET_HIMODE_MATH"
10169   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10170
10171 (define_insn "*xorhi_1"
10172   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10173         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10174                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10175    (clobber (reg:CC FLAGS_REG))]
10176   "ix86_binary_operator_ok (XOR, HImode, operands)"
10177   "xor{w}\t{%2, %0|%0, %2}"
10178   [(set_attr "type" "alu")
10179    (set_attr "mode" "HI")])
10180
10181 (define_insn "*xorhi_2"
10182   [(set (reg FLAGS_REG)
10183         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10184                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10185                  (const_int 0)))
10186    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10187         (xor:HI (match_dup 1) (match_dup 2)))]
10188   "ix86_match_ccmode (insn, CCNOmode)
10189    && ix86_binary_operator_ok (XOR, HImode, operands)"
10190   "xor{w}\t{%2, %0|%0, %2}"
10191   [(set_attr "type" "alu")
10192    (set_attr "mode" "HI")])
10193
10194 (define_insn "*xorhi_3"
10195   [(set (reg FLAGS_REG)
10196         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10197                          (match_operand:HI 2 "general_operand" "rmn"))
10198                  (const_int 0)))
10199    (clobber (match_scratch:HI 0 "=r"))]
10200   "ix86_match_ccmode (insn, CCNOmode)
10201    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10202   "xor{w}\t{%2, %0|%0, %2}"
10203   [(set_attr "type" "alu")
10204    (set_attr "mode" "HI")])
10205
10206 (define_expand "xorqi3"
10207   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10208         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10209                 (match_operand:QI 2 "general_operand" "")))]
10210   "TARGET_QIMODE_MATH"
10211   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10212
10213 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10214 (define_insn "*xorqi_1"
10215   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10216         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10217                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10218    (clobber (reg:CC FLAGS_REG))]
10219   "ix86_binary_operator_ok (XOR, QImode, operands)"
10220   "@
10221    xor{b}\t{%2, %0|%0, %2}
10222    xor{b}\t{%2, %0|%0, %2}
10223    xor{l}\t{%k2, %k0|%k0, %k2}"
10224   [(set_attr "type" "alu")
10225    (set_attr "mode" "QI,QI,SI")])
10226
10227 (define_insn "*xorqi_1_slp"
10228   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10229         (xor:QI (match_dup 0)
10230                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10231    (clobber (reg:CC FLAGS_REG))]
10232   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10233    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10234   "xor{b}\t{%1, %0|%0, %1}"
10235   [(set_attr "type" "alu1")
10236    (set_attr "mode" "QI")])
10237
10238 (define_insn "*xorqi_ext_0"
10239   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10240                          (const_int 8)
10241                          (const_int 8))
10242         (xor:SI
10243           (zero_extract:SI
10244             (match_operand 1 "ext_register_operand" "0")
10245             (const_int 8)
10246             (const_int 8))
10247           (match_operand 2 "const_int_operand" "n")))
10248    (clobber (reg:CC FLAGS_REG))]
10249   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10250   "xor{b}\t{%2, %h0|%h0, %2}"
10251   [(set_attr "type" "alu")
10252    (set_attr "length_immediate" "1")
10253    (set_attr "mode" "QI")])
10254
10255 (define_insn "*xorqi_ext_1"
10256   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10257                          (const_int 8)
10258                          (const_int 8))
10259         (xor:SI
10260           (zero_extract:SI
10261             (match_operand 1 "ext_register_operand" "0")
10262             (const_int 8)
10263             (const_int 8))
10264           (zero_extend:SI
10265             (match_operand:QI 2 "general_operand" "Qm"))))
10266    (clobber (reg:CC FLAGS_REG))]
10267   "!TARGET_64BIT
10268    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10269   "xor{b}\t{%2, %h0|%h0, %2}"
10270   [(set_attr "type" "alu")
10271    (set_attr "length_immediate" "0")
10272    (set_attr "mode" "QI")])
10273
10274 (define_insn "*xorqi_ext_1_rex64"
10275   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10276                          (const_int 8)
10277                          (const_int 8))
10278         (xor:SI
10279           (zero_extract:SI
10280             (match_operand 1 "ext_register_operand" "0")
10281             (const_int 8)
10282             (const_int 8))
10283           (zero_extend:SI
10284             (match_operand 2 "ext_register_operand" "Q"))))
10285    (clobber (reg:CC FLAGS_REG))]
10286   "TARGET_64BIT
10287    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10288   "xor{b}\t{%2, %h0|%h0, %2}"
10289   [(set_attr "type" "alu")
10290    (set_attr "length_immediate" "0")
10291    (set_attr "mode" "QI")])
10292
10293 (define_insn "*xorqi_ext_2"
10294   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10295                          (const_int 8)
10296                          (const_int 8))
10297         (xor:SI
10298           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10299                            (const_int 8)
10300                            (const_int 8))
10301           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10302                            (const_int 8)
10303                            (const_int 8))))
10304    (clobber (reg:CC FLAGS_REG))]
10305   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10306   "xor{b}\t{%h2, %h0|%h0, %h2}"
10307   [(set_attr "type" "alu")
10308    (set_attr "length_immediate" "0")
10309    (set_attr "mode" "QI")])
10310
10311 (define_insn "*xorqi_cc_1"
10312   [(set (reg FLAGS_REG)
10313         (compare
10314           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10315                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10316           (const_int 0)))
10317    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10318         (xor:QI (match_dup 1) (match_dup 2)))]
10319   "ix86_match_ccmode (insn, CCNOmode)
10320    && ix86_binary_operator_ok (XOR, QImode, operands)"
10321   "xor{b}\t{%2, %0|%0, %2}"
10322   [(set_attr "type" "alu")
10323    (set_attr "mode" "QI")])
10324
10325 (define_insn "*xorqi_2_slp"
10326   [(set (reg FLAGS_REG)
10327         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10328                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10329                  (const_int 0)))
10330    (set (strict_low_part (match_dup 0))
10331         (xor:QI (match_dup 0) (match_dup 1)))]
10332   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10333    && ix86_match_ccmode (insn, CCNOmode)
10334    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10335   "xor{b}\t{%1, %0|%0, %1}"
10336   [(set_attr "type" "alu1")
10337    (set_attr "mode" "QI")])
10338
10339 (define_insn "*xorqi_cc_2"
10340   [(set (reg FLAGS_REG)
10341         (compare
10342           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10343                   (match_operand:QI 2 "general_operand" "qmn"))
10344           (const_int 0)))
10345    (clobber (match_scratch:QI 0 "=q"))]
10346   "ix86_match_ccmode (insn, CCNOmode)
10347    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10348   "xor{b}\t{%2, %0|%0, %2}"
10349   [(set_attr "type" "alu")
10350    (set_attr "mode" "QI")])
10351
10352 (define_insn "*xorqi_cc_ext_1"
10353   [(set (reg FLAGS_REG)
10354         (compare
10355           (xor:SI
10356             (zero_extract:SI
10357               (match_operand 1 "ext_register_operand" "0")
10358               (const_int 8)
10359               (const_int 8))
10360             (match_operand:QI 2 "general_operand" "qmn"))
10361           (const_int 0)))
10362    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10363                          (const_int 8)
10364                          (const_int 8))
10365         (xor:SI
10366           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10367           (match_dup 2)))]
10368   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10369   "xor{b}\t{%2, %h0|%h0, %2}"
10370   [(set_attr "type" "alu")
10371    (set_attr "mode" "QI")])
10372
10373 (define_insn "*xorqi_cc_ext_1_rex64"
10374   [(set (reg FLAGS_REG)
10375         (compare
10376           (xor:SI
10377             (zero_extract:SI
10378               (match_operand 1 "ext_register_operand" "0")
10379               (const_int 8)
10380               (const_int 8))
10381             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10382           (const_int 0)))
10383    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10384                          (const_int 8)
10385                          (const_int 8))
10386         (xor:SI
10387           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10388           (match_dup 2)))]
10389   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10390   "xor{b}\t{%2, %h0|%h0, %2}"
10391   [(set_attr "type" "alu")
10392    (set_attr "mode" "QI")])
10393
10394 (define_expand "xorqi_cc_ext_1"
10395   [(parallel [
10396      (set (reg:CCNO FLAGS_REG)
10397           (compare:CCNO
10398             (xor:SI
10399               (zero_extract:SI
10400                 (match_operand 1 "ext_register_operand" "")
10401                 (const_int 8)
10402                 (const_int 8))
10403               (match_operand:QI 2 "general_operand" ""))
10404             (const_int 0)))
10405      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10406                            (const_int 8)
10407                            (const_int 8))
10408           (xor:SI
10409             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10410             (match_dup 2)))])]
10411   ""
10412   "")
10413
10414 (define_split
10415   [(set (match_operand 0 "register_operand" "")
10416         (xor (match_operand 1 "register_operand" "")
10417              (match_operand 2 "const_int_operand" "")))
10418    (clobber (reg:CC FLAGS_REG))]
10419    "reload_completed
10420     && QI_REG_P (operands[0])
10421     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10422     && !(INTVAL (operands[2]) & ~(255 << 8))
10423     && GET_MODE (operands[0]) != QImode"
10424   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10425                    (xor:SI (zero_extract:SI (match_dup 1)
10426                                             (const_int 8) (const_int 8))
10427                            (match_dup 2)))
10428               (clobber (reg:CC FLAGS_REG))])]
10429   "operands[0] = gen_lowpart (SImode, operands[0]);
10430    operands[1] = gen_lowpart (SImode, operands[1]);
10431    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10432
10433 ;; Since XOR can be encoded with sign extended immediate, this is only
10434 ;; profitable when 7th bit is set.
10435 (define_split
10436   [(set (match_operand 0 "register_operand" "")
10437         (xor (match_operand 1 "general_operand" "")
10438              (match_operand 2 "const_int_operand" "")))
10439    (clobber (reg:CC FLAGS_REG))]
10440    "reload_completed
10441     && ANY_QI_REG_P (operands[0])
10442     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10443     && !(INTVAL (operands[2]) & ~255)
10444     && (INTVAL (operands[2]) & 128)
10445     && GET_MODE (operands[0]) != QImode"
10446   [(parallel [(set (strict_low_part (match_dup 0))
10447                    (xor:QI (match_dup 1)
10448                            (match_dup 2)))
10449               (clobber (reg:CC FLAGS_REG))])]
10450   "operands[0] = gen_lowpart (QImode, operands[0]);
10451    operands[1] = gen_lowpart (QImode, operands[1]);
10452    operands[2] = gen_lowpart (QImode, operands[2]);")
10453 \f
10454 ;; Negation instructions
10455
10456 (define_expand "negti2"
10457   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10458         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10459   "TARGET_64BIT"
10460   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10461
10462 (define_insn "*negti2_1"
10463   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10464         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10465    (clobber (reg:CC FLAGS_REG))]
10466   "TARGET_64BIT
10467    && ix86_unary_operator_ok (NEG, TImode, operands)"
10468   "#")
10469
10470 (define_split
10471   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10472         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10473    (clobber (reg:CC FLAGS_REG))]
10474   "TARGET_64BIT && reload_completed"
10475   [(parallel
10476     [(set (reg:CCZ FLAGS_REG)
10477           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10478      (set (match_dup 0) (neg:DI (match_dup 1)))])
10479    (parallel
10480     [(set (match_dup 2)
10481           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10482                             (match_dup 3))
10483                    (const_int 0)))
10484      (clobber (reg:CC FLAGS_REG))])
10485    (parallel
10486     [(set (match_dup 2)
10487           (neg:DI (match_dup 2)))
10488      (clobber (reg:CC FLAGS_REG))])]
10489   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10490
10491 (define_expand "negdi2"
10492   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10493         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10494   ""
10495   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10496
10497 (define_insn "*negdi2_1"
10498   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10499         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10500    (clobber (reg:CC FLAGS_REG))]
10501   "!TARGET_64BIT
10502    && ix86_unary_operator_ok (NEG, DImode, operands)"
10503   "#")
10504
10505 (define_split
10506   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10507         (neg:DI (match_operand:DI 1 "general_operand" "")))
10508    (clobber (reg:CC FLAGS_REG))]
10509   "!TARGET_64BIT && reload_completed"
10510   [(parallel
10511     [(set (reg:CCZ FLAGS_REG)
10512           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10513      (set (match_dup 0) (neg:SI (match_dup 1)))])
10514    (parallel
10515     [(set (match_dup 2)
10516           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10517                             (match_dup 3))
10518                    (const_int 0)))
10519      (clobber (reg:CC FLAGS_REG))])
10520    (parallel
10521     [(set (match_dup 2)
10522           (neg:SI (match_dup 2)))
10523      (clobber (reg:CC FLAGS_REG))])]
10524   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10525
10526 (define_insn "*negdi2_1_rex64"
10527   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10528         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10529    (clobber (reg:CC FLAGS_REG))]
10530   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10531   "neg{q}\t%0"
10532   [(set_attr "type" "negnot")
10533    (set_attr "mode" "DI")])
10534
10535 ;; The problem with neg is that it does not perform (compare x 0),
10536 ;; it really performs (compare 0 x), which leaves us with the zero
10537 ;; flag being the only useful item.
10538
10539 (define_insn "*negdi2_cmpz_rex64"
10540   [(set (reg:CCZ FLAGS_REG)
10541         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10542                      (const_int 0)))
10543    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10544         (neg:DI (match_dup 1)))]
10545   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10546   "neg{q}\t%0"
10547   [(set_attr "type" "negnot")
10548    (set_attr "mode" "DI")])
10549
10550
10551 (define_expand "negsi2"
10552   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10553         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10554   ""
10555   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10556
10557 (define_insn "*negsi2_1"
10558   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10559         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10560    (clobber (reg:CC FLAGS_REG))]
10561   "ix86_unary_operator_ok (NEG, SImode, operands)"
10562   "neg{l}\t%0"
10563   [(set_attr "type" "negnot")
10564    (set_attr "mode" "SI")])
10565
10566 ;; Combine is quite creative about this pattern.
10567 (define_insn "*negsi2_1_zext"
10568   [(set (match_operand:DI 0 "register_operand" "=r")
10569         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10570                                         (const_int 32)))
10571                      (const_int 32)))
10572    (clobber (reg:CC FLAGS_REG))]
10573   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10574   "neg{l}\t%k0"
10575   [(set_attr "type" "negnot")
10576    (set_attr "mode" "SI")])
10577
10578 ;; The problem with neg is that it does not perform (compare x 0),
10579 ;; it really performs (compare 0 x), which leaves us with the zero
10580 ;; flag being the only useful item.
10581
10582 (define_insn "*negsi2_cmpz"
10583   [(set (reg:CCZ FLAGS_REG)
10584         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10585                      (const_int 0)))
10586    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10587         (neg:SI (match_dup 1)))]
10588   "ix86_unary_operator_ok (NEG, SImode, operands)"
10589   "neg{l}\t%0"
10590   [(set_attr "type" "negnot")
10591    (set_attr "mode" "SI")])
10592
10593 (define_insn "*negsi2_cmpz_zext"
10594   [(set (reg:CCZ FLAGS_REG)
10595         (compare:CCZ (lshiftrt:DI
10596                        (neg:DI (ashift:DI
10597                                  (match_operand:DI 1 "register_operand" "0")
10598                                  (const_int 32)))
10599                        (const_int 32))
10600                      (const_int 0)))
10601    (set (match_operand:DI 0 "register_operand" "=r")
10602         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10603                                         (const_int 32)))
10604                      (const_int 32)))]
10605   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10606   "neg{l}\t%k0"
10607   [(set_attr "type" "negnot")
10608    (set_attr "mode" "SI")])
10609
10610 (define_expand "neghi2"
10611   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10612         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10613   "TARGET_HIMODE_MATH"
10614   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10615
10616 (define_insn "*neghi2_1"
10617   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10618         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10619    (clobber (reg:CC FLAGS_REG))]
10620   "ix86_unary_operator_ok (NEG, HImode, operands)"
10621   "neg{w}\t%0"
10622   [(set_attr "type" "negnot")
10623    (set_attr "mode" "HI")])
10624
10625 (define_insn "*neghi2_cmpz"
10626   [(set (reg:CCZ FLAGS_REG)
10627         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10628                      (const_int 0)))
10629    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10630         (neg:HI (match_dup 1)))]
10631   "ix86_unary_operator_ok (NEG, HImode, operands)"
10632   "neg{w}\t%0"
10633   [(set_attr "type" "negnot")
10634    (set_attr "mode" "HI")])
10635
10636 (define_expand "negqi2"
10637   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10638         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10639   "TARGET_QIMODE_MATH"
10640   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10641
10642 (define_insn "*negqi2_1"
10643   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10644         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10645    (clobber (reg:CC FLAGS_REG))]
10646   "ix86_unary_operator_ok (NEG, QImode, operands)"
10647   "neg{b}\t%0"
10648   [(set_attr "type" "negnot")
10649    (set_attr "mode" "QI")])
10650
10651 (define_insn "*negqi2_cmpz"
10652   [(set (reg:CCZ FLAGS_REG)
10653         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10654                      (const_int 0)))
10655    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10656         (neg:QI (match_dup 1)))]
10657   "ix86_unary_operator_ok (NEG, QImode, operands)"
10658   "neg{b}\t%0"
10659   [(set_attr "type" "negnot")
10660    (set_attr "mode" "QI")])
10661
10662 ;; Changing of sign for FP values is doable using integer unit too.
10663
10664 (define_expand "<code><mode>2"
10665   [(set (match_operand:X87MODEF 0 "register_operand" "")
10666         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10667   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10668   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10669
10670 (define_insn "*absneg<mode>2_mixed"
10671   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10672         (match_operator:MODEF 3 "absneg_operator"
10673           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10674    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10675    (clobber (reg:CC FLAGS_REG))]
10676   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10677   "#")
10678
10679 (define_insn "*absneg<mode>2_sse"
10680   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10681         (match_operator:MODEF 3 "absneg_operator"
10682           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10683    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10684    (clobber (reg:CC FLAGS_REG))]
10685   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10686   "#")
10687
10688 (define_insn "*absneg<mode>2_i387"
10689   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10690         (match_operator:X87MODEF 3 "absneg_operator"
10691           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10692    (use (match_operand 2 "" ""))
10693    (clobber (reg:CC FLAGS_REG))]
10694   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10695   "#")
10696
10697 (define_expand "<code>tf2"
10698   [(set (match_operand:TF 0 "register_operand" "")
10699         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10700   "TARGET_SSE2"
10701   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10702
10703 (define_insn "*absnegtf2_sse"
10704   [(set (match_operand:TF 0 "register_operand" "=x,x")
10705         (match_operator:TF 3 "absneg_operator"
10706           [(match_operand:TF 1 "register_operand" "0,x")]))
10707    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10708    (clobber (reg:CC FLAGS_REG))]
10709   "TARGET_SSE2"
10710   "#")
10711
10712 ;; Splitters for fp abs and neg.
10713
10714 (define_split
10715   [(set (match_operand 0 "fp_register_operand" "")
10716         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10717    (use (match_operand 2 "" ""))
10718    (clobber (reg:CC FLAGS_REG))]
10719   "reload_completed"
10720   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10721
10722 (define_split
10723   [(set (match_operand 0 "register_operand" "")
10724         (match_operator 3 "absneg_operator"
10725           [(match_operand 1 "register_operand" "")]))
10726    (use (match_operand 2 "nonimmediate_operand" ""))
10727    (clobber (reg:CC FLAGS_REG))]
10728   "reload_completed && SSE_REG_P (operands[0])"
10729   [(set (match_dup 0) (match_dup 3))]
10730 {
10731   enum machine_mode mode = GET_MODE (operands[0]);
10732   enum machine_mode vmode = GET_MODE (operands[2]);
10733   rtx tmp;
10734
10735   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10736   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10737   if (operands_match_p (operands[0], operands[2]))
10738     {
10739       tmp = operands[1];
10740       operands[1] = operands[2];
10741       operands[2] = tmp;
10742     }
10743   if (GET_CODE (operands[3]) == ABS)
10744     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10745   else
10746     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10747   operands[3] = tmp;
10748 })
10749
10750 (define_split
10751   [(set (match_operand:SF 0 "register_operand" "")
10752         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10753    (use (match_operand:V4SF 2 "" ""))
10754    (clobber (reg:CC FLAGS_REG))]
10755   "reload_completed"
10756   [(parallel [(set (match_dup 0) (match_dup 1))
10757               (clobber (reg:CC FLAGS_REG))])]
10758 {
10759   rtx tmp;
10760   operands[0] = gen_lowpart (SImode, operands[0]);
10761   if (GET_CODE (operands[1]) == ABS)
10762     {
10763       tmp = gen_int_mode (0x7fffffff, SImode);
10764       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10765     }
10766   else
10767     {
10768       tmp = gen_int_mode (0x80000000, SImode);
10769       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10770     }
10771   operands[1] = tmp;
10772 })
10773
10774 (define_split
10775   [(set (match_operand:DF 0 "register_operand" "")
10776         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10777    (use (match_operand 2 "" ""))
10778    (clobber (reg:CC FLAGS_REG))]
10779   "reload_completed"
10780   [(parallel [(set (match_dup 0) (match_dup 1))
10781               (clobber (reg:CC FLAGS_REG))])]
10782 {
10783   rtx tmp;
10784   if (TARGET_64BIT)
10785     {
10786       tmp = gen_lowpart (DImode, operands[0]);
10787       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10788       operands[0] = tmp;
10789
10790       if (GET_CODE (operands[1]) == ABS)
10791         tmp = const0_rtx;
10792       else
10793         tmp = gen_rtx_NOT (DImode, tmp);
10794     }
10795   else
10796     {
10797       operands[0] = gen_highpart (SImode, operands[0]);
10798       if (GET_CODE (operands[1]) == ABS)
10799         {
10800           tmp = gen_int_mode (0x7fffffff, SImode);
10801           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10802         }
10803       else
10804         {
10805           tmp = gen_int_mode (0x80000000, SImode);
10806           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10807         }
10808     }
10809   operands[1] = tmp;
10810 })
10811
10812 (define_split
10813   [(set (match_operand:XF 0 "register_operand" "")
10814         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10815    (use (match_operand 2 "" ""))
10816    (clobber (reg:CC FLAGS_REG))]
10817   "reload_completed"
10818   [(parallel [(set (match_dup 0) (match_dup 1))
10819               (clobber (reg:CC FLAGS_REG))])]
10820 {
10821   rtx tmp;
10822   operands[0] = gen_rtx_REG (SImode,
10823                              true_regnum (operands[0])
10824                              + (TARGET_64BIT ? 1 : 2));
10825   if (GET_CODE (operands[1]) == ABS)
10826     {
10827       tmp = GEN_INT (0x7fff);
10828       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10829     }
10830   else
10831     {
10832       tmp = GEN_INT (0x8000);
10833       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10834     }
10835   operands[1] = tmp;
10836 })
10837
10838 ;; Conditionalize these after reload. If they match before reload, we
10839 ;; lose the clobber and ability to use integer instructions.
10840
10841 (define_insn "*<code><mode>2_1"
10842   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10843         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10844   "TARGET_80387
10845    && (reload_completed
10846        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10847   "f<absnegprefix>"
10848   [(set_attr "type" "fsgn")
10849    (set_attr "mode" "<MODE>")])
10850
10851 (define_insn "*<code>extendsfdf2"
10852   [(set (match_operand:DF 0 "register_operand" "=f")
10853         (absneg:DF (float_extend:DF
10854                      (match_operand:SF 1 "register_operand" "0"))))]
10855   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10856   "f<absnegprefix>"
10857   [(set_attr "type" "fsgn")
10858    (set_attr "mode" "DF")])
10859
10860 (define_insn "*<code>extendsfxf2"
10861   [(set (match_operand:XF 0 "register_operand" "=f")
10862         (absneg:XF (float_extend:XF
10863                      (match_operand:SF 1 "register_operand" "0"))))]
10864   "TARGET_80387"
10865   "f<absnegprefix>"
10866   [(set_attr "type" "fsgn")
10867    (set_attr "mode" "XF")])
10868
10869 (define_insn "*<code>extenddfxf2"
10870   [(set (match_operand:XF 0 "register_operand" "=f")
10871         (absneg:XF (float_extend:XF
10872                       (match_operand:DF 1 "register_operand" "0"))))]
10873   "TARGET_80387"
10874   "f<absnegprefix>"
10875   [(set_attr "type" "fsgn")
10876    (set_attr "mode" "XF")])
10877
10878 ;; Copysign instructions
10879
10880 (define_mode_iterator CSGNMODE [SF DF TF])
10881 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10882
10883 (define_expand "copysign<mode>3"
10884   [(match_operand:CSGNMODE 0 "register_operand" "")
10885    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10886    (match_operand:CSGNMODE 2 "register_operand" "")]
10887   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10888    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10889 {
10890   ix86_expand_copysign (operands);
10891   DONE;
10892 })
10893
10894 (define_insn_and_split "copysign<mode>3_const"
10895   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10896         (unspec:CSGNMODE
10897           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10898            (match_operand:CSGNMODE 2 "register_operand" "0")
10899            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10900           UNSPEC_COPYSIGN))]
10901   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10902    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10903   "#"
10904   "&& reload_completed"
10905   [(const_int 0)]
10906 {
10907   ix86_split_copysign_const (operands);
10908   DONE;
10909 })
10910
10911 (define_insn "copysign<mode>3_var"
10912   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10913         (unspec:CSGNMODE
10914           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10915            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10916            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10917            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10918           UNSPEC_COPYSIGN))
10919    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10920   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10921    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10922   "#")
10923
10924 (define_split
10925   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10926         (unspec:CSGNMODE
10927           [(match_operand:CSGNMODE 2 "register_operand" "")
10928            (match_operand:CSGNMODE 3 "register_operand" "")
10929            (match_operand:<CSGNVMODE> 4 "" "")
10930            (match_operand:<CSGNVMODE> 5 "" "")]
10931           UNSPEC_COPYSIGN))
10932    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10933   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10934     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10935    && reload_completed"
10936   [(const_int 0)]
10937 {
10938   ix86_split_copysign_var (operands);
10939   DONE;
10940 })
10941 \f
10942 ;; One complement instructions
10943
10944 (define_expand "one_cmpldi2"
10945   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10946         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10947   "TARGET_64BIT"
10948   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10949
10950 (define_insn "*one_cmpldi2_1_rex64"
10951   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10952         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10953   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10954   "not{q}\t%0"
10955   [(set_attr "type" "negnot")
10956    (set_attr "mode" "DI")])
10957
10958 (define_insn "*one_cmpldi2_2_rex64"
10959   [(set (reg FLAGS_REG)
10960         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10961                  (const_int 0)))
10962    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10963         (not:DI (match_dup 1)))]
10964   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10965    && ix86_unary_operator_ok (NOT, DImode, operands)"
10966   "#"
10967   [(set_attr "type" "alu1")
10968    (set_attr "mode" "DI")])
10969
10970 (define_split
10971   [(set (match_operand 0 "flags_reg_operand" "")
10972         (match_operator 2 "compare_operator"
10973           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10974            (const_int 0)]))
10975    (set (match_operand:DI 1 "nonimmediate_operand" "")
10976         (not:DI (match_dup 3)))]
10977   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10978   [(parallel [(set (match_dup 0)
10979                    (match_op_dup 2
10980                      [(xor:DI (match_dup 3) (const_int -1))
10981                       (const_int 0)]))
10982               (set (match_dup 1)
10983                    (xor:DI (match_dup 3) (const_int -1)))])]
10984   "")
10985
10986 (define_expand "one_cmplsi2"
10987   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10988         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10989   ""
10990   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10991
10992 (define_insn "*one_cmplsi2_1"
10993   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10994         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10995   "ix86_unary_operator_ok (NOT, SImode, operands)"
10996   "not{l}\t%0"
10997   [(set_attr "type" "negnot")
10998    (set_attr "mode" "SI")])
10999
11000 ;; ??? Currently never generated - xor is used instead.
11001 (define_insn "*one_cmplsi2_1_zext"
11002   [(set (match_operand:DI 0 "register_operand" "=r")
11003         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
11004   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
11005   "not{l}\t%k0"
11006   [(set_attr "type" "negnot")
11007    (set_attr "mode" "SI")])
11008
11009 (define_insn "*one_cmplsi2_2"
11010   [(set (reg FLAGS_REG)
11011         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11012                  (const_int 0)))
11013    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11014         (not:SI (match_dup 1)))]
11015   "ix86_match_ccmode (insn, CCNOmode)
11016    && ix86_unary_operator_ok (NOT, SImode, operands)"
11017   "#"
11018   [(set_attr "type" "alu1")
11019    (set_attr "mode" "SI")])
11020
11021 (define_split
11022   [(set (match_operand 0 "flags_reg_operand" "")
11023         (match_operator 2 "compare_operator"
11024           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
11025            (const_int 0)]))
11026    (set (match_operand:SI 1 "nonimmediate_operand" "")
11027         (not:SI (match_dup 3)))]
11028   "ix86_match_ccmode (insn, CCNOmode)"
11029   [(parallel [(set (match_dup 0)
11030                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11031                                     (const_int 0)]))
11032               (set (match_dup 1)
11033                    (xor:SI (match_dup 3) (const_int -1)))])]
11034   "")
11035
11036 ;; ??? Currently never generated - xor is used instead.
11037 (define_insn "*one_cmplsi2_2_zext"
11038   [(set (reg FLAGS_REG)
11039         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
11040                  (const_int 0)))
11041    (set (match_operand:DI 0 "register_operand" "=r")
11042         (zero_extend:DI (not:SI (match_dup 1))))]
11043   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11044    && ix86_unary_operator_ok (NOT, SImode, operands)"
11045   "#"
11046   [(set_attr "type" "alu1")
11047    (set_attr "mode" "SI")])
11048
11049 (define_split
11050   [(set (match_operand 0 "flags_reg_operand" "")
11051         (match_operator 2 "compare_operator"
11052           [(not:SI (match_operand:SI 3 "register_operand" ""))
11053            (const_int 0)]))
11054    (set (match_operand:DI 1 "register_operand" "")
11055         (zero_extend:DI (not:SI (match_dup 3))))]
11056   "ix86_match_ccmode (insn, CCNOmode)"
11057   [(parallel [(set (match_dup 0)
11058                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11059                                     (const_int 0)]))
11060               (set (match_dup 1)
11061                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
11062   "")
11063
11064 (define_expand "one_cmplhi2"
11065   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11066         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11067   "TARGET_HIMODE_MATH"
11068   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11069
11070 (define_insn "*one_cmplhi2_1"
11071   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11072         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11073   "ix86_unary_operator_ok (NOT, HImode, operands)"
11074   "not{w}\t%0"
11075   [(set_attr "type" "negnot")
11076    (set_attr "mode" "HI")])
11077
11078 (define_insn "*one_cmplhi2_2"
11079   [(set (reg FLAGS_REG)
11080         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11081                  (const_int 0)))
11082    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11083         (not:HI (match_dup 1)))]
11084   "ix86_match_ccmode (insn, CCNOmode)
11085    && ix86_unary_operator_ok (NEG, HImode, operands)"
11086   "#"
11087   [(set_attr "type" "alu1")
11088    (set_attr "mode" "HI")])
11089
11090 (define_split
11091   [(set (match_operand 0 "flags_reg_operand" "")
11092         (match_operator 2 "compare_operator"
11093           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11094            (const_int 0)]))
11095    (set (match_operand:HI 1 "nonimmediate_operand" "")
11096         (not:HI (match_dup 3)))]
11097   "ix86_match_ccmode (insn, CCNOmode)"
11098   [(parallel [(set (match_dup 0)
11099                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11100                                     (const_int 0)]))
11101               (set (match_dup 1)
11102                    (xor:HI (match_dup 3) (const_int -1)))])]
11103   "")
11104
11105 ;; %%% Potential partial reg stall on alternative 1.  What to do?
11106 (define_expand "one_cmplqi2"
11107   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11108         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11109   "TARGET_QIMODE_MATH"
11110   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11111
11112 (define_insn "*one_cmplqi2_1"
11113   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11114         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11115   "ix86_unary_operator_ok (NOT, QImode, operands)"
11116   "@
11117    not{b}\t%0
11118    not{l}\t%k0"
11119   [(set_attr "type" "negnot")
11120    (set_attr "mode" "QI,SI")])
11121
11122 (define_insn "*one_cmplqi2_2"
11123   [(set (reg FLAGS_REG)
11124         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11125                  (const_int 0)))
11126    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11127         (not:QI (match_dup 1)))]
11128   "ix86_match_ccmode (insn, CCNOmode)
11129    && ix86_unary_operator_ok (NOT, QImode, operands)"
11130   "#"
11131   [(set_attr "type" "alu1")
11132    (set_attr "mode" "QI")])
11133
11134 (define_split
11135   [(set (match_operand 0 "flags_reg_operand" "")
11136         (match_operator 2 "compare_operator"
11137           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11138            (const_int 0)]))
11139    (set (match_operand:QI 1 "nonimmediate_operand" "")
11140         (not:QI (match_dup 3)))]
11141   "ix86_match_ccmode (insn, CCNOmode)"
11142   [(parallel [(set (match_dup 0)
11143                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11144                                     (const_int 0)]))
11145               (set (match_dup 1)
11146                    (xor:QI (match_dup 3) (const_int -1)))])]
11147   "")
11148 \f
11149 ;; Arithmetic shift instructions
11150
11151 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11152 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11153 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11154 ;; from the assembler input.
11155 ;;
11156 ;; This instruction shifts the target reg/mem as usual, but instead of
11157 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11158 ;; is a left shift double, bits are taken from the high order bits of
11159 ;; reg, else if the insn is a shift right double, bits are taken from the
11160 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11161 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11162 ;;
11163 ;; Since sh[lr]d does not change the `reg' operand, that is done
11164 ;; separately, making all shifts emit pairs of shift double and normal
11165 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11166 ;; support a 63 bit shift, each shift where the count is in a reg expands
11167 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11168 ;;
11169 ;; If the shift count is a constant, we need never emit more than one
11170 ;; shift pair, instead using moves and sign extension for counts greater
11171 ;; than 31.
11172
11173 (define_expand "ashlti3"
11174   [(set (match_operand:TI 0 "register_operand" "")
11175         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11176                    (match_operand:QI 2 "nonmemory_operand" "")))]
11177   "TARGET_64BIT"
11178   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11179
11180 ;; This pattern must be defined before *ashlti3_1 to prevent
11181 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11182
11183 (define_insn "*avx_ashlti3"
11184   [(set (match_operand:TI 0 "register_operand" "=x")
11185         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11186                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11187   "TARGET_AVX"
11188 {
11189   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11190   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11191 }
11192   [(set_attr "type" "sseishft")
11193    (set_attr "prefix" "vex")
11194    (set_attr "mode" "TI")])
11195
11196 (define_insn "sse2_ashlti3"
11197   [(set (match_operand:TI 0 "register_operand" "=x")
11198         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11199                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11200   "TARGET_SSE2"
11201 {
11202   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11203   return "pslldq\t{%2, %0|%0, %2}";
11204 }
11205   [(set_attr "type" "sseishft")
11206    (set_attr "prefix_data16" "1")
11207    (set_attr "mode" "TI")])
11208
11209 (define_insn "*ashlti3_1"
11210   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11211         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11212                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11213    (clobber (reg:CC FLAGS_REG))]
11214   "TARGET_64BIT"
11215   "#"
11216   [(set_attr "type" "multi")])
11217
11218 (define_peephole2
11219   [(match_scratch:DI 3 "r")
11220    (parallel [(set (match_operand:TI 0 "register_operand" "")
11221                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11222                               (match_operand:QI 2 "nonmemory_operand" "")))
11223               (clobber (reg:CC FLAGS_REG))])
11224    (match_dup 3)]
11225   "TARGET_64BIT"
11226   [(const_int 0)]
11227   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11228
11229 (define_split
11230   [(set (match_operand:TI 0 "register_operand" "")
11231         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11232                    (match_operand:QI 2 "nonmemory_operand" "")))
11233    (clobber (reg:CC FLAGS_REG))]
11234   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11235                     ? epilogue_completed : reload_completed)"
11236   [(const_int 0)]
11237   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11238
11239 (define_insn "x86_64_shld"
11240   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11241         (ior:DI (ashift:DI (match_dup 0)
11242                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11243                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11244                   (minus:QI (const_int 64) (match_dup 2)))))
11245    (clobber (reg:CC FLAGS_REG))]
11246   "TARGET_64BIT"
11247   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11248   [(set_attr "type" "ishift")
11249    (set_attr "prefix_0f" "1")
11250    (set_attr "mode" "DI")
11251    (set_attr "athlon_decode" "vector")
11252    (set_attr "amdfam10_decode" "vector")])
11253
11254 (define_expand "x86_64_shift_adj_1"
11255   [(set (reg:CCZ FLAGS_REG)
11256         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11257                              (const_int 64))
11258                      (const_int 0)))
11259    (set (match_operand:DI 0 "register_operand" "")
11260         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11261                          (match_operand:DI 1 "register_operand" "")
11262                          (match_dup 0)))
11263    (set (match_dup 1)
11264         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11265                          (match_operand:DI 3 "register_operand" "r")
11266                          (match_dup 1)))]
11267   "TARGET_64BIT"
11268   "")
11269
11270 (define_expand "x86_64_shift_adj_2"
11271   [(use (match_operand:DI 0 "register_operand" ""))
11272    (use (match_operand:DI 1 "register_operand" ""))
11273    (use (match_operand:QI 2 "register_operand" ""))]
11274   "TARGET_64BIT"
11275 {
11276   rtx label = gen_label_rtx ();
11277   rtx tmp;
11278
11279   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11280
11281   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11282   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11283   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11284                               gen_rtx_LABEL_REF (VOIDmode, label),
11285                               pc_rtx);
11286   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11287   JUMP_LABEL (tmp) = label;
11288
11289   emit_move_insn (operands[0], operands[1]);
11290   ix86_expand_clear (operands[1]);
11291
11292   emit_label (label);
11293   LABEL_NUSES (label) = 1;
11294
11295   DONE;
11296 })
11297
11298 (define_expand "ashldi3"
11299   [(set (match_operand:DI 0 "shiftdi_operand" "")
11300         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11301                    (match_operand:QI 2 "nonmemory_operand" "")))]
11302   ""
11303   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11304
11305 (define_insn "*ashldi3_1_rex64"
11306   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11307         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11308                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11309    (clobber (reg:CC FLAGS_REG))]
11310   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11311 {
11312   switch (get_attr_type (insn))
11313     {
11314     case TYPE_ALU:
11315       gcc_assert (operands[2] == const1_rtx);
11316       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11317       return "add{q}\t%0, %0";
11318
11319     case TYPE_LEA:
11320       gcc_assert (CONST_INT_P (operands[2]));
11321       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11322       operands[1] = gen_rtx_MULT (DImode, operands[1],
11323                                   GEN_INT (1 << INTVAL (operands[2])));
11324       return "lea{q}\t{%a1, %0|%0, %a1}";
11325
11326     default:
11327       if (REG_P (operands[2]))
11328         return "sal{q}\t{%b2, %0|%0, %b2}";
11329       else if (operands[2] == const1_rtx
11330                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11331         return "sal{q}\t%0";
11332       else
11333         return "sal{q}\t{%2, %0|%0, %2}";
11334     }
11335 }
11336   [(set (attr "type")
11337      (cond [(eq_attr "alternative" "1")
11338               (const_string "lea")
11339             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11340                           (const_int 0))
11341                       (match_operand 0 "register_operand" ""))
11342                  (match_operand 2 "const1_operand" ""))
11343               (const_string "alu")
11344            ]
11345            (const_string "ishift")))
11346    (set_attr "mode" "DI")])
11347
11348 ;; Convert lea to the lea pattern to avoid flags dependency.
11349 (define_split
11350   [(set (match_operand:DI 0 "register_operand" "")
11351         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11352                    (match_operand:QI 2 "immediate_operand" "")))
11353    (clobber (reg:CC FLAGS_REG))]
11354   "TARGET_64BIT && reload_completed
11355    && true_regnum (operands[0]) != true_regnum (operands[1])"
11356   [(set (match_dup 0)
11357         (mult:DI (match_dup 1)
11358                  (match_dup 2)))]
11359   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11360
11361 ;; This pattern can't accept a variable shift count, since shifts by
11362 ;; zero don't affect the flags.  We assume that shifts by constant
11363 ;; zero are optimized away.
11364 (define_insn "*ashldi3_cmp_rex64"
11365   [(set (reg FLAGS_REG)
11366         (compare
11367           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11368                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11369           (const_int 0)))
11370    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11371         (ashift:DI (match_dup 1) (match_dup 2)))]
11372   "TARGET_64BIT
11373    && (optimize_function_for_size_p (cfun)
11374        || !TARGET_PARTIAL_FLAG_REG_STALL
11375        || (operands[2] == const1_rtx
11376            && (TARGET_SHIFT1
11377                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11378    && ix86_match_ccmode (insn, CCGOCmode)
11379    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11380 {
11381   switch (get_attr_type (insn))
11382     {
11383     case TYPE_ALU:
11384       gcc_assert (operands[2] == const1_rtx);
11385       return "add{q}\t%0, %0";
11386
11387     default:
11388       if (REG_P (operands[2]))
11389         return "sal{q}\t{%b2, %0|%0, %b2}";
11390       else if (operands[2] == const1_rtx
11391                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11392         return "sal{q}\t%0";
11393       else
11394         return "sal{q}\t{%2, %0|%0, %2}";
11395     }
11396 }
11397   [(set (attr "type")
11398      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11399                           (const_int 0))
11400                       (match_operand 0 "register_operand" ""))
11401                  (match_operand 2 "const1_operand" ""))
11402               (const_string "alu")
11403            ]
11404            (const_string "ishift")))
11405    (set_attr "mode" "DI")])
11406
11407 (define_insn "*ashldi3_cconly_rex64"
11408   [(set (reg FLAGS_REG)
11409         (compare
11410           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11411                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11412           (const_int 0)))
11413    (clobber (match_scratch:DI 0 "=r"))]
11414   "TARGET_64BIT
11415    && (optimize_function_for_size_p (cfun)
11416        || !TARGET_PARTIAL_FLAG_REG_STALL
11417        || (operands[2] == const1_rtx
11418            && (TARGET_SHIFT1
11419                || TARGET_DOUBLE_WITH_ADD)))
11420    && ix86_match_ccmode (insn, CCGOCmode)
11421    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11422 {
11423   switch (get_attr_type (insn))
11424     {
11425     case TYPE_ALU:
11426       gcc_assert (operands[2] == const1_rtx);
11427       return "add{q}\t%0, %0";
11428
11429     default:
11430       if (REG_P (operands[2]))
11431         return "sal{q}\t{%b2, %0|%0, %b2}";
11432       else if (operands[2] == const1_rtx
11433                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11434         return "sal{q}\t%0";
11435       else
11436         return "sal{q}\t{%2, %0|%0, %2}";
11437     }
11438 }
11439   [(set (attr "type")
11440      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11441                           (const_int 0))
11442                       (match_operand 0 "register_operand" ""))
11443                  (match_operand 2 "const1_operand" ""))
11444               (const_string "alu")
11445            ]
11446            (const_string "ishift")))
11447    (set_attr "mode" "DI")])
11448
11449 (define_insn "*ashldi3_1"
11450   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11451         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11452                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11453    (clobber (reg:CC FLAGS_REG))]
11454   "!TARGET_64BIT"
11455   "#"
11456   [(set_attr "type" "multi")])
11457
11458 ;; By default we don't ask for a scratch register, because when DImode
11459 ;; values are manipulated, registers are already at a premium.  But if
11460 ;; we have one handy, we won't turn it away.
11461 (define_peephole2
11462   [(match_scratch:SI 3 "r")
11463    (parallel [(set (match_operand:DI 0 "register_operand" "")
11464                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11465                               (match_operand:QI 2 "nonmemory_operand" "")))
11466               (clobber (reg:CC FLAGS_REG))])
11467    (match_dup 3)]
11468   "!TARGET_64BIT && TARGET_CMOVE"
11469   [(const_int 0)]
11470   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11471
11472 (define_split
11473   [(set (match_operand:DI 0 "register_operand" "")
11474         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11475                    (match_operand:QI 2 "nonmemory_operand" "")))
11476    (clobber (reg:CC FLAGS_REG))]
11477   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11478                      ? epilogue_completed : reload_completed)"
11479   [(const_int 0)]
11480   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11481
11482 (define_insn "x86_shld"
11483   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11484         (ior:SI (ashift:SI (match_dup 0)
11485                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11486                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11487                   (minus:QI (const_int 32) (match_dup 2)))))
11488    (clobber (reg:CC FLAGS_REG))]
11489   ""
11490   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11491   [(set_attr "type" "ishift")
11492    (set_attr "prefix_0f" "1")
11493    (set_attr "mode" "SI")
11494    (set_attr "pent_pair" "np")
11495    (set_attr "athlon_decode" "vector")
11496    (set_attr "amdfam10_decode" "vector")])
11497
11498 (define_expand "x86_shift_adj_1"
11499   [(set (reg:CCZ FLAGS_REG)
11500         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11501                              (const_int 32))
11502                      (const_int 0)))
11503    (set (match_operand:SI 0 "register_operand" "")
11504         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11505                          (match_operand:SI 1 "register_operand" "")
11506                          (match_dup 0)))
11507    (set (match_dup 1)
11508         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11509                          (match_operand:SI 3 "register_operand" "r")
11510                          (match_dup 1)))]
11511   "TARGET_CMOVE"
11512   "")
11513
11514 (define_expand "x86_shift_adj_2"
11515   [(use (match_operand:SI 0 "register_operand" ""))
11516    (use (match_operand:SI 1 "register_operand" ""))
11517    (use (match_operand:QI 2 "register_operand" ""))]
11518   ""
11519 {
11520   rtx label = gen_label_rtx ();
11521   rtx tmp;
11522
11523   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11524
11525   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11526   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11527   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11528                               gen_rtx_LABEL_REF (VOIDmode, label),
11529                               pc_rtx);
11530   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11531   JUMP_LABEL (tmp) = label;
11532
11533   emit_move_insn (operands[0], operands[1]);
11534   ix86_expand_clear (operands[1]);
11535
11536   emit_label (label);
11537   LABEL_NUSES (label) = 1;
11538
11539   DONE;
11540 })
11541
11542 (define_expand "ashlsi3"
11543   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11544         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11545                    (match_operand:QI 2 "nonmemory_operand" "")))]
11546   ""
11547   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11548
11549 (define_insn "*ashlsi3_1"
11550   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11551         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11552                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11553    (clobber (reg:CC FLAGS_REG))]
11554   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11555 {
11556   switch (get_attr_type (insn))
11557     {
11558     case TYPE_ALU:
11559       gcc_assert (operands[2] == const1_rtx);
11560       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11561       return "add{l}\t%0, %0";
11562
11563     case TYPE_LEA:
11564       return "#";
11565
11566     default:
11567       if (REG_P (operands[2]))
11568         return "sal{l}\t{%b2, %0|%0, %b2}";
11569       else if (operands[2] == const1_rtx
11570                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11571         return "sal{l}\t%0";
11572       else
11573         return "sal{l}\t{%2, %0|%0, %2}";
11574     }
11575 }
11576   [(set (attr "type")
11577      (cond [(eq_attr "alternative" "1")
11578               (const_string "lea")
11579             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11580                           (const_int 0))
11581                       (match_operand 0 "register_operand" ""))
11582                  (match_operand 2 "const1_operand" ""))
11583               (const_string "alu")
11584            ]
11585            (const_string "ishift")))
11586    (set_attr "mode" "SI")])
11587
11588 ;; Convert lea to the lea pattern to avoid flags dependency.
11589 (define_split
11590   [(set (match_operand 0 "register_operand" "")
11591         (ashift (match_operand 1 "index_register_operand" "")
11592                 (match_operand:QI 2 "const_int_operand" "")))
11593    (clobber (reg:CC FLAGS_REG))]
11594   "reload_completed
11595    && true_regnum (operands[0]) != true_regnum (operands[1])
11596    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11597   [(const_int 0)]
11598 {
11599   rtx pat;
11600   enum machine_mode mode = GET_MODE (operands[0]);
11601
11602   if (GET_MODE_SIZE (mode) < 4)
11603     operands[0] = gen_lowpart (SImode, operands[0]);
11604   if (mode != Pmode)
11605     operands[1] = gen_lowpart (Pmode, operands[1]);
11606   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11607
11608   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11609   if (Pmode != SImode)
11610     pat = gen_rtx_SUBREG (SImode, pat, 0);
11611   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11612   DONE;
11613 })
11614
11615 ;; Rare case of shifting RSP is handled by generating move and shift
11616 (define_split
11617   [(set (match_operand 0 "register_operand" "")
11618         (ashift (match_operand 1 "register_operand" "")
11619                 (match_operand:QI 2 "const_int_operand" "")))
11620    (clobber (reg:CC FLAGS_REG))]
11621   "reload_completed
11622    && true_regnum (operands[0]) != true_regnum (operands[1])"
11623   [(const_int 0)]
11624 {
11625   rtx pat, clob;
11626   emit_move_insn (operands[0], operands[1]);
11627   pat = gen_rtx_SET (VOIDmode, operands[0],
11628                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11629                                      operands[0], operands[2]));
11630   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11631   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11632   DONE;
11633 })
11634
11635 (define_insn "*ashlsi3_1_zext"
11636   [(set (match_operand:DI 0 "register_operand" "=r,r")
11637         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11638                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11639    (clobber (reg:CC FLAGS_REG))]
11640   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11641 {
11642   switch (get_attr_type (insn))
11643     {
11644     case TYPE_ALU:
11645       gcc_assert (operands[2] == const1_rtx);
11646       return "add{l}\t%k0, %k0";
11647
11648     case TYPE_LEA:
11649       return "#";
11650
11651     default:
11652       if (REG_P (operands[2]))
11653         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11654       else if (operands[2] == const1_rtx
11655                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11656         return "sal{l}\t%k0";
11657       else
11658         return "sal{l}\t{%2, %k0|%k0, %2}";
11659     }
11660 }
11661   [(set (attr "type")
11662      (cond [(eq_attr "alternative" "1")
11663               (const_string "lea")
11664             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11665                      (const_int 0))
11666                  (match_operand 2 "const1_operand" ""))
11667               (const_string "alu")
11668            ]
11669            (const_string "ishift")))
11670    (set_attr "mode" "SI")])
11671
11672 ;; Convert lea to the lea pattern to avoid flags dependency.
11673 (define_split
11674   [(set (match_operand:DI 0 "register_operand" "")
11675         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11676                                 (match_operand:QI 2 "const_int_operand" ""))))
11677    (clobber (reg:CC FLAGS_REG))]
11678   "TARGET_64BIT && reload_completed
11679    && true_regnum (operands[0]) != true_regnum (operands[1])"
11680   [(set (match_dup 0) (zero_extend:DI
11681                         (subreg:SI (mult:SI (match_dup 1)
11682                                             (match_dup 2)) 0)))]
11683 {
11684   operands[1] = gen_lowpart (Pmode, operands[1]);
11685   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11686 })
11687
11688 ;; This pattern can't accept a variable shift count, since shifts by
11689 ;; zero don't affect the flags.  We assume that shifts by constant
11690 ;; zero are optimized away.
11691 (define_insn "*ashlsi3_cmp"
11692   [(set (reg FLAGS_REG)
11693         (compare
11694           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11695                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11696           (const_int 0)))
11697    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11698         (ashift:SI (match_dup 1) (match_dup 2)))]
11699    "(optimize_function_for_size_p (cfun)
11700      || !TARGET_PARTIAL_FLAG_REG_STALL
11701      || (operands[2] == const1_rtx
11702          && (TARGET_SHIFT1
11703              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11704    && ix86_match_ccmode (insn, CCGOCmode)
11705    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11706 {
11707   switch (get_attr_type (insn))
11708     {
11709     case TYPE_ALU:
11710       gcc_assert (operands[2] == const1_rtx);
11711       return "add{l}\t%0, %0";
11712
11713     default:
11714       if (REG_P (operands[2]))
11715         return "sal{l}\t{%b2, %0|%0, %b2}";
11716       else if (operands[2] == const1_rtx
11717                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11718         return "sal{l}\t%0";
11719       else
11720         return "sal{l}\t{%2, %0|%0, %2}";
11721     }
11722 }
11723   [(set (attr "type")
11724      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11725                           (const_int 0))
11726                       (match_operand 0 "register_operand" ""))
11727                  (match_operand 2 "const1_operand" ""))
11728               (const_string "alu")
11729            ]
11730            (const_string "ishift")))
11731    (set_attr "mode" "SI")])
11732
11733 (define_insn "*ashlsi3_cconly"
11734   [(set (reg FLAGS_REG)
11735         (compare
11736           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11737                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11738           (const_int 0)))
11739    (clobber (match_scratch:SI 0 "=r"))]
11740   "(optimize_function_for_size_p (cfun)
11741     || !TARGET_PARTIAL_FLAG_REG_STALL
11742     || (operands[2] == const1_rtx
11743         && (TARGET_SHIFT1
11744             || TARGET_DOUBLE_WITH_ADD)))
11745    && ix86_match_ccmode (insn, CCGOCmode)
11746    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11747 {
11748   switch (get_attr_type (insn))
11749     {
11750     case TYPE_ALU:
11751       gcc_assert (operands[2] == const1_rtx);
11752       return "add{l}\t%0, %0";
11753
11754     default:
11755       if (REG_P (operands[2]))
11756         return "sal{l}\t{%b2, %0|%0, %b2}";
11757       else if (operands[2] == const1_rtx
11758                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11759         return "sal{l}\t%0";
11760       else
11761         return "sal{l}\t{%2, %0|%0, %2}";
11762     }
11763 }
11764   [(set (attr "type")
11765      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11766                           (const_int 0))
11767                       (match_operand 0 "register_operand" ""))
11768                  (match_operand 2 "const1_operand" ""))
11769               (const_string "alu")
11770            ]
11771            (const_string "ishift")))
11772    (set_attr "mode" "SI")])
11773
11774 (define_insn "*ashlsi3_cmp_zext"
11775   [(set (reg FLAGS_REG)
11776         (compare
11777           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11778                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11779           (const_int 0)))
11780    (set (match_operand:DI 0 "register_operand" "=r")
11781         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11782   "TARGET_64BIT
11783    && (optimize_function_for_size_p (cfun)
11784        || !TARGET_PARTIAL_FLAG_REG_STALL
11785        || (operands[2] == const1_rtx
11786            && (TARGET_SHIFT1
11787                || TARGET_DOUBLE_WITH_ADD)))
11788    && ix86_match_ccmode (insn, CCGOCmode)
11789    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11790 {
11791   switch (get_attr_type (insn))
11792     {
11793     case TYPE_ALU:
11794       gcc_assert (operands[2] == const1_rtx);
11795       return "add{l}\t%k0, %k0";
11796
11797     default:
11798       if (REG_P (operands[2]))
11799         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11800       else if (operands[2] == const1_rtx
11801                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11802         return "sal{l}\t%k0";
11803       else
11804         return "sal{l}\t{%2, %k0|%k0, %2}";
11805     }
11806 }
11807   [(set (attr "type")
11808      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11809                      (const_int 0))
11810                  (match_operand 2 "const1_operand" ""))
11811               (const_string "alu")
11812            ]
11813            (const_string "ishift")))
11814    (set_attr "mode" "SI")])
11815
11816 (define_expand "ashlhi3"
11817   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11818         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11819                    (match_operand:QI 2 "nonmemory_operand" "")))]
11820   "TARGET_HIMODE_MATH"
11821   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11822
11823 (define_insn "*ashlhi3_1_lea"
11824   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11825         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11826                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11827    (clobber (reg:CC FLAGS_REG))]
11828   "!TARGET_PARTIAL_REG_STALL
11829    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11830 {
11831   switch (get_attr_type (insn))
11832     {
11833     case TYPE_LEA:
11834       return "#";
11835     case TYPE_ALU:
11836       gcc_assert (operands[2] == const1_rtx);
11837       return "add{w}\t%0, %0";
11838
11839     default:
11840       if (REG_P (operands[2]))
11841         return "sal{w}\t{%b2, %0|%0, %b2}";
11842       else if (operands[2] == const1_rtx
11843                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11844         return "sal{w}\t%0";
11845       else
11846         return "sal{w}\t{%2, %0|%0, %2}";
11847     }
11848 }
11849   [(set (attr "type")
11850      (cond [(eq_attr "alternative" "1")
11851               (const_string "lea")
11852             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11853                           (const_int 0))
11854                       (match_operand 0 "register_operand" ""))
11855                  (match_operand 2 "const1_operand" ""))
11856               (const_string "alu")
11857            ]
11858            (const_string "ishift")))
11859    (set_attr "mode" "HI,SI")])
11860
11861 (define_insn "*ashlhi3_1"
11862   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11863         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11864                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "TARGET_PARTIAL_REG_STALL
11867    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11868 {
11869   switch (get_attr_type (insn))
11870     {
11871     case TYPE_ALU:
11872       gcc_assert (operands[2] == const1_rtx);
11873       return "add{w}\t%0, %0";
11874
11875     default:
11876       if (REG_P (operands[2]))
11877         return "sal{w}\t{%b2, %0|%0, %b2}";
11878       else if (operands[2] == const1_rtx
11879                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11880         return "sal{w}\t%0";
11881       else
11882         return "sal{w}\t{%2, %0|%0, %2}";
11883     }
11884 }
11885   [(set (attr "type")
11886      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11887                           (const_int 0))
11888                       (match_operand 0 "register_operand" ""))
11889                  (match_operand 2 "const1_operand" ""))
11890               (const_string "alu")
11891            ]
11892            (const_string "ishift")))
11893    (set_attr "mode" "HI")])
11894
11895 ;; This pattern can't accept a variable shift count, since shifts by
11896 ;; zero don't affect the flags.  We assume that shifts by constant
11897 ;; zero are optimized away.
11898 (define_insn "*ashlhi3_cmp"
11899   [(set (reg FLAGS_REG)
11900         (compare
11901           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11902                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11903           (const_int 0)))
11904    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11905         (ashift:HI (match_dup 1) (match_dup 2)))]
11906   "(optimize_function_for_size_p (cfun)
11907     || !TARGET_PARTIAL_FLAG_REG_STALL
11908     || (operands[2] == const1_rtx
11909         && (TARGET_SHIFT1
11910             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11911    && ix86_match_ccmode (insn, CCGOCmode)
11912    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11913 {
11914   switch (get_attr_type (insn))
11915     {
11916     case TYPE_ALU:
11917       gcc_assert (operands[2] == const1_rtx);
11918       return "add{w}\t%0, %0";
11919
11920     default:
11921       if (REG_P (operands[2]))
11922         return "sal{w}\t{%b2, %0|%0, %b2}";
11923       else if (operands[2] == const1_rtx
11924                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11925         return "sal{w}\t%0";
11926       else
11927         return "sal{w}\t{%2, %0|%0, %2}";
11928     }
11929 }
11930   [(set (attr "type")
11931      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11932                           (const_int 0))
11933                       (match_operand 0 "register_operand" ""))
11934                  (match_operand 2 "const1_operand" ""))
11935               (const_string "alu")
11936            ]
11937            (const_string "ishift")))
11938    (set_attr "mode" "HI")])
11939
11940 (define_insn "*ashlhi3_cconly"
11941   [(set (reg FLAGS_REG)
11942         (compare
11943           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11944                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11945           (const_int 0)))
11946    (clobber (match_scratch:HI 0 "=r"))]
11947   "(optimize_function_for_size_p (cfun)
11948     || !TARGET_PARTIAL_FLAG_REG_STALL
11949     || (operands[2] == const1_rtx
11950         && (TARGET_SHIFT1
11951             || TARGET_DOUBLE_WITH_ADD)))
11952    && ix86_match_ccmode (insn, CCGOCmode)
11953    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11954 {
11955   switch (get_attr_type (insn))
11956     {
11957     case TYPE_ALU:
11958       gcc_assert (operands[2] == const1_rtx);
11959       return "add{w}\t%0, %0";
11960
11961     default:
11962       if (REG_P (operands[2]))
11963         return "sal{w}\t{%b2, %0|%0, %b2}";
11964       else if (operands[2] == const1_rtx
11965                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11966         return "sal{w}\t%0";
11967       else
11968         return "sal{w}\t{%2, %0|%0, %2}";
11969     }
11970 }
11971   [(set (attr "type")
11972      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11973                           (const_int 0))
11974                       (match_operand 0 "register_operand" ""))
11975                  (match_operand 2 "const1_operand" ""))
11976               (const_string "alu")
11977            ]
11978            (const_string "ishift")))
11979    (set_attr "mode" "HI")])
11980
11981 (define_expand "ashlqi3"
11982   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11983         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11984                    (match_operand:QI 2 "nonmemory_operand" "")))]
11985   "TARGET_QIMODE_MATH"
11986   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11987
11988 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11989
11990 (define_insn "*ashlqi3_1_lea"
11991   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11992         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11993                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11994    (clobber (reg:CC FLAGS_REG))]
11995   "!TARGET_PARTIAL_REG_STALL
11996    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11997 {
11998   switch (get_attr_type (insn))
11999     {
12000     case TYPE_LEA:
12001       return "#";
12002     case TYPE_ALU:
12003       gcc_assert (operands[2] == const1_rtx);
12004       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12005         return "add{l}\t%k0, %k0";
12006       else
12007         return "add{b}\t%0, %0";
12008
12009     default:
12010       if (REG_P (operands[2]))
12011         {
12012           if (get_attr_mode (insn) == MODE_SI)
12013             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12014           else
12015             return "sal{b}\t{%b2, %0|%0, %b2}";
12016         }
12017       else if (operands[2] == const1_rtx
12018                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12019         {
12020           if (get_attr_mode (insn) == MODE_SI)
12021             return "sal{l}\t%0";
12022           else
12023             return "sal{b}\t%0";
12024         }
12025       else
12026         {
12027           if (get_attr_mode (insn) == MODE_SI)
12028             return "sal{l}\t{%2, %k0|%k0, %2}";
12029           else
12030             return "sal{b}\t{%2, %0|%0, %2}";
12031         }
12032     }
12033 }
12034   [(set (attr "type")
12035      (cond [(eq_attr "alternative" "2")
12036               (const_string "lea")
12037             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12038                           (const_int 0))
12039                       (match_operand 0 "register_operand" ""))
12040                  (match_operand 2 "const1_operand" ""))
12041               (const_string "alu")
12042            ]
12043            (const_string "ishift")))
12044    (set_attr "mode" "QI,SI,SI")])
12045
12046 (define_insn "*ashlqi3_1"
12047   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
12048         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12049                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
12050    (clobber (reg:CC FLAGS_REG))]
12051   "TARGET_PARTIAL_REG_STALL
12052    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12053 {
12054   switch (get_attr_type (insn))
12055     {
12056     case TYPE_ALU:
12057       gcc_assert (operands[2] == const1_rtx);
12058       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12059         return "add{l}\t%k0, %k0";
12060       else
12061         return "add{b}\t%0, %0";
12062
12063     default:
12064       if (REG_P (operands[2]))
12065         {
12066           if (get_attr_mode (insn) == MODE_SI)
12067             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12068           else
12069             return "sal{b}\t{%b2, %0|%0, %b2}";
12070         }
12071       else if (operands[2] == const1_rtx
12072                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12073         {
12074           if (get_attr_mode (insn) == MODE_SI)
12075             return "sal{l}\t%0";
12076           else
12077             return "sal{b}\t%0";
12078         }
12079       else
12080         {
12081           if (get_attr_mode (insn) == MODE_SI)
12082             return "sal{l}\t{%2, %k0|%k0, %2}";
12083           else
12084             return "sal{b}\t{%2, %0|%0, %2}";
12085         }
12086     }
12087 }
12088   [(set (attr "type")
12089      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12090                           (const_int 0))
12091                       (match_operand 0 "register_operand" ""))
12092                  (match_operand 2 "const1_operand" ""))
12093               (const_string "alu")
12094            ]
12095            (const_string "ishift")))
12096    (set_attr "mode" "QI,SI")])
12097
12098 ;; This pattern can't accept a variable shift count, since shifts by
12099 ;; zero don't affect the flags.  We assume that shifts by constant
12100 ;; zero are optimized away.
12101 (define_insn "*ashlqi3_cmp"
12102   [(set (reg FLAGS_REG)
12103         (compare
12104           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12105                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12106           (const_int 0)))
12107    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12108         (ashift:QI (match_dup 1) (match_dup 2)))]
12109   "(optimize_function_for_size_p (cfun)
12110     || !TARGET_PARTIAL_FLAG_REG_STALL
12111     || (operands[2] == const1_rtx
12112         && (TARGET_SHIFT1
12113             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12114    && ix86_match_ccmode (insn, CCGOCmode)
12115    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12116 {
12117   switch (get_attr_type (insn))
12118     {
12119     case TYPE_ALU:
12120       gcc_assert (operands[2] == const1_rtx);
12121       return "add{b}\t%0, %0";
12122
12123     default:
12124       if (REG_P (operands[2]))
12125         return "sal{b}\t{%b2, %0|%0, %b2}";
12126       else if (operands[2] == const1_rtx
12127                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12128         return "sal{b}\t%0";
12129       else
12130         return "sal{b}\t{%2, %0|%0, %2}";
12131     }
12132 }
12133   [(set (attr "type")
12134      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12135                           (const_int 0))
12136                       (match_operand 0 "register_operand" ""))
12137                  (match_operand 2 "const1_operand" ""))
12138               (const_string "alu")
12139            ]
12140            (const_string "ishift")))
12141    (set_attr "mode" "QI")])
12142
12143 (define_insn "*ashlqi3_cconly"
12144   [(set (reg FLAGS_REG)
12145         (compare
12146           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12147                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12148           (const_int 0)))
12149    (clobber (match_scratch:QI 0 "=q"))]
12150   "(optimize_function_for_size_p (cfun)
12151     || !TARGET_PARTIAL_FLAG_REG_STALL
12152     || (operands[2] == const1_rtx
12153         && (TARGET_SHIFT1
12154             || TARGET_DOUBLE_WITH_ADD)))
12155    && ix86_match_ccmode (insn, CCGOCmode)
12156    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12157 {
12158   switch (get_attr_type (insn))
12159     {
12160     case TYPE_ALU:
12161       gcc_assert (operands[2] == const1_rtx);
12162       return "add{b}\t%0, %0";
12163
12164     default:
12165       if (REG_P (operands[2]))
12166         return "sal{b}\t{%b2, %0|%0, %b2}";
12167       else if (operands[2] == const1_rtx
12168                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12169         return "sal{b}\t%0";
12170       else
12171         return "sal{b}\t{%2, %0|%0, %2}";
12172     }
12173 }
12174   [(set (attr "type")
12175      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12176                           (const_int 0))
12177                       (match_operand 0 "register_operand" ""))
12178                  (match_operand 2 "const1_operand" ""))
12179               (const_string "alu")
12180            ]
12181            (const_string "ishift")))
12182    (set_attr "mode" "QI")])
12183
12184 ;; See comment above `ashldi3' about how this works.
12185
12186 (define_expand "ashrti3"
12187   [(set (match_operand:TI 0 "register_operand" "")
12188         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12189                      (match_operand:QI 2 "nonmemory_operand" "")))]
12190   "TARGET_64BIT"
12191   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12192
12193 (define_insn "*ashrti3_1"
12194   [(set (match_operand:TI 0 "register_operand" "=r")
12195         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12196                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12197    (clobber (reg:CC FLAGS_REG))]
12198   "TARGET_64BIT"
12199   "#"
12200   [(set_attr "type" "multi")])
12201
12202 (define_peephole2
12203   [(match_scratch:DI 3 "r")
12204    (parallel [(set (match_operand:TI 0 "register_operand" "")
12205                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12206                                 (match_operand:QI 2 "nonmemory_operand" "")))
12207               (clobber (reg:CC FLAGS_REG))])
12208    (match_dup 3)]
12209   "TARGET_64BIT"
12210   [(const_int 0)]
12211   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12212
12213 (define_split
12214   [(set (match_operand:TI 0 "register_operand" "")
12215         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12216                      (match_operand:QI 2 "nonmemory_operand" "")))
12217    (clobber (reg:CC FLAGS_REG))]
12218   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12219                     ? epilogue_completed : reload_completed)"
12220   [(const_int 0)]
12221   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12222
12223 (define_insn "x86_64_shrd"
12224   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12225         (ior:DI (ashiftrt:DI (match_dup 0)
12226                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12227                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12228                   (minus:QI (const_int 64) (match_dup 2)))))
12229    (clobber (reg:CC FLAGS_REG))]
12230   "TARGET_64BIT"
12231   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12232   [(set_attr "type" "ishift")
12233    (set_attr "prefix_0f" "1")
12234    (set_attr "mode" "DI")
12235    (set_attr "athlon_decode" "vector")
12236    (set_attr "amdfam10_decode" "vector")])
12237
12238 (define_expand "ashrdi3"
12239   [(set (match_operand:DI 0 "shiftdi_operand" "")
12240         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12241                      (match_operand:QI 2 "nonmemory_operand" "")))]
12242   ""
12243   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12244
12245 (define_expand "x86_64_shift_adj_3"
12246   [(use (match_operand:DI 0 "register_operand" ""))
12247    (use (match_operand:DI 1 "register_operand" ""))
12248    (use (match_operand:QI 2 "register_operand" ""))]
12249   ""
12250 {
12251   rtx label = gen_label_rtx ();
12252   rtx tmp;
12253
12254   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12255
12256   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12257   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12258   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12259                               gen_rtx_LABEL_REF (VOIDmode, label),
12260                               pc_rtx);
12261   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12262   JUMP_LABEL (tmp) = label;
12263
12264   emit_move_insn (operands[0], operands[1]);
12265   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12266
12267   emit_label (label);
12268   LABEL_NUSES (label) = 1;
12269
12270   DONE;
12271 })
12272
12273 (define_insn "ashrdi3_63_rex64"
12274   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12275         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12276                      (match_operand:DI 2 "const_int_operand" "i,i")))
12277    (clobber (reg:CC FLAGS_REG))]
12278   "TARGET_64BIT && INTVAL (operands[2]) == 63
12279    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12280    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12281   "@
12282    {cqto|cqo}
12283    sar{q}\t{%2, %0|%0, %2}"
12284   [(set_attr "type" "imovx,ishift")
12285    (set_attr "prefix_0f" "0,*")
12286    (set_attr "length_immediate" "0,*")
12287    (set_attr "modrm" "0,1")
12288    (set_attr "mode" "DI")])
12289
12290 (define_insn "*ashrdi3_1_one_bit_rex64"
12291   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12292         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12293                      (match_operand:QI 2 "const1_operand" "")))
12294    (clobber (reg:CC FLAGS_REG))]
12295   "TARGET_64BIT
12296    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12297    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12298   "sar{q}\t%0"
12299   [(set_attr "type" "ishift")
12300    (set (attr "length")
12301      (if_then_else (match_operand:DI 0 "register_operand" "")
12302         (const_string "2")
12303         (const_string "*")))])
12304
12305 (define_insn "*ashrdi3_1_rex64"
12306   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12307         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12308                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12309    (clobber (reg:CC FLAGS_REG))]
12310   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12311   "@
12312    sar{q}\t{%2, %0|%0, %2}
12313    sar{q}\t{%b2, %0|%0, %b2}"
12314   [(set_attr "type" "ishift")
12315    (set_attr "mode" "DI")])
12316
12317 ;; This pattern can't accept a variable shift count, since shifts by
12318 ;; zero don't affect the flags.  We assume that shifts by constant
12319 ;; zero are optimized away.
12320 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12321   [(set (reg FLAGS_REG)
12322         (compare
12323           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12324                        (match_operand:QI 2 "const1_operand" ""))
12325           (const_int 0)))
12326    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12327         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12328   "TARGET_64BIT
12329    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12330    && ix86_match_ccmode (insn, CCGOCmode)
12331    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12332   "sar{q}\t%0"
12333   [(set_attr "type" "ishift")
12334    (set (attr "length")
12335      (if_then_else (match_operand:DI 0 "register_operand" "")
12336         (const_string "2")
12337         (const_string "*")))])
12338
12339 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12340   [(set (reg FLAGS_REG)
12341         (compare
12342           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12343                        (match_operand:QI 2 "const1_operand" ""))
12344           (const_int 0)))
12345    (clobber (match_scratch:DI 0 "=r"))]
12346   "TARGET_64BIT
12347    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12348    && ix86_match_ccmode (insn, CCGOCmode)
12349    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12350   "sar{q}\t%0"
12351   [(set_attr "type" "ishift")
12352    (set_attr "length" "2")])
12353
12354 ;; This pattern can't accept a variable shift count, since shifts by
12355 ;; zero don't affect the flags.  We assume that shifts by constant
12356 ;; zero are optimized away.
12357 (define_insn "*ashrdi3_cmp_rex64"
12358   [(set (reg FLAGS_REG)
12359         (compare
12360           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12361                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12362           (const_int 0)))
12363    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12364         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12365   "TARGET_64BIT
12366    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12367    && ix86_match_ccmode (insn, CCGOCmode)
12368    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12369   "sar{q}\t{%2, %0|%0, %2}"
12370   [(set_attr "type" "ishift")
12371    (set_attr "mode" "DI")])
12372
12373 (define_insn "*ashrdi3_cconly_rex64"
12374   [(set (reg FLAGS_REG)
12375         (compare
12376           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12377                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12378           (const_int 0)))
12379    (clobber (match_scratch:DI 0 "=r"))]
12380   "TARGET_64BIT
12381    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12382    && ix86_match_ccmode (insn, CCGOCmode)
12383    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12384   "sar{q}\t{%2, %0|%0, %2}"
12385   [(set_attr "type" "ishift")
12386    (set_attr "mode" "DI")])
12387
12388 (define_insn "*ashrdi3_1"
12389   [(set (match_operand:DI 0 "register_operand" "=r")
12390         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12391                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12392    (clobber (reg:CC FLAGS_REG))]
12393   "!TARGET_64BIT"
12394   "#"
12395   [(set_attr "type" "multi")])
12396
12397 ;; By default we don't ask for a scratch register, because when DImode
12398 ;; values are manipulated, registers are already at a premium.  But if
12399 ;; we have one handy, we won't turn it away.
12400 (define_peephole2
12401   [(match_scratch:SI 3 "r")
12402    (parallel [(set (match_operand:DI 0 "register_operand" "")
12403                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12404                                 (match_operand:QI 2 "nonmemory_operand" "")))
12405               (clobber (reg:CC FLAGS_REG))])
12406    (match_dup 3)]
12407   "!TARGET_64BIT && TARGET_CMOVE"
12408   [(const_int 0)]
12409   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12410
12411 (define_split
12412   [(set (match_operand:DI 0 "register_operand" "")
12413         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12414                      (match_operand:QI 2 "nonmemory_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12417                      ? epilogue_completed : reload_completed)"
12418   [(const_int 0)]
12419   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12420
12421 (define_insn "x86_shrd"
12422   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12423         (ior:SI (ashiftrt:SI (match_dup 0)
12424                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12425                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12426                   (minus:QI (const_int 32) (match_dup 2)))))
12427    (clobber (reg:CC FLAGS_REG))]
12428   ""
12429   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12430   [(set_attr "type" "ishift")
12431    (set_attr "prefix_0f" "1")
12432    (set_attr "pent_pair" "np")
12433    (set_attr "mode" "SI")])
12434
12435 (define_expand "x86_shift_adj_3"
12436   [(use (match_operand:SI 0 "register_operand" ""))
12437    (use (match_operand:SI 1 "register_operand" ""))
12438    (use (match_operand:QI 2 "register_operand" ""))]
12439   ""
12440 {
12441   rtx label = gen_label_rtx ();
12442   rtx tmp;
12443
12444   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12445
12446   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12447   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12448   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12449                               gen_rtx_LABEL_REF (VOIDmode, label),
12450                               pc_rtx);
12451   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12452   JUMP_LABEL (tmp) = label;
12453
12454   emit_move_insn (operands[0], operands[1]);
12455   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12456
12457   emit_label (label);
12458   LABEL_NUSES (label) = 1;
12459
12460   DONE;
12461 })
12462
12463 (define_expand "ashrsi3_31"
12464   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12465                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12466                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12467               (clobber (reg:CC FLAGS_REG))])]
12468   "")
12469
12470 (define_insn "*ashrsi3_31"
12471   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12472         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12473                      (match_operand:SI 2 "const_int_operand" "i,i")))
12474    (clobber (reg:CC FLAGS_REG))]
12475   "INTVAL (operands[2]) == 31
12476    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12477    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12478   "@
12479    {cltd|cdq}
12480    sar{l}\t{%2, %0|%0, %2}"
12481   [(set_attr "type" "imovx,ishift")
12482    (set_attr "prefix_0f" "0,*")
12483    (set_attr "length_immediate" "0,*")
12484    (set_attr "modrm" "0,1")
12485    (set_attr "mode" "SI")])
12486
12487 (define_insn "*ashrsi3_31_zext"
12488   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12489         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12490                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12491    (clobber (reg:CC FLAGS_REG))]
12492   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12493    && INTVAL (operands[2]) == 31
12494    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12495   "@
12496    {cltd|cdq}
12497    sar{l}\t{%2, %k0|%k0, %2}"
12498   [(set_attr "type" "imovx,ishift")
12499    (set_attr "prefix_0f" "0,*")
12500    (set_attr "length_immediate" "0,*")
12501    (set_attr "modrm" "0,1")
12502    (set_attr "mode" "SI")])
12503
12504 (define_expand "ashrsi3"
12505   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12506         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12507                      (match_operand:QI 2 "nonmemory_operand" "")))]
12508   ""
12509   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12510
12511 (define_insn "*ashrsi3_1_one_bit"
12512   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12514                      (match_operand:QI 2 "const1_operand" "")))
12515    (clobber (reg:CC FLAGS_REG))]
12516   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12517    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12518   "sar{l}\t%0"
12519   [(set_attr "type" "ishift")
12520    (set (attr "length")
12521      (if_then_else (match_operand:SI 0 "register_operand" "")
12522         (const_string "2")
12523         (const_string "*")))])
12524
12525 (define_insn "*ashrsi3_1_one_bit_zext"
12526   [(set (match_operand:DI 0 "register_operand" "=r")
12527         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12528                                      (match_operand:QI 2 "const1_operand" ""))))
12529    (clobber (reg:CC FLAGS_REG))]
12530   "TARGET_64BIT
12531    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12532    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12533   "sar{l}\t%k0"
12534   [(set_attr "type" "ishift")
12535    (set_attr "length" "2")])
12536
12537 (define_insn "*ashrsi3_1"
12538   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12539         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12540                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12541    (clobber (reg:CC FLAGS_REG))]
12542   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12543   "@
12544    sar{l}\t{%2, %0|%0, %2}
12545    sar{l}\t{%b2, %0|%0, %b2}"
12546   [(set_attr "type" "ishift")
12547    (set_attr "mode" "SI")])
12548
12549 (define_insn "*ashrsi3_1_zext"
12550   [(set (match_operand:DI 0 "register_operand" "=r,r")
12551         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12552                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12553    (clobber (reg:CC FLAGS_REG))]
12554   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12555   "@
12556    sar{l}\t{%2, %k0|%k0, %2}
12557    sar{l}\t{%b2, %k0|%k0, %b2}"
12558   [(set_attr "type" "ishift")
12559    (set_attr "mode" "SI")])
12560
12561 ;; This pattern can't accept a variable shift count, since shifts by
12562 ;; zero don't affect the flags.  We assume that shifts by constant
12563 ;; zero are optimized away.
12564 (define_insn "*ashrsi3_one_bit_cmp"
12565   [(set (reg FLAGS_REG)
12566         (compare
12567           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12568                        (match_operand:QI 2 "const1_operand" ""))
12569           (const_int 0)))
12570    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12571         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12572   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12573    && ix86_match_ccmode (insn, CCGOCmode)
12574    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12575   "sar{l}\t%0"
12576   [(set_attr "type" "ishift")
12577    (set (attr "length")
12578      (if_then_else (match_operand:SI 0 "register_operand" "")
12579         (const_string "2")
12580         (const_string "*")))])
12581
12582 (define_insn "*ashrsi3_one_bit_cconly"
12583   [(set (reg FLAGS_REG)
12584         (compare
12585           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12586                        (match_operand:QI 2 "const1_operand" ""))
12587           (const_int 0)))
12588    (clobber (match_scratch:SI 0 "=r"))]
12589   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12590    && ix86_match_ccmode (insn, CCGOCmode)
12591    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12592   "sar{l}\t%0"
12593   [(set_attr "type" "ishift")
12594    (set_attr "length" "2")])
12595
12596 (define_insn "*ashrsi3_one_bit_cmp_zext"
12597   [(set (reg FLAGS_REG)
12598         (compare
12599           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12600                        (match_operand:QI 2 "const1_operand" ""))
12601           (const_int 0)))
12602    (set (match_operand:DI 0 "register_operand" "=r")
12603         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12604   "TARGET_64BIT
12605    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12606    && ix86_match_ccmode (insn, CCmode)
12607    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12608   "sar{l}\t%k0"
12609   [(set_attr "type" "ishift")
12610    (set_attr "length" "2")])
12611
12612 ;; This pattern can't accept a variable shift count, since shifts by
12613 ;; zero don't affect the flags.  We assume that shifts by constant
12614 ;; zero are optimized away.
12615 (define_insn "*ashrsi3_cmp"
12616   [(set (reg FLAGS_REG)
12617         (compare
12618           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12619                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12620           (const_int 0)))
12621    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12622         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12623   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12624    && ix86_match_ccmode (insn, CCGOCmode)
12625    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12626   "sar{l}\t{%2, %0|%0, %2}"
12627   [(set_attr "type" "ishift")
12628    (set_attr "mode" "SI")])
12629
12630 (define_insn "*ashrsi3_cconly"
12631   [(set (reg FLAGS_REG)
12632         (compare
12633           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12634                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12635           (const_int 0)))
12636    (clobber (match_scratch:SI 0 "=r"))]
12637   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12638    && ix86_match_ccmode (insn, CCGOCmode)
12639    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12640   "sar{l}\t{%2, %0|%0, %2}"
12641   [(set_attr "type" "ishift")
12642    (set_attr "mode" "SI")])
12643
12644 (define_insn "*ashrsi3_cmp_zext"
12645   [(set (reg FLAGS_REG)
12646         (compare
12647           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12648                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12649           (const_int 0)))
12650    (set (match_operand:DI 0 "register_operand" "=r")
12651         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12652   "TARGET_64BIT
12653    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12654    && ix86_match_ccmode (insn, CCGOCmode)
12655    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12656   "sar{l}\t{%2, %k0|%k0, %2}"
12657   [(set_attr "type" "ishift")
12658    (set_attr "mode" "SI")])
12659
12660 (define_expand "ashrhi3"
12661   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12662         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12663                      (match_operand:QI 2 "nonmemory_operand" "")))]
12664   "TARGET_HIMODE_MATH"
12665   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12666
12667 (define_insn "*ashrhi3_1_one_bit"
12668   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12669         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12670                      (match_operand:QI 2 "const1_operand" "")))
12671    (clobber (reg:CC FLAGS_REG))]
12672   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12673    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12674   "sar{w}\t%0"
12675   [(set_attr "type" "ishift")
12676    (set (attr "length")
12677      (if_then_else (match_operand 0 "register_operand" "")
12678         (const_string "2")
12679         (const_string "*")))])
12680
12681 (define_insn "*ashrhi3_1"
12682   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12683         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12684                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12685    (clobber (reg:CC FLAGS_REG))]
12686   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12687   "@
12688    sar{w}\t{%2, %0|%0, %2}
12689    sar{w}\t{%b2, %0|%0, %b2}"
12690   [(set_attr "type" "ishift")
12691    (set_attr "mode" "HI")])
12692
12693 ;; This pattern can't accept a variable shift count, since shifts by
12694 ;; zero don't affect the flags.  We assume that shifts by constant
12695 ;; zero are optimized away.
12696 (define_insn "*ashrhi3_one_bit_cmp"
12697   [(set (reg FLAGS_REG)
12698         (compare
12699           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12700                        (match_operand:QI 2 "const1_operand" ""))
12701           (const_int 0)))
12702    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12703         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12704   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12705    && ix86_match_ccmode (insn, CCGOCmode)
12706    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12707   "sar{w}\t%0"
12708   [(set_attr "type" "ishift")
12709    (set (attr "length")
12710      (if_then_else (match_operand 0 "register_operand" "")
12711         (const_string "2")
12712         (const_string "*")))])
12713
12714 (define_insn "*ashrhi3_one_bit_cconly"
12715   [(set (reg FLAGS_REG)
12716         (compare
12717           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12718                        (match_operand:QI 2 "const1_operand" ""))
12719           (const_int 0)))
12720    (clobber (match_scratch:HI 0 "=r"))]
12721   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12722    && ix86_match_ccmode (insn, CCGOCmode)
12723    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12724   "sar{w}\t%0"
12725   [(set_attr "type" "ishift")
12726    (set_attr "length" "2")])
12727
12728 ;; This pattern can't accept a variable shift count, since shifts by
12729 ;; zero don't affect the flags.  We assume that shifts by constant
12730 ;; zero are optimized away.
12731 (define_insn "*ashrhi3_cmp"
12732   [(set (reg FLAGS_REG)
12733         (compare
12734           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12735                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12736           (const_int 0)))
12737    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12738         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12739   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12740    && ix86_match_ccmode (insn, CCGOCmode)
12741    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12742   "sar{w}\t{%2, %0|%0, %2}"
12743   [(set_attr "type" "ishift")
12744    (set_attr "mode" "HI")])
12745
12746 (define_insn "*ashrhi3_cconly"
12747   [(set (reg FLAGS_REG)
12748         (compare
12749           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12750                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12751           (const_int 0)))
12752    (clobber (match_scratch:HI 0 "=r"))]
12753   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12754    && ix86_match_ccmode (insn, CCGOCmode)
12755    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12756   "sar{w}\t{%2, %0|%0, %2}"
12757   [(set_attr "type" "ishift")
12758    (set_attr "mode" "HI")])
12759
12760 (define_expand "ashrqi3"
12761   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12762         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12763                      (match_operand:QI 2 "nonmemory_operand" "")))]
12764   "TARGET_QIMODE_MATH"
12765   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12766
12767 (define_insn "*ashrqi3_1_one_bit"
12768   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12769         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12770                      (match_operand:QI 2 "const1_operand" "")))
12771    (clobber (reg:CC FLAGS_REG))]
12772   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12773    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12774   "sar{b}\t%0"
12775   [(set_attr "type" "ishift")
12776    (set (attr "length")
12777      (if_then_else (match_operand 0 "register_operand" "")
12778         (const_string "2")
12779         (const_string "*")))])
12780
12781 (define_insn "*ashrqi3_1_one_bit_slp"
12782   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12783         (ashiftrt:QI (match_dup 0)
12784                      (match_operand:QI 1 "const1_operand" "")))
12785    (clobber (reg:CC FLAGS_REG))]
12786   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12787    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12788    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12789   "sar{b}\t%0"
12790   [(set_attr "type" "ishift1")
12791    (set (attr "length")
12792      (if_then_else (match_operand 0 "register_operand" "")
12793         (const_string "2")
12794         (const_string "*")))])
12795
12796 (define_insn "*ashrqi3_1"
12797   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12798         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12799                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12800    (clobber (reg:CC FLAGS_REG))]
12801   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12802   "@
12803    sar{b}\t{%2, %0|%0, %2}
12804    sar{b}\t{%b2, %0|%0, %b2}"
12805   [(set_attr "type" "ishift")
12806    (set_attr "mode" "QI")])
12807
12808 (define_insn "*ashrqi3_1_slp"
12809   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12810         (ashiftrt:QI (match_dup 0)
12811                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12812    (clobber (reg:CC FLAGS_REG))]
12813   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12814    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12815   "@
12816    sar{b}\t{%1, %0|%0, %1}
12817    sar{b}\t{%b1, %0|%0, %b1}"
12818   [(set_attr "type" "ishift1")
12819    (set_attr "mode" "QI")])
12820
12821 ;; This pattern can't accept a variable shift count, since shifts by
12822 ;; zero don't affect the flags.  We assume that shifts by constant
12823 ;; zero are optimized away.
12824 (define_insn "*ashrqi3_one_bit_cmp"
12825   [(set (reg FLAGS_REG)
12826         (compare
12827           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12828                        (match_operand:QI 2 "const1_operand" "I"))
12829           (const_int 0)))
12830    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12831         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12832   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12833    && ix86_match_ccmode (insn, CCGOCmode)
12834    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12835   "sar{b}\t%0"
12836   [(set_attr "type" "ishift")
12837    (set (attr "length")
12838      (if_then_else (match_operand 0 "register_operand" "")
12839         (const_string "2")
12840         (const_string "*")))])
12841
12842 (define_insn "*ashrqi3_one_bit_cconly"
12843   [(set (reg FLAGS_REG)
12844         (compare
12845           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12846                        (match_operand:QI 2 "const1_operand" ""))
12847           (const_int 0)))
12848    (clobber (match_scratch:QI 0 "=q"))]
12849   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12850    && ix86_match_ccmode (insn, CCGOCmode)
12851    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12852   "sar{b}\t%0"
12853   [(set_attr "type" "ishift")
12854    (set_attr "length" "2")])
12855
12856 ;; This pattern can't accept a variable shift count, since shifts by
12857 ;; zero don't affect the flags.  We assume that shifts by constant
12858 ;; zero are optimized away.
12859 (define_insn "*ashrqi3_cmp"
12860   [(set (reg FLAGS_REG)
12861         (compare
12862           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12863                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12864           (const_int 0)))
12865    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12866         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12867   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12868    && ix86_match_ccmode (insn, CCGOCmode)
12869    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12870   "sar{b}\t{%2, %0|%0, %2}"
12871   [(set_attr "type" "ishift")
12872    (set_attr "mode" "QI")])
12873
12874 (define_insn "*ashrqi3_cconly"
12875   [(set (reg FLAGS_REG)
12876         (compare
12877           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12878                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12879           (const_int 0)))
12880    (clobber (match_scratch:QI 0 "=q"))]
12881   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12882    && ix86_match_ccmode (insn, CCGOCmode)
12883    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12884   "sar{b}\t{%2, %0|%0, %2}"
12885   [(set_attr "type" "ishift")
12886    (set_attr "mode" "QI")])
12887
12888 \f
12889 ;; Logical shift instructions
12890
12891 ;; See comment above `ashldi3' about how this works.
12892
12893 (define_expand "lshrti3"
12894   [(set (match_operand:TI 0 "register_operand" "")
12895         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12896                      (match_operand:QI 2 "nonmemory_operand" "")))]
12897   "TARGET_64BIT"
12898   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12899
12900 ;; This pattern must be defined before *lshrti3_1 to prevent
12901 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12902
12903 (define_insn "*avx_lshrti3"
12904   [(set (match_operand:TI 0 "register_operand" "=x")
12905         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12906                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12907   "TARGET_AVX"
12908 {
12909   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12910   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12911 }
12912   [(set_attr "type" "sseishft")
12913    (set_attr "prefix" "vex")
12914    (set_attr "mode" "TI")])
12915
12916 (define_insn "sse2_lshrti3"
12917   [(set (match_operand:TI 0 "register_operand" "=x")
12918         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12919                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12920   "TARGET_SSE2"
12921 {
12922   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12923   return "psrldq\t{%2, %0|%0, %2}";
12924 }
12925   [(set_attr "type" "sseishft")
12926    (set_attr "prefix_data16" "1")
12927    (set_attr "mode" "TI")])
12928
12929 (define_insn "*lshrti3_1"
12930   [(set (match_operand:TI 0 "register_operand" "=r")
12931         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12932                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12933    (clobber (reg:CC FLAGS_REG))]
12934   "TARGET_64BIT"
12935   "#"
12936   [(set_attr "type" "multi")])
12937
12938 (define_peephole2
12939   [(match_scratch:DI 3 "r")
12940    (parallel [(set (match_operand:TI 0 "register_operand" "")
12941                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12942                                 (match_operand:QI 2 "nonmemory_operand" "")))
12943               (clobber (reg:CC FLAGS_REG))])
12944    (match_dup 3)]
12945   "TARGET_64BIT"
12946   [(const_int 0)]
12947   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12948
12949 (define_split
12950   [(set (match_operand:TI 0 "register_operand" "")
12951         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12952                      (match_operand:QI 2 "nonmemory_operand" "")))
12953    (clobber (reg:CC FLAGS_REG))]
12954   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12955                     ? epilogue_completed : reload_completed)"
12956   [(const_int 0)]
12957   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12958
12959 (define_expand "lshrdi3"
12960   [(set (match_operand:DI 0 "shiftdi_operand" "")
12961         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12962                      (match_operand:QI 2 "nonmemory_operand" "")))]
12963   ""
12964   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12965
12966 (define_insn "*lshrdi3_1_one_bit_rex64"
12967   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12968         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12969                      (match_operand:QI 2 "const1_operand" "")))
12970    (clobber (reg:CC FLAGS_REG))]
12971   "TARGET_64BIT
12972    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12973    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12974   "shr{q}\t%0"
12975   [(set_attr "type" "ishift")
12976    (set (attr "length")
12977      (if_then_else (match_operand:DI 0 "register_operand" "")
12978         (const_string "2")
12979         (const_string "*")))])
12980
12981 (define_insn "*lshrdi3_1_rex64"
12982   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12983         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12984                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12985    (clobber (reg:CC FLAGS_REG))]
12986   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12987   "@
12988    shr{q}\t{%2, %0|%0, %2}
12989    shr{q}\t{%b2, %0|%0, %b2}"
12990   [(set_attr "type" "ishift")
12991    (set_attr "mode" "DI")])
12992
12993 ;; This pattern can't accept a variable shift count, since shifts by
12994 ;; zero don't affect the flags.  We assume that shifts by constant
12995 ;; zero are optimized away.
12996 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12997   [(set (reg FLAGS_REG)
12998         (compare
12999           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13000                        (match_operand:QI 2 "const1_operand" ""))
13001           (const_int 0)))
13002    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13003         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13004   "TARGET_64BIT
13005    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13006    && ix86_match_ccmode (insn, CCGOCmode)
13007    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13008   "shr{q}\t%0"
13009   [(set_attr "type" "ishift")
13010    (set (attr "length")
13011      (if_then_else (match_operand:DI 0 "register_operand" "")
13012         (const_string "2")
13013         (const_string "*")))])
13014
13015 (define_insn "*lshrdi3_cconly_one_bit_rex64"
13016   [(set (reg FLAGS_REG)
13017         (compare
13018           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13019                        (match_operand:QI 2 "const1_operand" ""))
13020           (const_int 0)))
13021    (clobber (match_scratch:DI 0 "=r"))]
13022   "TARGET_64BIT
13023    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13024    && ix86_match_ccmode (insn, CCGOCmode)
13025    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13026   "shr{q}\t%0"
13027   [(set_attr "type" "ishift")
13028    (set_attr "length" "2")])
13029
13030 ;; This pattern can't accept a variable shift count, since shifts by
13031 ;; zero don't affect the flags.  We assume that shifts by constant
13032 ;; zero are optimized away.
13033 (define_insn "*lshrdi3_cmp_rex64"
13034   [(set (reg FLAGS_REG)
13035         (compare
13036           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13037                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
13038           (const_int 0)))
13039    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13040         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13041   "TARGET_64BIT
13042    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13043    && ix86_match_ccmode (insn, CCGOCmode)
13044    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13045   "shr{q}\t{%2, %0|%0, %2}"
13046   [(set_attr "type" "ishift")
13047    (set_attr "mode" "DI")])
13048
13049 (define_insn "*lshrdi3_cconly_rex64"
13050   [(set (reg FLAGS_REG)
13051         (compare
13052           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13053                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
13054           (const_int 0)))
13055    (clobber (match_scratch:DI 0 "=r"))]
13056   "TARGET_64BIT
13057    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13058    && ix86_match_ccmode (insn, CCGOCmode)
13059    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13060   "shr{q}\t{%2, %0|%0, %2}"
13061   [(set_attr "type" "ishift")
13062    (set_attr "mode" "DI")])
13063
13064 (define_insn "*lshrdi3_1"
13065   [(set (match_operand:DI 0 "register_operand" "=r")
13066         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13067                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
13068    (clobber (reg:CC FLAGS_REG))]
13069   "!TARGET_64BIT"
13070   "#"
13071   [(set_attr "type" "multi")])
13072
13073 ;; By default we don't ask for a scratch register, because when DImode
13074 ;; values are manipulated, registers are already at a premium.  But if
13075 ;; we have one handy, we won't turn it away.
13076 (define_peephole2
13077   [(match_scratch:SI 3 "r")
13078    (parallel [(set (match_operand:DI 0 "register_operand" "")
13079                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13080                                 (match_operand:QI 2 "nonmemory_operand" "")))
13081               (clobber (reg:CC FLAGS_REG))])
13082    (match_dup 3)]
13083   "!TARGET_64BIT && TARGET_CMOVE"
13084   [(const_int 0)]
13085   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13086
13087 (define_split
13088   [(set (match_operand:DI 0 "register_operand" "")
13089         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13090                      (match_operand:QI 2 "nonmemory_operand" "")))
13091    (clobber (reg:CC FLAGS_REG))]
13092   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13093                      ? epilogue_completed : reload_completed)"
13094   [(const_int 0)]
13095   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13096
13097 (define_expand "lshrsi3"
13098   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13099         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13100                      (match_operand:QI 2 "nonmemory_operand" "")))]
13101   ""
13102   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13103
13104 (define_insn "*lshrsi3_1_one_bit"
13105   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13106         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13107                      (match_operand:QI 2 "const1_operand" "")))
13108    (clobber (reg:CC FLAGS_REG))]
13109   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13110    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13111   "shr{l}\t%0"
13112   [(set_attr "type" "ishift")
13113    (set (attr "length")
13114      (if_then_else (match_operand:SI 0 "register_operand" "")
13115         (const_string "2")
13116         (const_string "*")))])
13117
13118 (define_insn "*lshrsi3_1_one_bit_zext"
13119   [(set (match_operand:DI 0 "register_operand" "=r")
13120         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13121                      (match_operand:QI 2 "const1_operand" "")))
13122    (clobber (reg:CC FLAGS_REG))]
13123   "TARGET_64BIT
13124    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13125    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13126   "shr{l}\t%k0"
13127   [(set_attr "type" "ishift")
13128    (set_attr "length" "2")])
13129
13130 (define_insn "*lshrsi3_1"
13131   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13132         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13133                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13134    (clobber (reg:CC FLAGS_REG))]
13135   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13136   "@
13137    shr{l}\t{%2, %0|%0, %2}
13138    shr{l}\t{%b2, %0|%0, %b2}"
13139   [(set_attr "type" "ishift")
13140    (set_attr "mode" "SI")])
13141
13142 (define_insn "*lshrsi3_1_zext"
13143   [(set (match_operand:DI 0 "register_operand" "=r,r")
13144         (zero_extend:DI
13145           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13146                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13147    (clobber (reg:CC FLAGS_REG))]
13148   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13149   "@
13150    shr{l}\t{%2, %k0|%k0, %2}
13151    shr{l}\t{%b2, %k0|%k0, %b2}"
13152   [(set_attr "type" "ishift")
13153    (set_attr "mode" "SI")])
13154
13155 ;; This pattern can't accept a variable shift count, since shifts by
13156 ;; zero don't affect the flags.  We assume that shifts by constant
13157 ;; zero are optimized away.
13158 (define_insn "*lshrsi3_one_bit_cmp"
13159   [(set (reg FLAGS_REG)
13160         (compare
13161           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13162                        (match_operand:QI 2 "const1_operand" ""))
13163           (const_int 0)))
13164    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13165         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13166   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13167    && ix86_match_ccmode (insn, CCGOCmode)
13168    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13169   "shr{l}\t%0"
13170   [(set_attr "type" "ishift")
13171    (set (attr "length")
13172      (if_then_else (match_operand:SI 0 "register_operand" "")
13173         (const_string "2")
13174         (const_string "*")))])
13175
13176 (define_insn "*lshrsi3_one_bit_cconly"
13177   [(set (reg FLAGS_REG)
13178         (compare
13179           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13180                        (match_operand:QI 2 "const1_operand" ""))
13181           (const_int 0)))
13182    (clobber (match_scratch:SI 0 "=r"))]
13183   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13184    && ix86_match_ccmode (insn, CCGOCmode)
13185    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13186   "shr{l}\t%0"
13187   [(set_attr "type" "ishift")
13188    (set_attr "length" "2")])
13189
13190 (define_insn "*lshrsi3_cmp_one_bit_zext"
13191   [(set (reg FLAGS_REG)
13192         (compare
13193           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13194                        (match_operand:QI 2 "const1_operand" ""))
13195           (const_int 0)))
13196    (set (match_operand:DI 0 "register_operand" "=r")
13197         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13198   "TARGET_64BIT
13199    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13200    && ix86_match_ccmode (insn, CCGOCmode)
13201    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13202   "shr{l}\t%k0"
13203   [(set_attr "type" "ishift")
13204    (set_attr "length" "2")])
13205
13206 ;; This pattern can't accept a variable shift count, since shifts by
13207 ;; zero don't affect the flags.  We assume that shifts by constant
13208 ;; zero are optimized away.
13209 (define_insn "*lshrsi3_cmp"
13210   [(set (reg FLAGS_REG)
13211         (compare
13212           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13213                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13214           (const_int 0)))
13215    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13216         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13217   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13218    && ix86_match_ccmode (insn, CCGOCmode)
13219    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13220   "shr{l}\t{%2, %0|%0, %2}"
13221   [(set_attr "type" "ishift")
13222    (set_attr "mode" "SI")])
13223
13224 (define_insn "*lshrsi3_cconly"
13225   [(set (reg FLAGS_REG)
13226       (compare
13227         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13228                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13229         (const_int 0)))
13230    (clobber (match_scratch:SI 0 "=r"))]
13231   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13232    && ix86_match_ccmode (insn, CCGOCmode)
13233    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13234   "shr{l}\t{%2, %0|%0, %2}"
13235   [(set_attr "type" "ishift")
13236    (set_attr "mode" "SI")])
13237
13238 (define_insn "*lshrsi3_cmp_zext"
13239   [(set (reg FLAGS_REG)
13240         (compare
13241           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13242                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13243           (const_int 0)))
13244    (set (match_operand:DI 0 "register_operand" "=r")
13245         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13246   "TARGET_64BIT
13247    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13248    && ix86_match_ccmode (insn, CCGOCmode)
13249    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13250   "shr{l}\t{%2, %k0|%k0, %2}"
13251   [(set_attr "type" "ishift")
13252    (set_attr "mode" "SI")])
13253
13254 (define_expand "lshrhi3"
13255   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13256         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13257                      (match_operand:QI 2 "nonmemory_operand" "")))]
13258   "TARGET_HIMODE_MATH"
13259   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13260
13261 (define_insn "*lshrhi3_1_one_bit"
13262   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13263         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13264                      (match_operand:QI 2 "const1_operand" "")))
13265    (clobber (reg:CC FLAGS_REG))]
13266   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13267    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13268   "shr{w}\t%0"
13269   [(set_attr "type" "ishift")
13270    (set (attr "length")
13271      (if_then_else (match_operand 0 "register_operand" "")
13272         (const_string "2")
13273         (const_string "*")))])
13274
13275 (define_insn "*lshrhi3_1"
13276   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13277         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13278                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13279    (clobber (reg:CC FLAGS_REG))]
13280   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13281   "@
13282    shr{w}\t{%2, %0|%0, %2}
13283    shr{w}\t{%b2, %0|%0, %b2}"
13284   [(set_attr "type" "ishift")
13285    (set_attr "mode" "HI")])
13286
13287 ;; This pattern can't accept a variable shift count, since shifts by
13288 ;; zero don't affect the flags.  We assume that shifts by constant
13289 ;; zero are optimized away.
13290 (define_insn "*lshrhi3_one_bit_cmp"
13291   [(set (reg FLAGS_REG)
13292         (compare
13293           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13294                        (match_operand:QI 2 "const1_operand" ""))
13295           (const_int 0)))
13296    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13297         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13298   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13299    && ix86_match_ccmode (insn, CCGOCmode)
13300    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13301   "shr{w}\t%0"
13302   [(set_attr "type" "ishift")
13303    (set (attr "length")
13304      (if_then_else (match_operand:SI 0 "register_operand" "")
13305         (const_string "2")
13306         (const_string "*")))])
13307
13308 (define_insn "*lshrhi3_one_bit_cconly"
13309   [(set (reg FLAGS_REG)
13310         (compare
13311           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13312                        (match_operand:QI 2 "const1_operand" ""))
13313           (const_int 0)))
13314    (clobber (match_scratch:HI 0 "=r"))]
13315   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13316    && ix86_match_ccmode (insn, CCGOCmode)
13317    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13318   "shr{w}\t%0"
13319   [(set_attr "type" "ishift")
13320    (set_attr "length" "2")])
13321
13322 ;; This pattern can't accept a variable shift count, since shifts by
13323 ;; zero don't affect the flags.  We assume that shifts by constant
13324 ;; zero are optimized away.
13325 (define_insn "*lshrhi3_cmp"
13326   [(set (reg FLAGS_REG)
13327         (compare
13328           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13329                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13330           (const_int 0)))
13331    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13332         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13333   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13334    && ix86_match_ccmode (insn, CCGOCmode)
13335    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13336   "shr{w}\t{%2, %0|%0, %2}"
13337   [(set_attr "type" "ishift")
13338    (set_attr "mode" "HI")])
13339
13340 (define_insn "*lshrhi3_cconly"
13341   [(set (reg FLAGS_REG)
13342         (compare
13343           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13344                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13345           (const_int 0)))
13346    (clobber (match_scratch:HI 0 "=r"))]
13347   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13348    && ix86_match_ccmode (insn, CCGOCmode)
13349    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13350   "shr{w}\t{%2, %0|%0, %2}"
13351   [(set_attr "type" "ishift")
13352    (set_attr "mode" "HI")])
13353
13354 (define_expand "lshrqi3"
13355   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13356         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13357                      (match_operand:QI 2 "nonmemory_operand" "")))]
13358   "TARGET_QIMODE_MATH"
13359   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13360
13361 (define_insn "*lshrqi3_1_one_bit"
13362   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13363         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13364                      (match_operand:QI 2 "const1_operand" "")))
13365    (clobber (reg:CC FLAGS_REG))]
13366   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13367    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13368   "shr{b}\t%0"
13369   [(set_attr "type" "ishift")
13370    (set (attr "length")
13371      (if_then_else (match_operand 0 "register_operand" "")
13372         (const_string "2")
13373         (const_string "*")))])
13374
13375 (define_insn "*lshrqi3_1_one_bit_slp"
13376   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13377         (lshiftrt:QI (match_dup 0)
13378                      (match_operand:QI 1 "const1_operand" "")))
13379    (clobber (reg:CC FLAGS_REG))]
13380   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13381    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13382   "shr{b}\t%0"
13383   [(set_attr "type" "ishift1")
13384    (set (attr "length")
13385      (if_then_else (match_operand 0 "register_operand" "")
13386         (const_string "2")
13387         (const_string "*")))])
13388
13389 (define_insn "*lshrqi3_1"
13390   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13391         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13392                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13393    (clobber (reg:CC FLAGS_REG))]
13394   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13395   "@
13396    shr{b}\t{%2, %0|%0, %2}
13397    shr{b}\t{%b2, %0|%0, %b2}"
13398   [(set_attr "type" "ishift")
13399    (set_attr "mode" "QI")])
13400
13401 (define_insn "*lshrqi3_1_slp"
13402   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13403         (lshiftrt:QI (match_dup 0)
13404                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13405    (clobber (reg:CC FLAGS_REG))]
13406   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13407    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13408   "@
13409    shr{b}\t{%1, %0|%0, %1}
13410    shr{b}\t{%b1, %0|%0, %b1}"
13411   [(set_attr "type" "ishift1")
13412    (set_attr "mode" "QI")])
13413
13414 ;; This pattern can't accept a variable shift count, since shifts by
13415 ;; zero don't affect the flags.  We assume that shifts by constant
13416 ;; zero are optimized away.
13417 (define_insn "*lshrqi2_one_bit_cmp"
13418   [(set (reg FLAGS_REG)
13419         (compare
13420           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13421                        (match_operand:QI 2 "const1_operand" ""))
13422           (const_int 0)))
13423    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13424         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13425   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13426    && ix86_match_ccmode (insn, CCGOCmode)
13427    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13428   "shr{b}\t%0"
13429   [(set_attr "type" "ishift")
13430    (set (attr "length")
13431      (if_then_else (match_operand:SI 0 "register_operand" "")
13432         (const_string "2")
13433         (const_string "*")))])
13434
13435 (define_insn "*lshrqi2_one_bit_cconly"
13436   [(set (reg FLAGS_REG)
13437         (compare
13438           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13439                        (match_operand:QI 2 "const1_operand" ""))
13440           (const_int 0)))
13441    (clobber (match_scratch:QI 0 "=q"))]
13442   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13443    && ix86_match_ccmode (insn, CCGOCmode)
13444    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13445   "shr{b}\t%0"
13446   [(set_attr "type" "ishift")
13447    (set_attr "length" "2")])
13448
13449 ;; This pattern can't accept a variable shift count, since shifts by
13450 ;; zero don't affect the flags.  We assume that shifts by constant
13451 ;; zero are optimized away.
13452 (define_insn "*lshrqi2_cmp"
13453   [(set (reg FLAGS_REG)
13454         (compare
13455           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13456                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13457           (const_int 0)))
13458    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13459         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13460   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13461    && ix86_match_ccmode (insn, CCGOCmode)
13462    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13463   "shr{b}\t{%2, %0|%0, %2}"
13464   [(set_attr "type" "ishift")
13465    (set_attr "mode" "QI")])
13466
13467 (define_insn "*lshrqi2_cconly"
13468   [(set (reg FLAGS_REG)
13469         (compare
13470           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13471                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13472           (const_int 0)))
13473    (clobber (match_scratch:QI 0 "=q"))]
13474   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13475    && ix86_match_ccmode (insn, CCGOCmode)
13476    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13477   "shr{b}\t{%2, %0|%0, %2}"
13478   [(set_attr "type" "ishift")
13479    (set_attr "mode" "QI")])
13480 \f
13481 ;; Rotate instructions
13482
13483 (define_expand "rotldi3"
13484   [(set (match_operand:DI 0 "shiftdi_operand" "")
13485         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13486                    (match_operand:QI 2 "nonmemory_operand" "")))]
13487  ""
13488 {
13489   if (TARGET_64BIT)
13490     {
13491       ix86_expand_binary_operator (ROTATE, DImode, operands);
13492       DONE;
13493     }
13494   if (!const_1_to_31_operand (operands[2], VOIDmode))
13495     FAIL;
13496   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13497   DONE;
13498 })
13499
13500 ;; Implement rotation using two double-precision shift instructions
13501 ;; and a scratch register.
13502 (define_insn_and_split "ix86_rotldi3"
13503  [(set (match_operand:DI 0 "register_operand" "=r")
13504        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13505                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13506   (clobber (reg:CC FLAGS_REG))
13507   (clobber (match_scratch:SI 3 "=&r"))]
13508  "!TARGET_64BIT"
13509  ""
13510  "&& reload_completed"
13511  [(set (match_dup 3) (match_dup 4))
13512   (parallel
13513    [(set (match_dup 4)
13514          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13515                  (lshiftrt:SI (match_dup 5)
13516                               (minus:QI (const_int 32) (match_dup 2)))))
13517     (clobber (reg:CC FLAGS_REG))])
13518   (parallel
13519    [(set (match_dup 5)
13520          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13521                  (lshiftrt:SI (match_dup 3)
13522                               (minus:QI (const_int 32) (match_dup 2)))))
13523     (clobber (reg:CC FLAGS_REG))])]
13524  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13525
13526 (define_insn "*rotlsi3_1_one_bit_rex64"
13527   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13528         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13529                    (match_operand:QI 2 "const1_operand" "")))
13530    (clobber (reg:CC FLAGS_REG))]
13531   "TARGET_64BIT
13532    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13533    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13534   "rol{q}\t%0"
13535   [(set_attr "type" "rotate")
13536    (set (attr "length")
13537      (if_then_else (match_operand:DI 0 "register_operand" "")
13538         (const_string "2")
13539         (const_string "*")))])
13540
13541 (define_insn "*rotldi3_1_rex64"
13542   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13543         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13544                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13545    (clobber (reg:CC FLAGS_REG))]
13546   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13547   "@
13548    rol{q}\t{%2, %0|%0, %2}
13549    rol{q}\t{%b2, %0|%0, %b2}"
13550   [(set_attr "type" "rotate")
13551    (set_attr "mode" "DI")])
13552
13553 (define_expand "rotlsi3"
13554   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13555         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13556                    (match_operand:QI 2 "nonmemory_operand" "")))]
13557   ""
13558   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13559
13560 (define_insn "*rotlsi3_1_one_bit"
13561   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13562         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13563                    (match_operand:QI 2 "const1_operand" "")))
13564    (clobber (reg:CC FLAGS_REG))]
13565   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13566    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13567   "rol{l}\t%0"
13568   [(set_attr "type" "rotate")
13569    (set (attr "length")
13570      (if_then_else (match_operand:SI 0 "register_operand" "")
13571         (const_string "2")
13572         (const_string "*")))])
13573
13574 (define_insn "*rotlsi3_1_one_bit_zext"
13575   [(set (match_operand:DI 0 "register_operand" "=r")
13576         (zero_extend:DI
13577           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13578                      (match_operand:QI 2 "const1_operand" ""))))
13579    (clobber (reg:CC FLAGS_REG))]
13580   "TARGET_64BIT
13581    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13582    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13583   "rol{l}\t%k0"
13584   [(set_attr "type" "rotate")
13585    (set_attr "length" "2")])
13586
13587 (define_insn "*rotlsi3_1"
13588   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13589         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13590                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13591    (clobber (reg:CC FLAGS_REG))]
13592   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13593   "@
13594    rol{l}\t{%2, %0|%0, %2}
13595    rol{l}\t{%b2, %0|%0, %b2}"
13596   [(set_attr "type" "rotate")
13597    (set_attr "mode" "SI")])
13598
13599 (define_insn "*rotlsi3_1_zext"
13600   [(set (match_operand:DI 0 "register_operand" "=r,r")
13601         (zero_extend:DI
13602           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13603                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13604    (clobber (reg:CC FLAGS_REG))]
13605   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13606   "@
13607    rol{l}\t{%2, %k0|%k0, %2}
13608    rol{l}\t{%b2, %k0|%k0, %b2}"
13609   [(set_attr "type" "rotate")
13610    (set_attr "mode" "SI")])
13611
13612 (define_expand "rotlhi3"
13613   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13614         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13615                    (match_operand:QI 2 "nonmemory_operand" "")))]
13616   "TARGET_HIMODE_MATH"
13617   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13618
13619 (define_insn "*rotlhi3_1_one_bit"
13620   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13621         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13622                    (match_operand:QI 2 "const1_operand" "")))
13623    (clobber (reg:CC FLAGS_REG))]
13624   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13625    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13626   "rol{w}\t%0"
13627   [(set_attr "type" "rotate")
13628    (set (attr "length")
13629      (if_then_else (match_operand 0 "register_operand" "")
13630         (const_string "2")
13631         (const_string "*")))])
13632
13633 (define_insn "*rotlhi3_1"
13634   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13635         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13636                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13637    (clobber (reg:CC FLAGS_REG))]
13638   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13639   "@
13640    rol{w}\t{%2, %0|%0, %2}
13641    rol{w}\t{%b2, %0|%0, %b2}"
13642   [(set_attr "type" "rotate")
13643    (set_attr "mode" "HI")])
13644
13645 (define_split
13646  [(set (match_operand:HI 0 "register_operand" "")
13647        (rotate:HI (match_dup 0) (const_int 8)))
13648   (clobber (reg:CC FLAGS_REG))]
13649  "reload_completed"
13650  [(parallel [(set (strict_low_part (match_dup 0))
13651                   (bswap:HI (match_dup 0)))
13652              (clobber (reg:CC FLAGS_REG))])]
13653  "")
13654
13655 (define_expand "rotlqi3"
13656   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13657         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13658                    (match_operand:QI 2 "nonmemory_operand" "")))]
13659   "TARGET_QIMODE_MATH"
13660   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13661
13662 (define_insn "*rotlqi3_1_one_bit_slp"
13663   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13664         (rotate:QI (match_dup 0)
13665                    (match_operand:QI 1 "const1_operand" "")))
13666    (clobber (reg:CC FLAGS_REG))]
13667   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13668    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13669   "rol{b}\t%0"
13670   [(set_attr "type" "rotate1")
13671    (set (attr "length")
13672      (if_then_else (match_operand 0 "register_operand" "")
13673         (const_string "2")
13674         (const_string "*")))])
13675
13676 (define_insn "*rotlqi3_1_one_bit"
13677   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13678         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13679                    (match_operand:QI 2 "const1_operand" "")))
13680    (clobber (reg:CC FLAGS_REG))]
13681   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13682    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13683   "rol{b}\t%0"
13684   [(set_attr "type" "rotate")
13685    (set (attr "length")
13686      (if_then_else (match_operand 0 "register_operand" "")
13687         (const_string "2")
13688         (const_string "*")))])
13689
13690 (define_insn "*rotlqi3_1_slp"
13691   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13692         (rotate:QI (match_dup 0)
13693                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13694    (clobber (reg:CC FLAGS_REG))]
13695   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13696    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13697   "@
13698    rol{b}\t{%1, %0|%0, %1}
13699    rol{b}\t{%b1, %0|%0, %b1}"
13700   [(set_attr "type" "rotate1")
13701    (set_attr "mode" "QI")])
13702
13703 (define_insn "*rotlqi3_1"
13704   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13705         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13706                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13707    (clobber (reg:CC FLAGS_REG))]
13708   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13709   "@
13710    rol{b}\t{%2, %0|%0, %2}
13711    rol{b}\t{%b2, %0|%0, %b2}"
13712   [(set_attr "type" "rotate")
13713    (set_attr "mode" "QI")])
13714
13715 (define_expand "rotrdi3"
13716   [(set (match_operand:DI 0 "shiftdi_operand" "")
13717         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13718                    (match_operand:QI 2 "nonmemory_operand" "")))]
13719  ""
13720 {
13721   if (TARGET_64BIT)
13722     {
13723       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13724       DONE;
13725     }
13726   if (!const_1_to_31_operand (operands[2], VOIDmode))
13727     FAIL;
13728   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13729   DONE;
13730 })
13731
13732 ;; Implement rotation using two double-precision shift instructions
13733 ;; and a scratch register.
13734 (define_insn_and_split "ix86_rotrdi3"
13735  [(set (match_operand:DI 0 "register_operand" "=r")
13736        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13737                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13738   (clobber (reg:CC FLAGS_REG))
13739   (clobber (match_scratch:SI 3 "=&r"))]
13740  "!TARGET_64BIT"
13741  ""
13742  "&& reload_completed"
13743  [(set (match_dup 3) (match_dup 4))
13744   (parallel
13745    [(set (match_dup 4)
13746          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13747                  (ashift:SI (match_dup 5)
13748                             (minus:QI (const_int 32) (match_dup 2)))))
13749     (clobber (reg:CC FLAGS_REG))])
13750   (parallel
13751    [(set (match_dup 5)
13752          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13753                  (ashift:SI (match_dup 3)
13754                             (minus:QI (const_int 32) (match_dup 2)))))
13755     (clobber (reg:CC FLAGS_REG))])]
13756  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13757
13758 (define_insn "*rotrdi3_1_one_bit_rex64"
13759   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13760         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13761                      (match_operand:QI 2 "const1_operand" "")))
13762    (clobber (reg:CC FLAGS_REG))]
13763   "TARGET_64BIT
13764    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13765    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13766   "ror{q}\t%0"
13767   [(set_attr "type" "rotate")
13768    (set (attr "length")
13769      (if_then_else (match_operand:DI 0 "register_operand" "")
13770         (const_string "2")
13771         (const_string "*")))])
13772
13773 (define_insn "*rotrdi3_1_rex64"
13774   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13775         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13776                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13777    (clobber (reg:CC FLAGS_REG))]
13778   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13779   "@
13780    ror{q}\t{%2, %0|%0, %2}
13781    ror{q}\t{%b2, %0|%0, %b2}"
13782   [(set_attr "type" "rotate")
13783    (set_attr "mode" "DI")])
13784
13785 (define_expand "rotrsi3"
13786   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13787         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13788                      (match_operand:QI 2 "nonmemory_operand" "")))]
13789   ""
13790   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13791
13792 (define_insn "*rotrsi3_1_one_bit"
13793   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13794         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13795                      (match_operand:QI 2 "const1_operand" "")))
13796    (clobber (reg:CC FLAGS_REG))]
13797   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13798    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13799   "ror{l}\t%0"
13800   [(set_attr "type" "rotate")
13801    (set (attr "length")
13802      (if_then_else (match_operand:SI 0 "register_operand" "")
13803         (const_string "2")
13804         (const_string "*")))])
13805
13806 (define_insn "*rotrsi3_1_one_bit_zext"
13807   [(set (match_operand:DI 0 "register_operand" "=r")
13808         (zero_extend:DI
13809           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13810                        (match_operand:QI 2 "const1_operand" ""))))
13811    (clobber (reg:CC FLAGS_REG))]
13812   "TARGET_64BIT
13813    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13814    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13815   "ror{l}\t%k0"
13816   [(set_attr "type" "rotate")
13817    (set (attr "length")
13818      (if_then_else (match_operand:SI 0 "register_operand" "")
13819         (const_string "2")
13820         (const_string "*")))])
13821
13822 (define_insn "*rotrsi3_1"
13823   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13824         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13825                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13826    (clobber (reg:CC FLAGS_REG))]
13827   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13828   "@
13829    ror{l}\t{%2, %0|%0, %2}
13830    ror{l}\t{%b2, %0|%0, %b2}"
13831   [(set_attr "type" "rotate")
13832    (set_attr "mode" "SI")])
13833
13834 (define_insn "*rotrsi3_1_zext"
13835   [(set (match_operand:DI 0 "register_operand" "=r,r")
13836         (zero_extend:DI
13837           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13838                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13839    (clobber (reg:CC FLAGS_REG))]
13840   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13841   "@
13842    ror{l}\t{%2, %k0|%k0, %2}
13843    ror{l}\t{%b2, %k0|%k0, %b2}"
13844   [(set_attr "type" "rotate")
13845    (set_attr "mode" "SI")])
13846
13847 (define_expand "rotrhi3"
13848   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13849         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13850                      (match_operand:QI 2 "nonmemory_operand" "")))]
13851   "TARGET_HIMODE_MATH"
13852   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13853
13854 (define_insn "*rotrhi3_one_bit"
13855   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13856         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13857                      (match_operand:QI 2 "const1_operand" "")))
13858    (clobber (reg:CC FLAGS_REG))]
13859   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13860    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13861   "ror{w}\t%0"
13862   [(set_attr "type" "rotate")
13863    (set (attr "length")
13864      (if_then_else (match_operand 0 "register_operand" "")
13865         (const_string "2")
13866         (const_string "*")))])
13867
13868 (define_insn "*rotrhi3_1"
13869   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13870         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13871                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13872    (clobber (reg:CC FLAGS_REG))]
13873   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13874   "@
13875    ror{w}\t{%2, %0|%0, %2}
13876    ror{w}\t{%b2, %0|%0, %b2}"
13877   [(set_attr "type" "rotate")
13878    (set_attr "mode" "HI")])
13879
13880 (define_split
13881  [(set (match_operand:HI 0 "register_operand" "")
13882        (rotatert:HI (match_dup 0) (const_int 8)))
13883   (clobber (reg:CC FLAGS_REG))]
13884  "reload_completed"
13885  [(parallel [(set (strict_low_part (match_dup 0))
13886                   (bswap:HI (match_dup 0)))
13887              (clobber (reg:CC FLAGS_REG))])]
13888  "")
13889
13890 (define_expand "rotrqi3"
13891   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13892         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13893                      (match_operand:QI 2 "nonmemory_operand" "")))]
13894   "TARGET_QIMODE_MATH"
13895   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13896
13897 (define_insn "*rotrqi3_1_one_bit"
13898   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13899         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13900                      (match_operand:QI 2 "const1_operand" "")))
13901    (clobber (reg:CC FLAGS_REG))]
13902   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13903    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13904   "ror{b}\t%0"
13905   [(set_attr "type" "rotate")
13906    (set (attr "length")
13907      (if_then_else (match_operand 0 "register_operand" "")
13908         (const_string "2")
13909         (const_string "*")))])
13910
13911 (define_insn "*rotrqi3_1_one_bit_slp"
13912   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13913         (rotatert:QI (match_dup 0)
13914                      (match_operand:QI 1 "const1_operand" "")))
13915    (clobber (reg:CC FLAGS_REG))]
13916   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13917    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13918   "ror{b}\t%0"
13919   [(set_attr "type" "rotate1")
13920    (set (attr "length")
13921      (if_then_else (match_operand 0 "register_operand" "")
13922         (const_string "2")
13923         (const_string "*")))])
13924
13925 (define_insn "*rotrqi3_1"
13926   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13927         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13928                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13929    (clobber (reg:CC FLAGS_REG))]
13930   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13931   "@
13932    ror{b}\t{%2, %0|%0, %2}
13933    ror{b}\t{%b2, %0|%0, %b2}"
13934   [(set_attr "type" "rotate")
13935    (set_attr "mode" "QI")])
13936
13937 (define_insn "*rotrqi3_1_slp"
13938   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13939         (rotatert:QI (match_dup 0)
13940                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13941    (clobber (reg:CC FLAGS_REG))]
13942   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13943    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13944   "@
13945    ror{b}\t{%1, %0|%0, %1}
13946    ror{b}\t{%b1, %0|%0, %b1}"
13947   [(set_attr "type" "rotate1")
13948    (set_attr "mode" "QI")])
13949 \f
13950 ;; Bit set / bit test instructions
13951
13952 (define_expand "extv"
13953   [(set (match_operand:SI 0 "register_operand" "")
13954         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13955                          (match_operand:SI 2 "const8_operand" "")
13956                          (match_operand:SI 3 "const8_operand" "")))]
13957   ""
13958 {
13959   /* Handle extractions from %ah et al.  */
13960   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13961     FAIL;
13962
13963   /* From mips.md: extract_bit_field doesn't verify that our source
13964      matches the predicate, so check it again here.  */
13965   if (! ext_register_operand (operands[1], VOIDmode))
13966     FAIL;
13967 })
13968
13969 (define_expand "extzv"
13970   [(set (match_operand:SI 0 "register_operand" "")
13971         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13972                          (match_operand:SI 2 "const8_operand" "")
13973                          (match_operand:SI 3 "const8_operand" "")))]
13974   ""
13975 {
13976   /* Handle extractions from %ah et al.  */
13977   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13978     FAIL;
13979
13980   /* From mips.md: extract_bit_field doesn't verify that our source
13981      matches the predicate, so check it again here.  */
13982   if (! ext_register_operand (operands[1], VOIDmode))
13983     FAIL;
13984 })
13985
13986 (define_expand "insv"
13987   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13988                       (match_operand 1 "const8_operand" "")
13989                       (match_operand 2 "const8_operand" ""))
13990         (match_operand 3 "register_operand" ""))]
13991   ""
13992 {
13993   /* Handle insertions to %ah et al.  */
13994   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13995     FAIL;
13996
13997   /* From mips.md: insert_bit_field doesn't verify that our source
13998      matches the predicate, so check it again here.  */
13999   if (! ext_register_operand (operands[0], VOIDmode))
14000     FAIL;
14001
14002   if (TARGET_64BIT)
14003     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
14004   else
14005     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
14006
14007   DONE;
14008 })
14009
14010 ;; %%% bts, btr, btc, bt.
14011 ;; In general these instructions are *slow* when applied to memory,
14012 ;; since they enforce atomic operation.  When applied to registers,
14013 ;; it depends on the cpu implementation.  They're never faster than
14014 ;; the corresponding and/ior/xor operations, so with 32-bit there's
14015 ;; no point.  But in 64-bit, we can't hold the relevant immediates
14016 ;; within the instruction itself, so operating on bits in the high
14017 ;; 32-bits of a register becomes easier.
14018 ;;
14019 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
14020 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
14021 ;; negdf respectively, so they can never be disabled entirely.
14022
14023 (define_insn "*btsq"
14024   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14025                          (const_int 1)
14026                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14027         (const_int 1))
14028    (clobber (reg:CC FLAGS_REG))]
14029   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14030   "bts{q}\t{%1, %0|%0, %1}"
14031   [(set_attr "type" "alu1")])
14032
14033 (define_insn "*btrq"
14034   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14035                          (const_int 1)
14036                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14037         (const_int 0))
14038    (clobber (reg:CC FLAGS_REG))]
14039   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14040   "btr{q}\t{%1, %0|%0, %1}"
14041   [(set_attr "type" "alu1")])
14042
14043 (define_insn "*btcq"
14044   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14045                          (const_int 1)
14046                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14047         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
14048    (clobber (reg:CC FLAGS_REG))]
14049   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14050   "btc{q}\t{%1, %0|%0, %1}"
14051   [(set_attr "type" "alu1")])
14052
14053 ;; Allow Nocona to avoid these instructions if a register is available.
14054
14055 (define_peephole2
14056   [(match_scratch:DI 2 "r")
14057    (parallel [(set (zero_extract:DI
14058                      (match_operand:DI 0 "register_operand" "")
14059                      (const_int 1)
14060                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14061                    (const_int 1))
14062               (clobber (reg:CC FLAGS_REG))])]
14063   "TARGET_64BIT && !TARGET_USE_BT"
14064   [(const_int 0)]
14065 {
14066   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14067   rtx op1;
14068
14069   if (HOST_BITS_PER_WIDE_INT >= 64)
14070     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14071   else if (i < HOST_BITS_PER_WIDE_INT)
14072     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14073   else
14074     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14075
14076   op1 = immed_double_const (lo, hi, DImode);
14077   if (i >= 31)
14078     {
14079       emit_move_insn (operands[2], op1);
14080       op1 = operands[2];
14081     }
14082
14083   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14084   DONE;
14085 })
14086
14087 (define_peephole2
14088   [(match_scratch:DI 2 "r")
14089    (parallel [(set (zero_extract:DI
14090                      (match_operand:DI 0 "register_operand" "")
14091                      (const_int 1)
14092                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14093                    (const_int 0))
14094               (clobber (reg:CC FLAGS_REG))])]
14095   "TARGET_64BIT && !TARGET_USE_BT"
14096   [(const_int 0)]
14097 {
14098   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14099   rtx op1;
14100
14101   if (HOST_BITS_PER_WIDE_INT >= 64)
14102     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14103   else if (i < HOST_BITS_PER_WIDE_INT)
14104     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14105   else
14106     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14107
14108   op1 = immed_double_const (~lo, ~hi, DImode);
14109   if (i >= 32)
14110     {
14111       emit_move_insn (operands[2], op1);
14112       op1 = operands[2];
14113     }
14114
14115   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14116   DONE;
14117 })
14118
14119 (define_peephole2
14120   [(match_scratch:DI 2 "r")
14121    (parallel [(set (zero_extract:DI
14122                      (match_operand:DI 0 "register_operand" "")
14123                      (const_int 1)
14124                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14125               (not:DI (zero_extract:DI
14126                         (match_dup 0) (const_int 1) (match_dup 1))))
14127               (clobber (reg:CC FLAGS_REG))])]
14128   "TARGET_64BIT && !TARGET_USE_BT"
14129   [(const_int 0)]
14130 {
14131   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14132   rtx op1;
14133
14134   if (HOST_BITS_PER_WIDE_INT >= 64)
14135     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14136   else if (i < HOST_BITS_PER_WIDE_INT)
14137     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14138   else
14139     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14140
14141   op1 = immed_double_const (lo, hi, DImode);
14142   if (i >= 31)
14143     {
14144       emit_move_insn (operands[2], op1);
14145       op1 = operands[2];
14146     }
14147
14148   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14149   DONE;
14150 })
14151
14152 (define_insn "*btdi_rex64"
14153   [(set (reg:CCC FLAGS_REG)
14154         (compare:CCC
14155           (zero_extract:DI
14156             (match_operand:DI 0 "register_operand" "r")
14157             (const_int 1)
14158             (match_operand:DI 1 "nonmemory_operand" "rN"))
14159           (const_int 0)))]
14160   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14161   "bt{q}\t{%1, %0|%0, %1}"
14162   [(set_attr "type" "alu1")])
14163
14164 (define_insn "*btsi"
14165   [(set (reg:CCC FLAGS_REG)
14166         (compare:CCC
14167           (zero_extract:SI
14168             (match_operand:SI 0 "register_operand" "r")
14169             (const_int 1)
14170             (match_operand:SI 1 "nonmemory_operand" "rN"))
14171           (const_int 0)))]
14172   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14173   "bt{l}\t{%1, %0|%0, %1}"
14174   [(set_attr "type" "alu1")])
14175 \f
14176 ;; Store-flag instructions.
14177
14178 ;; For all sCOND expanders, also expand the compare or test insn that
14179 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14180
14181 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14182 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14183 ;; way, which can later delete the movzx if only QImode is needed.
14184
14185 (define_expand "s<code>"
14186   [(set (match_operand:QI 0 "register_operand" "")
14187         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14188   ""
14189   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14190
14191 (define_expand "s<code>"
14192   [(set (match_operand:QI 0 "register_operand" "")
14193         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14194   "TARGET_80387 || TARGET_SSE"
14195   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14196
14197 (define_insn "*setcc_1"
14198   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14199         (match_operator:QI 1 "ix86_comparison_operator"
14200           [(reg FLAGS_REG) (const_int 0)]))]
14201   ""
14202   "set%C1\t%0"
14203   [(set_attr "type" "setcc")
14204    (set_attr "mode" "QI")])
14205
14206 (define_insn "*setcc_2"
14207   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14208         (match_operator:QI 1 "ix86_comparison_operator"
14209           [(reg FLAGS_REG) (const_int 0)]))]
14210   ""
14211   "set%C1\t%0"
14212   [(set_attr "type" "setcc")
14213    (set_attr "mode" "QI")])
14214
14215 ;; In general it is not safe to assume too much about CCmode registers,
14216 ;; so simplify-rtx stops when it sees a second one.  Under certain
14217 ;; conditions this is safe on x86, so help combine not create
14218 ;;
14219 ;;      seta    %al
14220 ;;      testb   %al, %al
14221 ;;      sete    %al
14222
14223 (define_split
14224   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14225         (ne:QI (match_operator 1 "ix86_comparison_operator"
14226                  [(reg FLAGS_REG) (const_int 0)])
14227             (const_int 0)))]
14228   ""
14229   [(set (match_dup 0) (match_dup 1))]
14230 {
14231   PUT_MODE (operands[1], QImode);
14232 })
14233
14234 (define_split
14235   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14236         (ne:QI (match_operator 1 "ix86_comparison_operator"
14237                  [(reg FLAGS_REG) (const_int 0)])
14238             (const_int 0)))]
14239   ""
14240   [(set (match_dup 0) (match_dup 1))]
14241 {
14242   PUT_MODE (operands[1], QImode);
14243 })
14244
14245 (define_split
14246   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14247         (eq:QI (match_operator 1 "ix86_comparison_operator"
14248                  [(reg FLAGS_REG) (const_int 0)])
14249             (const_int 0)))]
14250   ""
14251   [(set (match_dup 0) (match_dup 1))]
14252 {
14253   rtx new_op1 = copy_rtx (operands[1]);
14254   operands[1] = new_op1;
14255   PUT_MODE (new_op1, QImode);
14256   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14257                                              GET_MODE (XEXP (new_op1, 0))));
14258
14259   /* Make sure that (a) the CCmode we have for the flags is strong
14260      enough for the reversed compare or (b) we have a valid FP compare.  */
14261   if (! ix86_comparison_operator (new_op1, VOIDmode))
14262     FAIL;
14263 })
14264
14265 (define_split
14266   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14267         (eq:QI (match_operator 1 "ix86_comparison_operator"
14268                  [(reg FLAGS_REG) (const_int 0)])
14269             (const_int 0)))]
14270   ""
14271   [(set (match_dup 0) (match_dup 1))]
14272 {
14273   rtx new_op1 = copy_rtx (operands[1]);
14274   operands[1] = new_op1;
14275   PUT_MODE (new_op1, QImode);
14276   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14277                                              GET_MODE (XEXP (new_op1, 0))));
14278
14279   /* Make sure that (a) the CCmode we have for the flags is strong
14280      enough for the reversed compare or (b) we have a valid FP compare.  */
14281   if (! ix86_comparison_operator (new_op1, VOIDmode))
14282     FAIL;
14283 })
14284
14285 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14286 ;; subsequent logical operations are used to imitate conditional moves.
14287 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14288 ;; it directly.
14289
14290 (define_insn "*avx_setcc<mode>"
14291   [(set (match_operand:MODEF 0 "register_operand" "=x")
14292         (match_operator:MODEF 1 "avx_comparison_float_operator"
14293           [(match_operand:MODEF 2 "register_operand" "x")
14294            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14295   "TARGET_AVX"
14296   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14297   [(set_attr "type" "ssecmp")
14298    (set_attr "prefix" "vex")
14299    (set_attr "mode" "<MODE>")])
14300
14301 (define_insn "*sse_setcc<mode>"
14302   [(set (match_operand:MODEF 0 "register_operand" "=x")
14303         (match_operator:MODEF 1 "sse_comparison_operator"
14304           [(match_operand:MODEF 2 "register_operand" "0")
14305            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14306   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14307   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14308   [(set_attr "type" "ssecmp")
14309    (set_attr "mode" "<MODE>")])
14310
14311 (define_insn "*sse5_setcc<mode>"
14312   [(set (match_operand:MODEF 0 "register_operand" "=x")
14313         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14314           [(match_operand:MODEF 2 "register_operand" "x")
14315            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14316   "TARGET_SSE5"
14317   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14318   [(set_attr "type" "sse4arg")
14319    (set_attr "mode" "<MODE>")])
14320
14321 \f
14322 ;; Basic conditional jump instructions.
14323 ;; We ignore the overflow flag for signed branch instructions.
14324
14325 ;; For all bCOND expanders, also expand the compare or test insn that
14326 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14327
14328 (define_expand "b<code>"
14329   [(set (pc)
14330         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14331                                    (const_int 0))
14332                       (label_ref (match_operand 0 ""))
14333                       (pc)))]
14334   ""
14335   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14336
14337 (define_expand "b<code>"
14338   [(set (pc)
14339         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14340                                   (const_int 0))
14341                       (label_ref (match_operand 0 ""))
14342                       (pc)))]
14343   "TARGET_80387 || TARGET_SSE_MATH"
14344   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14345
14346 (define_insn "*jcc_1"
14347   [(set (pc)
14348         (if_then_else (match_operator 1 "ix86_comparison_operator"
14349                                       [(reg FLAGS_REG) (const_int 0)])
14350                       (label_ref (match_operand 0 "" ""))
14351                       (pc)))]
14352   ""
14353   "%+j%C1\t%l0"
14354   [(set_attr "type" "ibr")
14355    (set_attr "modrm" "0")
14356    (set (attr "length")
14357            (if_then_else (and (ge (minus (match_dup 0) (pc))
14358                                   (const_int -126))
14359                               (lt (minus (match_dup 0) (pc))
14360                                   (const_int 128)))
14361              (const_int 2)
14362              (const_int 6)))])
14363
14364 (define_insn "*jcc_2"
14365   [(set (pc)
14366         (if_then_else (match_operator 1 "ix86_comparison_operator"
14367                                       [(reg FLAGS_REG) (const_int 0)])
14368                       (pc)
14369                       (label_ref (match_operand 0 "" ""))))]
14370   ""
14371   "%+j%c1\t%l0"
14372   [(set_attr "type" "ibr")
14373    (set_attr "modrm" "0")
14374    (set (attr "length")
14375            (if_then_else (and (ge (minus (match_dup 0) (pc))
14376                                   (const_int -126))
14377                               (lt (minus (match_dup 0) (pc))
14378                                   (const_int 128)))
14379              (const_int 2)
14380              (const_int 6)))])
14381
14382 ;; In general it is not safe to assume too much about CCmode registers,
14383 ;; so simplify-rtx stops when it sees a second one.  Under certain
14384 ;; conditions this is safe on x86, so help combine not create
14385 ;;
14386 ;;      seta    %al
14387 ;;      testb   %al, %al
14388 ;;      je      Lfoo
14389
14390 (define_split
14391   [(set (pc)
14392         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14393                                       [(reg FLAGS_REG) (const_int 0)])
14394                           (const_int 0))
14395                       (label_ref (match_operand 1 "" ""))
14396                       (pc)))]
14397   ""
14398   [(set (pc)
14399         (if_then_else (match_dup 0)
14400                       (label_ref (match_dup 1))
14401                       (pc)))]
14402 {
14403   PUT_MODE (operands[0], VOIDmode);
14404 })
14405
14406 (define_split
14407   [(set (pc)
14408         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14409                                       [(reg FLAGS_REG) (const_int 0)])
14410                           (const_int 0))
14411                       (label_ref (match_operand 1 "" ""))
14412                       (pc)))]
14413   ""
14414   [(set (pc)
14415         (if_then_else (match_dup 0)
14416                       (label_ref (match_dup 1))
14417                       (pc)))]
14418 {
14419   rtx new_op0 = copy_rtx (operands[0]);
14420   operands[0] = new_op0;
14421   PUT_MODE (new_op0, VOIDmode);
14422   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14423                                              GET_MODE (XEXP (new_op0, 0))));
14424
14425   /* Make sure that (a) the CCmode we have for the flags is strong
14426      enough for the reversed compare or (b) we have a valid FP compare.  */
14427   if (! ix86_comparison_operator (new_op0, VOIDmode))
14428     FAIL;
14429 })
14430
14431 ;; zero_extend in SImode is correct, since this is what combine pass
14432 ;; generates from shift insn with QImode operand.  Actually, the mode of
14433 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14434 ;; appropriate modulo of the bit offset value.
14435
14436 (define_insn_and_split "*jcc_btdi_rex64"
14437   [(set (pc)
14438         (if_then_else (match_operator 0 "bt_comparison_operator"
14439                         [(zero_extract:DI
14440                            (match_operand:DI 1 "register_operand" "r")
14441                            (const_int 1)
14442                            (zero_extend:SI
14443                              (match_operand:QI 2 "register_operand" "r")))
14444                          (const_int 0)])
14445                       (label_ref (match_operand 3 "" ""))
14446                       (pc)))
14447    (clobber (reg:CC FLAGS_REG))]
14448   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14449   "#"
14450   "&& 1"
14451   [(set (reg:CCC FLAGS_REG)
14452         (compare:CCC
14453           (zero_extract:DI
14454             (match_dup 1)
14455             (const_int 1)
14456             (match_dup 2))
14457           (const_int 0)))
14458    (set (pc)
14459         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14460                       (label_ref (match_dup 3))
14461                       (pc)))]
14462 {
14463   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14464
14465   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14466 })
14467
14468 ;; avoid useless masking of bit offset operand
14469 (define_insn_and_split "*jcc_btdi_mask_rex64"
14470   [(set (pc)
14471         (if_then_else (match_operator 0 "bt_comparison_operator"
14472                         [(zero_extract:DI
14473                            (match_operand:DI 1 "register_operand" "r")
14474                            (const_int 1)
14475                            (and:SI
14476                              (match_operand:SI 2 "register_operand" "r")
14477                              (match_operand:SI 3 "const_int_operand" "n")))])
14478                       (label_ref (match_operand 4 "" ""))
14479                       (pc)))
14480    (clobber (reg:CC FLAGS_REG))]
14481   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14482    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14483   "#"
14484   "&& 1"
14485   [(set (reg:CCC FLAGS_REG)
14486         (compare:CCC
14487           (zero_extract:DI
14488             (match_dup 1)
14489             (const_int 1)
14490             (match_dup 2))
14491           (const_int 0)))
14492    (set (pc)
14493         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14494                       (label_ref (match_dup 4))
14495                       (pc)))]
14496 {
14497   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14498
14499   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14500 })
14501
14502 (define_insn_and_split "*jcc_btsi"
14503   [(set (pc)
14504         (if_then_else (match_operator 0 "bt_comparison_operator"
14505                         [(zero_extract:SI
14506                            (match_operand:SI 1 "register_operand" "r")
14507                            (const_int 1)
14508                            (zero_extend:SI
14509                              (match_operand:QI 2 "register_operand" "r")))
14510                          (const_int 0)])
14511                       (label_ref (match_operand 3 "" ""))
14512                       (pc)))
14513    (clobber (reg:CC FLAGS_REG))]
14514   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14515   "#"
14516   "&& 1"
14517   [(set (reg:CCC FLAGS_REG)
14518         (compare:CCC
14519           (zero_extract:SI
14520             (match_dup 1)
14521             (const_int 1)
14522             (match_dup 2))
14523           (const_int 0)))
14524    (set (pc)
14525         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14526                       (label_ref (match_dup 3))
14527                       (pc)))]
14528 {
14529   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14530
14531   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14532 })
14533
14534 ;; avoid useless masking of bit offset operand
14535 (define_insn_and_split "*jcc_btsi_mask"
14536   [(set (pc)
14537         (if_then_else (match_operator 0 "bt_comparison_operator"
14538                         [(zero_extract:SI
14539                            (match_operand:SI 1 "register_operand" "r")
14540                            (const_int 1)
14541                            (and:SI
14542                              (match_operand:SI 2 "register_operand" "r")
14543                              (match_operand:SI 3 "const_int_operand" "n")))])
14544                       (label_ref (match_operand 4 "" ""))
14545                       (pc)))
14546    (clobber (reg:CC FLAGS_REG))]
14547   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14548    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14549   "#"
14550   "&& 1"
14551   [(set (reg:CCC FLAGS_REG)
14552         (compare:CCC
14553           (zero_extract:SI
14554             (match_dup 1)
14555             (const_int 1)
14556             (match_dup 2))
14557           (const_int 0)))
14558    (set (pc)
14559         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14560                       (label_ref (match_dup 4))
14561                       (pc)))]
14562   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14563
14564 (define_insn_and_split "*jcc_btsi_1"
14565   [(set (pc)
14566         (if_then_else (match_operator 0 "bt_comparison_operator"
14567                         [(and:SI
14568                            (lshiftrt:SI
14569                              (match_operand:SI 1 "register_operand" "r")
14570                              (match_operand:QI 2 "register_operand" "r"))
14571                            (const_int 1))
14572                          (const_int 0)])
14573                       (label_ref (match_operand 3 "" ""))
14574                       (pc)))
14575    (clobber (reg:CC FLAGS_REG))]
14576   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14577   "#"
14578   "&& 1"
14579   [(set (reg:CCC FLAGS_REG)
14580         (compare:CCC
14581           (zero_extract:SI
14582             (match_dup 1)
14583             (const_int 1)
14584             (match_dup 2))
14585           (const_int 0)))
14586    (set (pc)
14587         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14588                       (label_ref (match_dup 3))
14589                       (pc)))]
14590 {
14591   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14592
14593   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14594 })
14595
14596 ;; avoid useless masking of bit offset operand
14597 (define_insn_and_split "*jcc_btsi_mask_1"
14598   [(set (pc)
14599         (if_then_else
14600           (match_operator 0 "bt_comparison_operator"
14601             [(and:SI
14602                (lshiftrt:SI
14603                  (match_operand:SI 1 "register_operand" "r")
14604                  (subreg:QI
14605                    (and:SI
14606                      (match_operand:SI 2 "register_operand" "r")
14607                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14608                (const_int 1))
14609              (const_int 0)])
14610           (label_ref (match_operand 4 "" ""))
14611           (pc)))
14612    (clobber (reg:CC FLAGS_REG))]
14613   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14614    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14615   "#"
14616   "&& 1"
14617   [(set (reg:CCC FLAGS_REG)
14618         (compare:CCC
14619           (zero_extract:SI
14620             (match_dup 1)
14621             (const_int 1)
14622             (match_dup 2))
14623           (const_int 0)))
14624    (set (pc)
14625         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14626                       (label_ref (match_dup 4))
14627                       (pc)))]
14628   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14629
14630 ;; Define combination compare-and-branch fp compare instructions to use
14631 ;; during early optimization.  Splitting the operation apart early makes
14632 ;; for bad code when we want to reverse the operation.
14633
14634 (define_insn "*fp_jcc_1_mixed"
14635   [(set (pc)
14636         (if_then_else (match_operator 0 "comparison_operator"
14637                         [(match_operand 1 "register_operand" "f,x")
14638                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14639           (label_ref (match_operand 3 "" ""))
14640           (pc)))
14641    (clobber (reg:CCFP FPSR_REG))
14642    (clobber (reg:CCFP FLAGS_REG))]
14643   "TARGET_MIX_SSE_I387
14644    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14645    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14646    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14647   "#")
14648
14649 (define_insn "*fp_jcc_1_sse"
14650   [(set (pc)
14651         (if_then_else (match_operator 0 "comparison_operator"
14652                         [(match_operand 1 "register_operand" "x")
14653                          (match_operand 2 "nonimmediate_operand" "xm")])
14654           (label_ref (match_operand 3 "" ""))
14655           (pc)))
14656    (clobber (reg:CCFP FPSR_REG))
14657    (clobber (reg:CCFP FLAGS_REG))]
14658   "TARGET_SSE_MATH
14659    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14660    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14661    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14662   "#")
14663
14664 (define_insn "*fp_jcc_1_387"
14665   [(set (pc)
14666         (if_then_else (match_operator 0 "comparison_operator"
14667                         [(match_operand 1 "register_operand" "f")
14668                          (match_operand 2 "register_operand" "f")])
14669           (label_ref (match_operand 3 "" ""))
14670           (pc)))
14671    (clobber (reg:CCFP FPSR_REG))
14672    (clobber (reg:CCFP FLAGS_REG))]
14673   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14674    && TARGET_CMOVE
14675    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14676    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14677   "#")
14678
14679 (define_insn "*fp_jcc_2_mixed"
14680   [(set (pc)
14681         (if_then_else (match_operator 0 "comparison_operator"
14682                         [(match_operand 1 "register_operand" "f,x")
14683                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14684           (pc)
14685           (label_ref (match_operand 3 "" ""))))
14686    (clobber (reg:CCFP FPSR_REG))
14687    (clobber (reg:CCFP FLAGS_REG))]
14688   "TARGET_MIX_SSE_I387
14689    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14690    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14691    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14692   "#")
14693
14694 (define_insn "*fp_jcc_2_sse"
14695   [(set (pc)
14696         (if_then_else (match_operator 0 "comparison_operator"
14697                         [(match_operand 1 "register_operand" "x")
14698                          (match_operand 2 "nonimmediate_operand" "xm")])
14699           (pc)
14700           (label_ref (match_operand 3 "" ""))))
14701    (clobber (reg:CCFP FPSR_REG))
14702    (clobber (reg:CCFP FLAGS_REG))]
14703   "TARGET_SSE_MATH
14704    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14705    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14706    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14707   "#")
14708
14709 (define_insn "*fp_jcc_2_387"
14710   [(set (pc)
14711         (if_then_else (match_operator 0 "comparison_operator"
14712                         [(match_operand 1 "register_operand" "f")
14713                          (match_operand 2 "register_operand" "f")])
14714           (pc)
14715           (label_ref (match_operand 3 "" ""))))
14716    (clobber (reg:CCFP FPSR_REG))
14717    (clobber (reg:CCFP FLAGS_REG))]
14718   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14719    && TARGET_CMOVE
14720    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14721    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14722   "#")
14723
14724 (define_insn "*fp_jcc_3_387"
14725   [(set (pc)
14726         (if_then_else (match_operator 0 "comparison_operator"
14727                         [(match_operand 1 "register_operand" "f")
14728                          (match_operand 2 "nonimmediate_operand" "fm")])
14729           (label_ref (match_operand 3 "" ""))
14730           (pc)))
14731    (clobber (reg:CCFP FPSR_REG))
14732    (clobber (reg:CCFP FLAGS_REG))
14733    (clobber (match_scratch:HI 4 "=a"))]
14734   "TARGET_80387
14735    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14736    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14737    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14738    && SELECT_CC_MODE (GET_CODE (operands[0]),
14739                       operands[1], operands[2]) == CCFPmode
14740    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14741   "#")
14742
14743 (define_insn "*fp_jcc_4_387"
14744   [(set (pc)
14745         (if_then_else (match_operator 0 "comparison_operator"
14746                         [(match_operand 1 "register_operand" "f")
14747                          (match_operand 2 "nonimmediate_operand" "fm")])
14748           (pc)
14749           (label_ref (match_operand 3 "" ""))))
14750    (clobber (reg:CCFP FPSR_REG))
14751    (clobber (reg:CCFP FLAGS_REG))
14752    (clobber (match_scratch:HI 4 "=a"))]
14753   "TARGET_80387
14754    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14755    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14756    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14757    && SELECT_CC_MODE (GET_CODE (operands[0]),
14758                       operands[1], operands[2]) == CCFPmode
14759    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14760   "#")
14761
14762 (define_insn "*fp_jcc_5_387"
14763   [(set (pc)
14764         (if_then_else (match_operator 0 "comparison_operator"
14765                         [(match_operand 1 "register_operand" "f")
14766                          (match_operand 2 "register_operand" "f")])
14767           (label_ref (match_operand 3 "" ""))
14768           (pc)))
14769    (clobber (reg:CCFP FPSR_REG))
14770    (clobber (reg:CCFP FLAGS_REG))
14771    (clobber (match_scratch:HI 4 "=a"))]
14772   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14773    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14774    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14775   "#")
14776
14777 (define_insn "*fp_jcc_6_387"
14778   [(set (pc)
14779         (if_then_else (match_operator 0 "comparison_operator"
14780                         [(match_operand 1 "register_operand" "f")
14781                          (match_operand 2 "register_operand" "f")])
14782           (pc)
14783           (label_ref (match_operand 3 "" ""))))
14784    (clobber (reg:CCFP FPSR_REG))
14785    (clobber (reg:CCFP FLAGS_REG))
14786    (clobber (match_scratch:HI 4 "=a"))]
14787   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14788    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14789    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14790   "#")
14791
14792 (define_insn "*fp_jcc_7_387"
14793   [(set (pc)
14794         (if_then_else (match_operator 0 "comparison_operator"
14795                         [(match_operand 1 "register_operand" "f")
14796                          (match_operand 2 "const0_operand" "")])
14797           (label_ref (match_operand 3 "" ""))
14798           (pc)))
14799    (clobber (reg:CCFP FPSR_REG))
14800    (clobber (reg:CCFP FLAGS_REG))
14801    (clobber (match_scratch:HI 4 "=a"))]
14802   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14803    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14804    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14805    && SELECT_CC_MODE (GET_CODE (operands[0]),
14806                       operands[1], operands[2]) == CCFPmode
14807    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14808   "#")
14809
14810 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14811 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14812 ;; with a precedence over other operators and is always put in the first
14813 ;; place. Swap condition and operands to match ficom instruction.
14814
14815 (define_insn "*fp_jcc_8<mode>_387"
14816   [(set (pc)
14817         (if_then_else (match_operator 0 "comparison_operator"
14818                         [(match_operator 1 "float_operator"
14819                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14820                            (match_operand 3 "register_operand" "f,f")])
14821           (label_ref (match_operand 4 "" ""))
14822           (pc)))
14823    (clobber (reg:CCFP FPSR_REG))
14824    (clobber (reg:CCFP FLAGS_REG))
14825    (clobber (match_scratch:HI 5 "=a,a"))]
14826   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14827    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14828    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14829    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14830    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14831    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14832   "#")
14833
14834 (define_split
14835   [(set (pc)
14836         (if_then_else (match_operator 0 "comparison_operator"
14837                         [(match_operand 1 "register_operand" "")
14838                          (match_operand 2 "nonimmediate_operand" "")])
14839           (match_operand 3 "" "")
14840           (match_operand 4 "" "")))
14841    (clobber (reg:CCFP FPSR_REG))
14842    (clobber (reg:CCFP FLAGS_REG))]
14843   "reload_completed"
14844   [(const_int 0)]
14845 {
14846   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14847                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14848   DONE;
14849 })
14850
14851 (define_split
14852   [(set (pc)
14853         (if_then_else (match_operator 0 "comparison_operator"
14854                         [(match_operand 1 "register_operand" "")
14855                          (match_operand 2 "general_operand" "")])
14856           (match_operand 3 "" "")
14857           (match_operand 4 "" "")))
14858    (clobber (reg:CCFP FPSR_REG))
14859    (clobber (reg:CCFP FLAGS_REG))
14860    (clobber (match_scratch:HI 5 "=a"))]
14861   "reload_completed"
14862   [(const_int 0)]
14863 {
14864   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14865                         operands[3], operands[4], operands[5], NULL_RTX);
14866   DONE;
14867 })
14868
14869 (define_split
14870   [(set (pc)
14871         (if_then_else (match_operator 0 "comparison_operator"
14872                         [(match_operator 1 "float_operator"
14873                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14874                            (match_operand 3 "register_operand" "")])
14875           (match_operand 4 "" "")
14876           (match_operand 5 "" "")))
14877    (clobber (reg:CCFP FPSR_REG))
14878    (clobber (reg:CCFP FLAGS_REG))
14879    (clobber (match_scratch:HI 6 "=a"))]
14880   "reload_completed"
14881   [(const_int 0)]
14882 {
14883   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14884   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14885                         operands[3], operands[7],
14886                         operands[4], operands[5], operands[6], NULL_RTX);
14887   DONE;
14888 })
14889
14890 ;; %%% Kill this when reload knows how to do it.
14891 (define_split
14892   [(set (pc)
14893         (if_then_else (match_operator 0 "comparison_operator"
14894                         [(match_operator 1 "float_operator"
14895                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14896                            (match_operand 3 "register_operand" "")])
14897           (match_operand 4 "" "")
14898           (match_operand 5 "" "")))
14899    (clobber (reg:CCFP FPSR_REG))
14900    (clobber (reg:CCFP FLAGS_REG))
14901    (clobber (match_scratch:HI 6 "=a"))]
14902   "reload_completed"
14903   [(const_int 0)]
14904 {
14905   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14906   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14907   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14908                         operands[3], operands[7],
14909                         operands[4], operands[5], operands[6], operands[2]);
14910   DONE;
14911 })
14912 \f
14913 ;; Unconditional and other jump instructions
14914
14915 (define_insn "jump"
14916   [(set (pc)
14917         (label_ref (match_operand 0 "" "")))]
14918   ""
14919   "jmp\t%l0"
14920   [(set_attr "type" "ibr")
14921    (set (attr "length")
14922            (if_then_else (and (ge (minus (match_dup 0) (pc))
14923                                   (const_int -126))
14924                               (lt (minus (match_dup 0) (pc))
14925                                   (const_int 128)))
14926              (const_int 2)
14927              (const_int 5)))
14928    (set_attr "modrm" "0")])
14929
14930 (define_expand "indirect_jump"
14931   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14932   ""
14933   "")
14934
14935 (define_insn "*indirect_jump"
14936   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14937   ""
14938   "jmp\t%A0"
14939   [(set_attr "type" "ibr")
14940    (set_attr "length_immediate" "0")])
14941
14942 (define_expand "tablejump"
14943   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14944               (use (label_ref (match_operand 1 "" "")))])]
14945   ""
14946 {
14947   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14948      relative.  Convert the relative address to an absolute address.  */
14949   if (flag_pic)
14950     {
14951       rtx op0, op1;
14952       enum rtx_code code;
14953
14954       /* We can't use @GOTOFF for text labels on VxWorks;
14955          see gotoff_operand.  */
14956       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14957         {
14958           code = PLUS;
14959           op0 = operands[0];
14960           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14961         }
14962       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14963         {
14964           code = PLUS;
14965           op0 = operands[0];
14966           op1 = pic_offset_table_rtx;
14967         }
14968       else
14969         {
14970           code = MINUS;
14971           op0 = pic_offset_table_rtx;
14972           op1 = operands[0];
14973         }
14974
14975       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14976                                          OPTAB_DIRECT);
14977     }
14978 })
14979
14980 (define_insn "*tablejump_1"
14981   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14982    (use (label_ref (match_operand 1 "" "")))]
14983   ""
14984   "jmp\t%A0"
14985   [(set_attr "type" "ibr")
14986    (set_attr "length_immediate" "0")])
14987 \f
14988 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14989
14990 (define_peephole2
14991   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14992    (set (match_operand:QI 1 "register_operand" "")
14993         (match_operator:QI 2 "ix86_comparison_operator"
14994           [(reg FLAGS_REG) (const_int 0)]))
14995    (set (match_operand 3 "q_regs_operand" "")
14996         (zero_extend (match_dup 1)))]
14997   "(peep2_reg_dead_p (3, operands[1])
14998     || operands_match_p (operands[1], operands[3]))
14999    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15000   [(set (match_dup 4) (match_dup 0))
15001    (set (strict_low_part (match_dup 5))
15002         (match_dup 2))]
15003 {
15004   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15005   operands[5] = gen_lowpart (QImode, operands[3]);
15006   ix86_expand_clear (operands[3]);
15007 })
15008
15009 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
15010
15011 (define_peephole2
15012   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15013    (set (match_operand:QI 1 "register_operand" "")
15014         (match_operator:QI 2 "ix86_comparison_operator"
15015           [(reg FLAGS_REG) (const_int 0)]))
15016    (parallel [(set (match_operand 3 "q_regs_operand" "")
15017                    (zero_extend (match_dup 1)))
15018               (clobber (reg:CC FLAGS_REG))])]
15019   "(peep2_reg_dead_p (3, operands[1])
15020     || operands_match_p (operands[1], operands[3]))
15021    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15022   [(set (match_dup 4) (match_dup 0))
15023    (set (strict_low_part (match_dup 5))
15024         (match_dup 2))]
15025 {
15026   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15027   operands[5] = gen_lowpart (QImode, operands[3]);
15028   ix86_expand_clear (operands[3]);
15029 })
15030 \f
15031 ;; Call instructions.
15032
15033 ;; The predicates normally associated with named expanders are not properly
15034 ;; checked for calls.  This is a bug in the generic code, but it isn't that
15035 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
15036
15037 ;; Call subroutine returning no value.
15038
15039 (define_expand "call_pop"
15040   [(parallel [(call (match_operand:QI 0 "" "")
15041                     (match_operand:SI 1 "" ""))
15042               (set (reg:SI SP_REG)
15043                    (plus:SI (reg:SI SP_REG)
15044                             (match_operand:SI 3 "" "")))])]
15045   "!TARGET_64BIT"
15046 {
15047   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
15048   DONE;
15049 })
15050
15051 (define_insn "*call_pop_0"
15052   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
15053          (match_operand:SI 1 "" ""))
15054    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15055                             (match_operand:SI 2 "immediate_operand" "")))]
15056   "!TARGET_64BIT"
15057 {
15058   if (SIBLING_CALL_P (insn))
15059     return "jmp\t%P0";
15060   else
15061     return "call\t%P0";
15062 }
15063   [(set_attr "type" "call")])
15064
15065 (define_insn "*call_pop_1"
15066   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15067          (match_operand:SI 1 "" ""))
15068    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15069                             (match_operand:SI 2 "immediate_operand" "i")))]
15070   "!TARGET_64BIT"
15071 {
15072   if (constant_call_address_operand (operands[0], Pmode))
15073     {
15074       if (SIBLING_CALL_P (insn))
15075         return "jmp\t%P0";
15076       else
15077         return "call\t%P0";
15078     }
15079   if (SIBLING_CALL_P (insn))
15080     return "jmp\t%A0";
15081   else
15082     return "call\t%A0";
15083 }
15084   [(set_attr "type" "call")])
15085
15086 (define_expand "call"
15087   [(call (match_operand:QI 0 "" "")
15088          (match_operand 1 "" ""))
15089    (use (match_operand 2 "" ""))]
15090   ""
15091 {
15092   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15093   DONE;
15094 })
15095
15096 (define_expand "sibcall"
15097   [(call (match_operand:QI 0 "" "")
15098          (match_operand 1 "" ""))
15099    (use (match_operand 2 "" ""))]
15100   ""
15101 {
15102   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15103   DONE;
15104 })
15105
15106 (define_insn "*call_0"
15107   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15108          (match_operand 1 "" ""))]
15109   ""
15110 {
15111   if (SIBLING_CALL_P (insn))
15112     return "jmp\t%P0";
15113   else
15114     return "call\t%P0";
15115 }
15116   [(set_attr "type" "call")])
15117
15118 (define_insn "*call_1"
15119   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15120          (match_operand 1 "" ""))]
15121   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15122 {
15123   if (constant_call_address_operand (operands[0], Pmode))
15124     return "call\t%P0";
15125   return "call\t%A0";
15126 }
15127   [(set_attr "type" "call")])
15128
15129 (define_insn "*sibcall_1"
15130   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15131          (match_operand 1 "" ""))]
15132   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15133 {
15134   if (constant_call_address_operand (operands[0], Pmode))
15135     return "jmp\t%P0";
15136   return "jmp\t%A0";
15137 }
15138   [(set_attr "type" "call")])
15139
15140 (define_insn "*call_1_rex64"
15141   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15142          (match_operand 1 "" ""))]
15143   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15144    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15145 {
15146   if (constant_call_address_operand (operands[0], Pmode))
15147     return "call\t%P0";
15148   return "call\t%A0";
15149 }
15150   [(set_attr "type" "call")])
15151
15152 (define_insn "*call_1_rex64_ms_sysv"
15153   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15154          (match_operand 1 "" ""))
15155    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15156    (clobber (reg:TI XMM6_REG))
15157    (clobber (reg:TI XMM7_REG))
15158    (clobber (reg:TI XMM8_REG))
15159    (clobber (reg:TI XMM9_REG))
15160    (clobber (reg:TI XMM10_REG))
15161    (clobber (reg:TI XMM11_REG))
15162    (clobber (reg:TI XMM12_REG))
15163    (clobber (reg:TI XMM13_REG))
15164    (clobber (reg:TI XMM14_REG))
15165    (clobber (reg:TI XMM15_REG))
15166    (clobber (reg:DI SI_REG))
15167    (clobber (reg:DI DI_REG))]
15168   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15169 {
15170   if (constant_call_address_operand (operands[0], Pmode))
15171     return "call\t%P0";
15172   return "call\t%A0";
15173 }
15174   [(set_attr "type" "call")])
15175
15176 (define_insn "*call_1_rex64_large"
15177   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15178          (match_operand 1 "" ""))]
15179   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15180   "call\t%A0"
15181   [(set_attr "type" "call")])
15182
15183 (define_insn "*sibcall_1_rex64"
15184   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15185          (match_operand 1 "" ""))]
15186   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15187   "jmp\t%P0"
15188   [(set_attr "type" "call")])
15189
15190 (define_insn "*sibcall_1_rex64_v"
15191   [(call (mem:QI (reg:DI R11_REG))
15192          (match_operand 0 "" ""))]
15193   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15194   "jmp\t{*%%}r11"
15195   [(set_attr "type" "call")])
15196
15197
15198 ;; Call subroutine, returning value in operand 0
15199
15200 (define_expand "call_value_pop"
15201   [(parallel [(set (match_operand 0 "" "")
15202                    (call (match_operand:QI 1 "" "")
15203                          (match_operand:SI 2 "" "")))
15204               (set (reg:SI SP_REG)
15205                    (plus:SI (reg:SI SP_REG)
15206                             (match_operand:SI 4 "" "")))])]
15207   "!TARGET_64BIT"
15208 {
15209   ix86_expand_call (operands[0], operands[1], operands[2],
15210                     operands[3], operands[4], 0);
15211   DONE;
15212 })
15213
15214 (define_expand "call_value"
15215   [(set (match_operand 0 "" "")
15216         (call (match_operand:QI 1 "" "")
15217               (match_operand:SI 2 "" "")))
15218    (use (match_operand:SI 3 "" ""))]
15219   ;; Operand 2 not used on the i386.
15220   ""
15221 {
15222   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15223   DONE;
15224 })
15225
15226 (define_expand "sibcall_value"
15227   [(set (match_operand 0 "" "")
15228         (call (match_operand:QI 1 "" "")
15229               (match_operand:SI 2 "" "")))
15230    (use (match_operand:SI 3 "" ""))]
15231   ;; Operand 2 not used on the i386.
15232   ""
15233 {
15234   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15235   DONE;
15236 })
15237
15238 ;; Call subroutine returning any type.
15239
15240 (define_expand "untyped_call"
15241   [(parallel [(call (match_operand 0 "" "")
15242                     (const_int 0))
15243               (match_operand 1 "" "")
15244               (match_operand 2 "" "")])]
15245   ""
15246 {
15247   int i;
15248
15249   /* In order to give reg-stack an easier job in validating two
15250      coprocessor registers as containing a possible return value,
15251      simply pretend the untyped call returns a complex long double
15252      value. 
15253
15254      We can't use SSE_REGPARM_MAX here since callee is unprototyped
15255      and should have the default ABI.  */
15256
15257   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15258                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15259                     operands[0], const0_rtx,
15260                     GEN_INT ((TARGET_64BIT
15261                               ? (ix86_abi == SYSV_ABI
15262                                  ? X86_64_SSE_REGPARM_MAX
15263                                  : X64_SSE_REGPARM_MAX)
15264                               : X86_32_SSE_REGPARM_MAX)
15265                              - 1),
15266                     NULL, 0);
15267
15268   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15269     {
15270       rtx set = XVECEXP (operands[2], 0, i);
15271       emit_move_insn (SET_DEST (set), SET_SRC (set));
15272     }
15273
15274   /* The optimizer does not know that the call sets the function value
15275      registers we stored in the result block.  We avoid problems by
15276      claiming that all hard registers are used and clobbered at this
15277      point.  */
15278   emit_insn (gen_blockage ());
15279
15280   DONE;
15281 })
15282 \f
15283 ;; Prologue and epilogue instructions
15284
15285 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15286 ;; all of memory.  This blocks insns from being moved across this point.
15287
15288 (define_insn "blockage"
15289   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15290   ""
15291   ""
15292   [(set_attr "length" "0")])
15293
15294 ;; Do not schedule instructions accessing memory across this point.
15295
15296 (define_expand "memory_blockage"
15297   [(set (match_dup 0)
15298         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15299   ""
15300 {
15301   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15302   MEM_VOLATILE_P (operands[0]) = 1;
15303 })
15304
15305 (define_insn "*memory_blockage"
15306   [(set (match_operand:BLK 0 "" "")
15307         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15308   ""
15309   ""
15310   [(set_attr "length" "0")])
15311
15312 ;; As USE insns aren't meaningful after reload, this is used instead
15313 ;; to prevent deleting instructions setting registers for PIC code
15314 (define_insn "prologue_use"
15315   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15316   ""
15317   ""
15318   [(set_attr "length" "0")])
15319
15320 ;; Insn emitted into the body of a function to return from a function.
15321 ;; This is only done if the function's epilogue is known to be simple.
15322 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15323
15324 (define_expand "return"
15325   [(return)]
15326   "ix86_can_use_return_insn_p ()"
15327 {
15328   if (crtl->args.pops_args)
15329     {
15330       rtx popc = GEN_INT (crtl->args.pops_args);
15331       emit_jump_insn (gen_return_pop_internal (popc));
15332       DONE;
15333     }
15334 })
15335
15336 (define_insn "return_internal"
15337   [(return)]
15338   "reload_completed"
15339   "ret"
15340   [(set_attr "length" "1")
15341    (set_attr "atom_unit" "jeu")
15342    (set_attr "length_immediate" "0")
15343    (set_attr "modrm" "0")])
15344
15345 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15346 ;; instruction Athlon and K8 have.
15347
15348 (define_insn "return_internal_long"
15349   [(return)
15350    (unspec [(const_int 0)] UNSPEC_REP)]
15351   "reload_completed"
15352   "rep\;ret"
15353   [(set_attr "length" "1")
15354    (set_attr "atom_unit" "jeu")
15355    (set_attr "length_immediate" "0")
15356    (set_attr "prefix_rep" "1")
15357    (set_attr "modrm" "0")])
15358
15359 (define_insn "return_pop_internal"
15360   [(return)
15361    (use (match_operand:SI 0 "const_int_operand" ""))]
15362   "reload_completed"
15363   "ret\t%0"
15364   [(set_attr "length" "3")
15365    (set_attr "atom_unit" "jeu")
15366    (set_attr "length_immediate" "2")
15367    (set_attr "modrm" "0")])
15368
15369 (define_insn "return_indirect_internal"
15370   [(return)
15371    (use (match_operand:SI 0 "register_operand" "r"))]
15372   "reload_completed"
15373   "jmp\t%A0"
15374   [(set_attr "type" "ibr")
15375    (set_attr "length_immediate" "0")])
15376
15377 (define_insn "nop"
15378   [(const_int 0)]
15379   ""
15380   "nop"
15381   [(set_attr "length" "1")
15382    (set_attr "length_immediate" "0")
15383    (set_attr "modrm" "0")])
15384
15385 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15386 ;; branch prediction penalty for the third jump in a 16-byte
15387 ;; block on K8.
15388
15389 (define_insn "align"
15390   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15391   ""
15392 {
15393 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15394   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15395 #else
15396   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15397      The align insn is used to avoid 3 jump instructions in the row to improve
15398      branch prediction and the benefits hardly outweigh the cost of extra 8
15399      nops on the average inserted by full alignment pseudo operation.  */
15400 #endif
15401   return "";
15402 }
15403   [(set_attr "length" "16")])
15404
15405 (define_expand "prologue"
15406   [(const_int 0)]
15407   ""
15408   "ix86_expand_prologue (); DONE;")
15409
15410 (define_insn "set_got"
15411   [(set (match_operand:SI 0 "register_operand" "=r")
15412         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15413    (clobber (reg:CC FLAGS_REG))]
15414   "!TARGET_64BIT"
15415   { return output_set_got (operands[0], NULL_RTX); }
15416   [(set_attr "type" "multi")
15417    (set_attr "length" "12")])
15418
15419 (define_insn "set_got_labelled"
15420   [(set (match_operand:SI 0 "register_operand" "=r")
15421         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15422          UNSPEC_SET_GOT))
15423    (clobber (reg:CC FLAGS_REG))]
15424   "!TARGET_64BIT"
15425   { return output_set_got (operands[0], operands[1]); }
15426   [(set_attr "type" "multi")
15427    (set_attr "length" "12")])
15428
15429 (define_insn "set_got_rex64"
15430   [(set (match_operand:DI 0 "register_operand" "=r")
15431         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15432   "TARGET_64BIT"
15433   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15434   [(set_attr "type" "lea")
15435    (set_attr "length" "6")])
15436
15437 (define_insn "set_rip_rex64"
15438   [(set (match_operand:DI 0 "register_operand" "=r")
15439         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15440   "TARGET_64BIT"
15441   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15442   [(set_attr "type" "lea")
15443    (set_attr "length" "6")])
15444
15445 (define_insn "set_got_offset_rex64"
15446   [(set (match_operand:DI 0 "register_operand" "=r")
15447         (unspec:DI
15448           [(label_ref (match_operand 1 "" ""))]
15449           UNSPEC_SET_GOT_OFFSET))]
15450   "TARGET_64BIT"
15451   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15452   [(set_attr "type" "imov")
15453    (set_attr "length" "11")])
15454
15455 (define_expand "epilogue"
15456   [(const_int 0)]
15457   ""
15458   "ix86_expand_epilogue (1); DONE;")
15459
15460 (define_expand "sibcall_epilogue"
15461   [(const_int 0)]
15462   ""
15463   "ix86_expand_epilogue (0); DONE;")
15464
15465 (define_expand "eh_return"
15466   [(use (match_operand 0 "register_operand" ""))]
15467   ""
15468 {
15469   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15470
15471   /* Tricky bit: we write the address of the handler to which we will
15472      be returning into someone else's stack frame, one word below the
15473      stack address we wish to restore.  */
15474   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15475   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15476   tmp = gen_rtx_MEM (Pmode, tmp);
15477   emit_move_insn (tmp, ra);
15478
15479   if (Pmode == SImode)
15480     emit_jump_insn (gen_eh_return_si (sa));
15481   else
15482     emit_jump_insn (gen_eh_return_di (sa));
15483   emit_barrier ();
15484   DONE;
15485 })
15486
15487 (define_insn_and_split "eh_return_<mode>"
15488   [(set (pc)
15489         (unspec [(match_operand:P 0 "register_operand" "c")]
15490                  UNSPEC_EH_RETURN))]
15491   ""
15492   "#"
15493   "reload_completed"
15494   [(const_int 0)]
15495   "ix86_expand_epilogue (2); DONE;")
15496
15497 (define_insn "leave"
15498   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15499    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15500    (clobber (mem:BLK (scratch)))]
15501   "!TARGET_64BIT"
15502   "leave"
15503   [(set_attr "type" "leave")])
15504
15505 (define_insn "leave_rex64"
15506   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15507    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15508    (clobber (mem:BLK (scratch)))]
15509   "TARGET_64BIT"
15510   "leave"
15511   [(set_attr "type" "leave")])
15512 \f
15513 (define_expand "ffssi2"
15514   [(parallel
15515      [(set (match_operand:SI 0 "register_operand" "")
15516            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15517       (clobber (match_scratch:SI 2 ""))
15518       (clobber (reg:CC FLAGS_REG))])]
15519   ""
15520 {
15521   if (TARGET_CMOVE)
15522     {
15523       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15524       DONE;
15525     }
15526 })
15527
15528 (define_expand "ffs_cmove"
15529   [(set (match_dup 2) (const_int -1))
15530    (parallel [(set (reg:CCZ FLAGS_REG)
15531                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15532                                 (const_int 0)))
15533               (set (match_operand:SI 0 "register_operand" "")
15534                    (ctz:SI (match_dup 1)))])
15535    (set (match_dup 0) (if_then_else:SI
15536                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15537                         (match_dup 2)
15538                         (match_dup 0)))
15539    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15540               (clobber (reg:CC FLAGS_REG))])]
15541   "TARGET_CMOVE"
15542   "operands[2] = gen_reg_rtx (SImode);")
15543
15544 (define_insn_and_split "*ffs_no_cmove"
15545   [(set (match_operand:SI 0 "register_operand" "=r")
15546         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15547    (clobber (match_scratch:SI 2 "=&q"))
15548    (clobber (reg:CC FLAGS_REG))]
15549   "!TARGET_CMOVE"
15550   "#"
15551   "&& reload_completed"
15552   [(parallel [(set (reg:CCZ FLAGS_REG)
15553                    (compare:CCZ (match_dup 1) (const_int 0)))
15554               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15555    (set (strict_low_part (match_dup 3))
15556         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15557    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15558               (clobber (reg:CC FLAGS_REG))])
15559    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15560               (clobber (reg:CC FLAGS_REG))])
15561    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15562               (clobber (reg:CC FLAGS_REG))])]
15563 {
15564   operands[3] = gen_lowpart (QImode, operands[2]);
15565   ix86_expand_clear (operands[2]);
15566 })
15567
15568 (define_insn "*ffssi_1"
15569   [(set (reg:CCZ FLAGS_REG)
15570         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15571                      (const_int 0)))
15572    (set (match_operand:SI 0 "register_operand" "=r")
15573         (ctz:SI (match_dup 1)))]
15574   ""
15575   "bsf{l}\t{%1, %0|%0, %1}"
15576   [(set_attr "prefix_0f" "1")])
15577
15578 (define_expand "ffsdi2"
15579   [(set (match_dup 2) (const_int -1))
15580    (parallel [(set (reg:CCZ FLAGS_REG)
15581                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15582                                 (const_int 0)))
15583               (set (match_operand:DI 0 "register_operand" "")
15584                    (ctz:DI (match_dup 1)))])
15585    (set (match_dup 0) (if_then_else:DI
15586                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15587                         (match_dup 2)
15588                         (match_dup 0)))
15589    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15590               (clobber (reg:CC FLAGS_REG))])]
15591   "TARGET_64BIT"
15592   "operands[2] = gen_reg_rtx (DImode);")
15593
15594 (define_insn "*ffsdi_1"
15595   [(set (reg:CCZ FLAGS_REG)
15596         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15597                      (const_int 0)))
15598    (set (match_operand:DI 0 "register_operand" "=r")
15599         (ctz:DI (match_dup 1)))]
15600   "TARGET_64BIT"
15601   "bsf{q}\t{%1, %0|%0, %1}"
15602   [(set_attr "prefix_0f" "1")])
15603
15604 (define_insn "ctzsi2"
15605   [(set (match_operand:SI 0 "register_operand" "=r")
15606         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15607    (clobber (reg:CC FLAGS_REG))]
15608   ""
15609   "bsf{l}\t{%1, %0|%0, %1}"
15610   [(set_attr "prefix_0f" "1")])
15611
15612 (define_insn "ctzdi2"
15613   [(set (match_operand:DI 0 "register_operand" "=r")
15614         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15615    (clobber (reg:CC FLAGS_REG))]
15616   "TARGET_64BIT"
15617   "bsf{q}\t{%1, %0|%0, %1}"
15618   [(set_attr "prefix_0f" "1")])
15619
15620 (define_expand "clzsi2"
15621   [(parallel
15622      [(set (match_operand:SI 0 "register_operand" "")
15623            (minus:SI (const_int 31)
15624                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15625       (clobber (reg:CC FLAGS_REG))])
15626    (parallel
15627      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15628       (clobber (reg:CC FLAGS_REG))])]
15629   ""
15630 {
15631   if (TARGET_ABM)
15632     {
15633       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15634       DONE;
15635     }
15636 })
15637
15638 (define_insn "clzsi2_abm"
15639   [(set (match_operand:SI 0 "register_operand" "=r")
15640         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15641    (clobber (reg:CC FLAGS_REG))]
15642   "TARGET_ABM"
15643   "lzcnt{l}\t{%1, %0|%0, %1}"
15644   [(set_attr "prefix_rep" "1")
15645    (set_attr "type" "bitmanip")
15646    (set_attr "mode" "SI")])
15647
15648 (define_insn "*bsr"
15649   [(set (match_operand:SI 0 "register_operand" "=r")
15650         (minus:SI (const_int 31)
15651                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15652    (clobber (reg:CC FLAGS_REG))]
15653   ""
15654   "bsr{l}\t{%1, %0|%0, %1}"
15655   [(set_attr "prefix_0f" "1")
15656    (set_attr "mode" "SI")])
15657
15658 (define_insn "popcount<mode>2"
15659   [(set (match_operand:SWI248 0 "register_operand" "=r")
15660         (popcount:SWI248
15661           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15662    (clobber (reg:CC FLAGS_REG))]
15663   "TARGET_POPCNT"
15664 {
15665 #if TARGET_MACHO
15666   return "popcnt\t{%1, %0|%0, %1}";
15667 #else
15668   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15669 #endif
15670 }
15671   [(set_attr "prefix_rep" "1")
15672    (set_attr "type" "bitmanip")
15673    (set_attr "mode" "<MODE>")])
15674
15675 (define_insn "*popcount<mode>2_cmp"
15676   [(set (reg FLAGS_REG)
15677         (compare
15678           (popcount:SWI248
15679             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15680           (const_int 0)))
15681    (set (match_operand:SWI248 0 "register_operand" "=r")
15682         (popcount:SWI248 (match_dup 1)))]
15683   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15684 {
15685 #if TARGET_MACHO
15686   return "popcnt\t{%1, %0|%0, %1}";
15687 #else
15688   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15689 #endif
15690 }
15691   [(set_attr "prefix_rep" "1")
15692    (set_attr "type" "bitmanip")
15693    (set_attr "mode" "<MODE>")])
15694
15695 (define_insn "*popcountsi2_cmp_zext"
15696   [(set (reg FLAGS_REG)
15697         (compare
15698           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15699           (const_int 0)))
15700    (set (match_operand:DI 0 "register_operand" "=r")
15701         (zero_extend:DI(popcount:SI (match_dup 1))))]
15702   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15703 {
15704 #if TARGET_MACHO
15705   return "popcnt\t{%1, %0|%0, %1}";
15706 #else
15707   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15708 #endif
15709 }
15710   [(set_attr "prefix_rep" "1")
15711    (set_attr "type" "bitmanip")
15712    (set_attr "mode" "SI")])
15713
15714 (define_expand "bswapsi2"
15715   [(set (match_operand:SI 0 "register_operand" "")
15716         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15717   ""
15718 {
15719   if (!TARGET_BSWAP)
15720     {
15721       rtx x = operands[0];
15722
15723       emit_move_insn (x, operands[1]);
15724       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15725       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15726       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15727       DONE;
15728     }
15729 })
15730
15731 (define_insn "*bswapsi_1"
15732   [(set (match_operand:SI 0 "register_operand" "=r")
15733         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15734   "TARGET_BSWAP"
15735   "bswap\t%0"
15736   [(set_attr "prefix_0f" "1")
15737    (set_attr "length" "2")])
15738
15739 (define_insn "*bswaphi_lowpart_1"
15740   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15741         (bswap:HI (match_dup 0)))
15742    (clobber (reg:CC FLAGS_REG))]
15743   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15744   "@
15745     xchg{b}\t{%h0, %b0|%b0, %h0}
15746     rol{w}\t{$8, %0|%0, 8}"
15747   [(set_attr "length" "2,4")
15748    (set_attr "mode" "QI,HI")])
15749
15750 (define_insn "bswaphi_lowpart"
15751   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15752         (bswap:HI (match_dup 0)))
15753    (clobber (reg:CC FLAGS_REG))]
15754   ""
15755   "rol{w}\t{$8, %0|%0, 8}"
15756   [(set_attr "length" "4")
15757    (set_attr "mode" "HI")])
15758
15759 (define_insn "bswapdi2"
15760   [(set (match_operand:DI 0 "register_operand" "=r")
15761         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15762   "TARGET_64BIT"
15763   "bswap\t%0"
15764   [(set_attr "prefix_0f" "1")
15765    (set_attr "length" "3")])
15766
15767 (define_expand "clzdi2"
15768   [(parallel
15769      [(set (match_operand:DI 0 "register_operand" "")
15770            (minus:DI (const_int 63)
15771                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15772       (clobber (reg:CC FLAGS_REG))])
15773    (parallel
15774      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15775       (clobber (reg:CC FLAGS_REG))])]
15776   "TARGET_64BIT"
15777 {
15778   if (TARGET_ABM)
15779     {
15780       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15781       DONE;
15782     }
15783 })
15784
15785 (define_insn "clzdi2_abm"
15786   [(set (match_operand:DI 0 "register_operand" "=r")
15787         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15788    (clobber (reg:CC FLAGS_REG))]
15789   "TARGET_64BIT && TARGET_ABM"
15790   "lzcnt{q}\t{%1, %0|%0, %1}"
15791   [(set_attr "prefix_rep" "1")
15792    (set_attr "type" "bitmanip")
15793    (set_attr "mode" "DI")])
15794
15795 (define_insn "*bsr_rex64"
15796   [(set (match_operand:DI 0 "register_operand" "=r")
15797         (minus:DI (const_int 63)
15798                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15799    (clobber (reg:CC FLAGS_REG))]
15800   "TARGET_64BIT"
15801   "bsr{q}\t{%1, %0|%0, %1}"
15802   [(set_attr "prefix_0f" "1")
15803    (set_attr "mode" "DI")])
15804
15805 (define_expand "clzhi2"
15806   [(parallel
15807      [(set (match_operand:HI 0 "register_operand" "")
15808            (minus:HI (const_int 15)
15809                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15810       (clobber (reg:CC FLAGS_REG))])
15811    (parallel
15812      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15813       (clobber (reg:CC FLAGS_REG))])]
15814   ""
15815 {
15816   if (TARGET_ABM)
15817     {
15818       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15819       DONE;
15820     }
15821 })
15822
15823 (define_insn "clzhi2_abm"
15824   [(set (match_operand:HI 0 "register_operand" "=r")
15825         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15826    (clobber (reg:CC FLAGS_REG))]
15827   "TARGET_ABM"
15828   "lzcnt{w}\t{%1, %0|%0, %1}"
15829   [(set_attr "prefix_rep" "1")
15830    (set_attr "type" "bitmanip")
15831    (set_attr "mode" "HI")])
15832
15833 (define_insn "*bsrhi"
15834   [(set (match_operand:HI 0 "register_operand" "=r")
15835         (minus:HI (const_int 15)
15836                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15837    (clobber (reg:CC FLAGS_REG))]
15838   ""
15839   "bsr{w}\t{%1, %0|%0, %1}"
15840   [(set_attr "prefix_0f" "1")
15841    (set_attr "mode" "HI")])
15842
15843 (define_expand "paritydi2"
15844   [(set (match_operand:DI 0 "register_operand" "")
15845         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15846   "! TARGET_POPCNT"
15847 {
15848   rtx scratch = gen_reg_rtx (QImode);
15849   rtx cond;
15850
15851   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15852                                 NULL_RTX, operands[1]));
15853
15854   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15855                          gen_rtx_REG (CCmode, FLAGS_REG),
15856                          const0_rtx);
15857   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15858
15859   if (TARGET_64BIT)
15860     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15861   else
15862     {
15863       rtx tmp = gen_reg_rtx (SImode);
15864
15865       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15866       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15867     }
15868   DONE;
15869 })
15870
15871 (define_insn_and_split "paritydi2_cmp"
15872   [(set (reg:CC FLAGS_REG)
15873         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15874    (clobber (match_scratch:DI 0 "=r"))
15875    (clobber (match_scratch:SI 1 "=&r"))
15876    (clobber (match_scratch:HI 2 "=Q"))]
15877   "! TARGET_POPCNT"
15878   "#"
15879   "&& reload_completed"
15880   [(parallel
15881      [(set (match_dup 1)
15882            (xor:SI (match_dup 1) (match_dup 4)))
15883       (clobber (reg:CC FLAGS_REG))])
15884    (parallel
15885      [(set (reg:CC FLAGS_REG)
15886            (parity:CC (match_dup 1)))
15887       (clobber (match_dup 1))
15888       (clobber (match_dup 2))])]
15889 {
15890   operands[4] = gen_lowpart (SImode, operands[3]);
15891
15892   if (TARGET_64BIT)
15893     {
15894       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15895       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15896     }
15897   else
15898     operands[1] = gen_highpart (SImode, operands[3]);
15899 })
15900
15901 (define_expand "paritysi2"
15902   [(set (match_operand:SI 0 "register_operand" "")
15903         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15904   "! TARGET_POPCNT"
15905 {
15906   rtx scratch = gen_reg_rtx (QImode);
15907   rtx cond;
15908
15909   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15910
15911   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15912                          gen_rtx_REG (CCmode, FLAGS_REG),
15913                          const0_rtx);
15914   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15915
15916   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15917   DONE;
15918 })
15919
15920 (define_insn_and_split "paritysi2_cmp"
15921   [(set (reg:CC FLAGS_REG)
15922         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15923    (clobber (match_scratch:SI 0 "=r"))
15924    (clobber (match_scratch:HI 1 "=&Q"))]
15925   "! TARGET_POPCNT"
15926   "#"
15927   "&& reload_completed"
15928   [(parallel
15929      [(set (match_dup 1)
15930            (xor:HI (match_dup 1) (match_dup 3)))
15931       (clobber (reg:CC FLAGS_REG))])
15932    (parallel
15933      [(set (reg:CC FLAGS_REG)
15934            (parity:CC (match_dup 1)))
15935       (clobber (match_dup 1))])]
15936 {
15937   operands[3] = gen_lowpart (HImode, operands[2]);
15938
15939   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15940   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15941 })
15942
15943 (define_insn "*parityhi2_cmp"
15944   [(set (reg:CC FLAGS_REG)
15945         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15946    (clobber (match_scratch:HI 0 "=Q"))]
15947   "! TARGET_POPCNT"
15948   "xor{b}\t{%h0, %b0|%b0, %h0}"
15949   [(set_attr "length" "2")
15950    (set_attr "mode" "HI")])
15951
15952 (define_insn "*parityqi2_cmp"
15953   [(set (reg:CC FLAGS_REG)
15954         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15955   "! TARGET_POPCNT"
15956   "test{b}\t%0, %0"
15957   [(set_attr "length" "2")
15958    (set_attr "mode" "QI")])
15959 \f
15960 ;; Thread-local storage patterns for ELF.
15961 ;;
15962 ;; Note that these code sequences must appear exactly as shown
15963 ;; in order to allow linker relaxation.
15964
15965 (define_insn "*tls_global_dynamic_32_gnu"
15966   [(set (match_operand:SI 0 "register_operand" "=a")
15967         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15968                     (match_operand:SI 2 "tls_symbolic_operand" "")
15969                     (match_operand:SI 3 "call_insn_operand" "")]
15970                     UNSPEC_TLS_GD))
15971    (clobber (match_scratch:SI 4 "=d"))
15972    (clobber (match_scratch:SI 5 "=c"))
15973    (clobber (reg:CC FLAGS_REG))]
15974   "!TARGET_64BIT && TARGET_GNU_TLS"
15975   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15976   [(set_attr "type" "multi")
15977    (set_attr "length" "12")])
15978
15979 (define_insn "*tls_global_dynamic_32_sun"
15980   [(set (match_operand:SI 0 "register_operand" "=a")
15981         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15982                     (match_operand:SI 2 "tls_symbolic_operand" "")
15983                     (match_operand:SI 3 "call_insn_operand" "")]
15984                     UNSPEC_TLS_GD))
15985    (clobber (match_scratch:SI 4 "=d"))
15986    (clobber (match_scratch:SI 5 "=c"))
15987    (clobber (reg:CC FLAGS_REG))]
15988   "!TARGET_64BIT && TARGET_SUN_TLS"
15989   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15990         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15991   [(set_attr "type" "multi")
15992    (set_attr "length" "14")])
15993
15994 (define_expand "tls_global_dynamic_32"
15995   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15996                    (unspec:SI
15997                     [(match_dup 2)
15998                      (match_operand:SI 1 "tls_symbolic_operand" "")
15999                      (match_dup 3)]
16000                     UNSPEC_TLS_GD))
16001               (clobber (match_scratch:SI 4 ""))
16002               (clobber (match_scratch:SI 5 ""))
16003               (clobber (reg:CC FLAGS_REG))])]
16004   ""
16005 {
16006   if (flag_pic)
16007     operands[2] = pic_offset_table_rtx;
16008   else
16009     {
16010       operands[2] = gen_reg_rtx (Pmode);
16011       emit_insn (gen_set_got (operands[2]));
16012     }
16013   if (TARGET_GNU2_TLS)
16014     {
16015        emit_insn (gen_tls_dynamic_gnu2_32
16016                   (operands[0], operands[1], operands[2]));
16017        DONE;
16018     }
16019   operands[3] = ix86_tls_get_addr ();
16020 })
16021
16022 (define_insn "*tls_global_dynamic_64"
16023   [(set (match_operand:DI 0 "register_operand" "=a")
16024         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16025                  (match_operand:DI 3 "" "")))
16026    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16027               UNSPEC_TLS_GD)]
16028   "TARGET_64BIT"
16029   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
16030   [(set_attr "type" "multi")
16031    (set_attr "length" "16")])
16032
16033 (define_expand "tls_global_dynamic_64"
16034   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16035                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16036               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16037                          UNSPEC_TLS_GD)])]
16038   ""
16039 {
16040   if (TARGET_GNU2_TLS)
16041     {
16042        emit_insn (gen_tls_dynamic_gnu2_64
16043                   (operands[0], operands[1]));
16044        DONE;
16045     }
16046   operands[2] = ix86_tls_get_addr ();
16047 })
16048
16049 (define_insn "*tls_local_dynamic_base_32_gnu"
16050   [(set (match_operand:SI 0 "register_operand" "=a")
16051         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16052                     (match_operand:SI 2 "call_insn_operand" "")]
16053                    UNSPEC_TLS_LD_BASE))
16054    (clobber (match_scratch:SI 3 "=d"))
16055    (clobber (match_scratch:SI 4 "=c"))
16056    (clobber (reg:CC FLAGS_REG))]
16057   "!TARGET_64BIT && TARGET_GNU_TLS"
16058   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16059   [(set_attr "type" "multi")
16060    (set_attr "length" "11")])
16061
16062 (define_insn "*tls_local_dynamic_base_32_sun"
16063   [(set (match_operand:SI 0 "register_operand" "=a")
16064         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16065                     (match_operand:SI 2 "call_insn_operand" "")]
16066                    UNSPEC_TLS_LD_BASE))
16067    (clobber (match_scratch:SI 3 "=d"))
16068    (clobber (match_scratch:SI 4 "=c"))
16069    (clobber (reg:CC FLAGS_REG))]
16070   "!TARGET_64BIT && TARGET_SUN_TLS"
16071   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16072         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16073   [(set_attr "type" "multi")
16074    (set_attr "length" "13")])
16075
16076 (define_expand "tls_local_dynamic_base_32"
16077   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16078                    (unspec:SI [(match_dup 1) (match_dup 2)]
16079                               UNSPEC_TLS_LD_BASE))
16080               (clobber (match_scratch:SI 3 ""))
16081               (clobber (match_scratch:SI 4 ""))
16082               (clobber (reg:CC FLAGS_REG))])]
16083   ""
16084 {
16085   if (flag_pic)
16086     operands[1] = pic_offset_table_rtx;
16087   else
16088     {
16089       operands[1] = gen_reg_rtx (Pmode);
16090       emit_insn (gen_set_got (operands[1]));
16091     }
16092   if (TARGET_GNU2_TLS)
16093     {
16094        emit_insn (gen_tls_dynamic_gnu2_32
16095                   (operands[0], ix86_tls_module_base (), operands[1]));
16096        DONE;
16097     }
16098   operands[2] = ix86_tls_get_addr ();
16099 })
16100
16101 (define_insn "*tls_local_dynamic_base_64"
16102   [(set (match_operand:DI 0 "register_operand" "=a")
16103         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16104                  (match_operand:DI 2 "" "")))
16105    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16106   "TARGET_64BIT"
16107   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16108   [(set_attr "type" "multi")
16109    (set_attr "length" "12")])
16110
16111 (define_expand "tls_local_dynamic_base_64"
16112   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16113                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16114               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16115   ""
16116 {
16117   if (TARGET_GNU2_TLS)
16118     {
16119        emit_insn (gen_tls_dynamic_gnu2_64
16120                   (operands[0], ix86_tls_module_base ()));
16121        DONE;
16122     }
16123   operands[1] = ix86_tls_get_addr ();
16124 })
16125
16126 ;; Local dynamic of a single variable is a lose.  Show combine how
16127 ;; to convert that back to global dynamic.
16128
16129 (define_insn_and_split "*tls_local_dynamic_32_once"
16130   [(set (match_operand:SI 0 "register_operand" "=a")
16131         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16132                              (match_operand:SI 2 "call_insn_operand" "")]
16133                             UNSPEC_TLS_LD_BASE)
16134                  (const:SI (unspec:SI
16135                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16136                             UNSPEC_DTPOFF))))
16137    (clobber (match_scratch:SI 4 "=d"))
16138    (clobber (match_scratch:SI 5 "=c"))
16139    (clobber (reg:CC FLAGS_REG))]
16140   ""
16141   "#"
16142   ""
16143   [(parallel [(set (match_dup 0)
16144                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16145                               UNSPEC_TLS_GD))
16146               (clobber (match_dup 4))
16147               (clobber (match_dup 5))
16148               (clobber (reg:CC FLAGS_REG))])]
16149   "")
16150
16151 ;; Load and add the thread base pointer from %gs:0.
16152
16153 (define_insn "*load_tp_si"
16154   [(set (match_operand:SI 0 "register_operand" "=r")
16155         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16156   "!TARGET_64BIT"
16157   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16158   [(set_attr "type" "imov")
16159    (set_attr "modrm" "0")
16160    (set_attr "length" "7")
16161    (set_attr "memory" "load")
16162    (set_attr "imm_disp" "false")])
16163
16164 (define_insn "*add_tp_si"
16165   [(set (match_operand:SI 0 "register_operand" "=r")
16166         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16167                  (match_operand:SI 1 "register_operand" "0")))
16168    (clobber (reg:CC FLAGS_REG))]
16169   "!TARGET_64BIT"
16170   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16171   [(set_attr "type" "alu")
16172    (set_attr "modrm" "0")
16173    (set_attr "length" "7")
16174    (set_attr "memory" "load")
16175    (set_attr "imm_disp" "false")])
16176
16177 (define_insn "*load_tp_di"
16178   [(set (match_operand:DI 0 "register_operand" "=r")
16179         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16180   "TARGET_64BIT"
16181   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16182   [(set_attr "type" "imov")
16183    (set_attr "modrm" "0")
16184    (set_attr "length" "7")
16185    (set_attr "memory" "load")
16186    (set_attr "imm_disp" "false")])
16187
16188 (define_insn "*add_tp_di"
16189   [(set (match_operand:DI 0 "register_operand" "=r")
16190         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16191                  (match_operand:DI 1 "register_operand" "0")))
16192    (clobber (reg:CC FLAGS_REG))]
16193   "TARGET_64BIT"
16194   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16195   [(set_attr "type" "alu")
16196    (set_attr "modrm" "0")
16197    (set_attr "length" "7")
16198    (set_attr "memory" "load")
16199    (set_attr "imm_disp" "false")])
16200
16201 ;; GNU2 TLS patterns can be split.
16202
16203 (define_expand "tls_dynamic_gnu2_32"
16204   [(set (match_dup 3)
16205         (plus:SI (match_operand:SI 2 "register_operand" "")
16206                  (const:SI
16207                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16208                              UNSPEC_TLSDESC))))
16209    (parallel
16210     [(set (match_operand:SI 0 "register_operand" "")
16211           (unspec:SI [(match_dup 1) (match_dup 3)
16212                       (match_dup 2) (reg:SI SP_REG)]
16213                       UNSPEC_TLSDESC))
16214      (clobber (reg:CC FLAGS_REG))])]
16215   "!TARGET_64BIT && TARGET_GNU2_TLS"
16216 {
16217   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16218   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16219 })
16220
16221 (define_insn "*tls_dynamic_lea_32"
16222   [(set (match_operand:SI 0 "register_operand" "=r")
16223         (plus:SI (match_operand:SI 1 "register_operand" "b")
16224                  (const:SI
16225                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16226                               UNSPEC_TLSDESC))))]
16227   "!TARGET_64BIT && TARGET_GNU2_TLS"
16228   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16229   [(set_attr "type" "lea")
16230    (set_attr "mode" "SI")
16231    (set_attr "length" "6")
16232    (set_attr "length_address" "4")])
16233
16234 (define_insn "*tls_dynamic_call_32"
16235   [(set (match_operand:SI 0 "register_operand" "=a")
16236         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16237                     (match_operand:SI 2 "register_operand" "0")
16238                     ;; we have to make sure %ebx still points to the GOT
16239                     (match_operand:SI 3 "register_operand" "b")
16240                     (reg:SI SP_REG)]
16241                    UNSPEC_TLSDESC))
16242    (clobber (reg:CC FLAGS_REG))]
16243   "!TARGET_64BIT && TARGET_GNU2_TLS"
16244   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16245   [(set_attr "type" "call")
16246    (set_attr "length" "2")
16247    (set_attr "length_address" "0")])
16248
16249 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16250   [(set (match_operand:SI 0 "register_operand" "=&a")
16251         (plus:SI
16252          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16253                      (match_operand:SI 4 "" "")
16254                      (match_operand:SI 2 "register_operand" "b")
16255                      (reg:SI SP_REG)]
16256                     UNSPEC_TLSDESC)
16257          (const:SI (unspec:SI
16258                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16259                     UNSPEC_DTPOFF))))
16260    (clobber (reg:CC FLAGS_REG))]
16261   "!TARGET_64BIT && TARGET_GNU2_TLS"
16262   "#"
16263   ""
16264   [(set (match_dup 0) (match_dup 5))]
16265 {
16266   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16267   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16268 })
16269
16270 (define_expand "tls_dynamic_gnu2_64"
16271   [(set (match_dup 2)
16272         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16273                    UNSPEC_TLSDESC))
16274    (parallel
16275     [(set (match_operand:DI 0 "register_operand" "")
16276           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16277                      UNSPEC_TLSDESC))
16278      (clobber (reg:CC FLAGS_REG))])]
16279   "TARGET_64BIT && TARGET_GNU2_TLS"
16280 {
16281   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16282   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16283 })
16284
16285 (define_insn "*tls_dynamic_lea_64"
16286   [(set (match_operand:DI 0 "register_operand" "=r")
16287         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16288                    UNSPEC_TLSDESC))]
16289   "TARGET_64BIT && TARGET_GNU2_TLS"
16290   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16291   [(set_attr "type" "lea")
16292    (set_attr "mode" "DI")
16293    (set_attr "length" "7")
16294    (set_attr "length_address" "4")])
16295
16296 (define_insn "*tls_dynamic_call_64"
16297   [(set (match_operand:DI 0 "register_operand" "=a")
16298         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16299                     (match_operand:DI 2 "register_operand" "0")
16300                     (reg:DI SP_REG)]
16301                    UNSPEC_TLSDESC))
16302    (clobber (reg:CC FLAGS_REG))]
16303   "TARGET_64BIT && TARGET_GNU2_TLS"
16304   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16305   [(set_attr "type" "call")
16306    (set_attr "length" "2")
16307    (set_attr "length_address" "0")])
16308
16309 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16310   [(set (match_operand:DI 0 "register_operand" "=&a")
16311         (plus:DI
16312          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16313                      (match_operand:DI 3 "" "")
16314                      (reg:DI SP_REG)]
16315                     UNSPEC_TLSDESC)
16316          (const:DI (unspec:DI
16317                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16318                     UNSPEC_DTPOFF))))
16319    (clobber (reg:CC FLAGS_REG))]
16320   "TARGET_64BIT && TARGET_GNU2_TLS"
16321   "#"
16322   ""
16323   [(set (match_dup 0) (match_dup 4))]
16324 {
16325   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16326   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16327 })
16328
16329 ;;
16330 \f
16331 ;; These patterns match the binary 387 instructions for addM3, subM3,
16332 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16333 ;; SFmode.  The first is the normal insn, the second the same insn but
16334 ;; with one operand a conversion, and the third the same insn but with
16335 ;; the other operand a conversion.  The conversion may be SFmode or
16336 ;; SImode if the target mode DFmode, but only SImode if the target mode
16337 ;; is SFmode.
16338
16339 ;; Gcc is slightly more smart about handling normal two address instructions
16340 ;; so use special patterns for add and mull.
16341
16342 (define_insn "*fop_<mode>_comm_mixed_avx"
16343   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16344         (match_operator:MODEF 3 "binary_fp_operator"
16345           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16346            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16347   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16348    && COMMUTATIVE_ARITH_P (operands[3])
16349    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16350   "* return output_387_binary_op (insn, operands);"
16351   [(set (attr "type")
16352         (if_then_else (eq_attr "alternative" "1")
16353            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16354               (const_string "ssemul")
16355               (const_string "sseadd"))
16356            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16357               (const_string "fmul")
16358               (const_string "fop"))))
16359    (set_attr "prefix" "orig,maybe_vex")
16360    (set_attr "mode" "<MODE>")])
16361
16362 (define_insn "*fop_<mode>_comm_mixed"
16363   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16364         (match_operator:MODEF 3 "binary_fp_operator"
16365           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16366            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16367   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16368    && COMMUTATIVE_ARITH_P (operands[3])
16369    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16370   "* return output_387_binary_op (insn, operands);"
16371   [(set (attr "type")
16372         (if_then_else (eq_attr "alternative" "1")
16373            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16374               (const_string "ssemul")
16375               (const_string "sseadd"))
16376            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16377               (const_string "fmul")
16378               (const_string "fop"))))
16379    (set_attr "mode" "<MODE>")])
16380
16381 (define_insn "*fop_<mode>_comm_avx"
16382   [(set (match_operand:MODEF 0 "register_operand" "=x")
16383         (match_operator:MODEF 3 "binary_fp_operator"
16384           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16385            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16386   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16387    && COMMUTATIVE_ARITH_P (operands[3])
16388    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16389   "* return output_387_binary_op (insn, operands);"
16390   [(set (attr "type")
16391         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16392            (const_string "ssemul")
16393            (const_string "sseadd")))
16394    (set_attr "prefix" "vex")
16395    (set_attr "mode" "<MODE>")])
16396
16397 (define_insn "*fop_<mode>_comm_sse"
16398   [(set (match_operand:MODEF 0 "register_operand" "=x")
16399         (match_operator:MODEF 3 "binary_fp_operator"
16400           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16401            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16402   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16403    && COMMUTATIVE_ARITH_P (operands[3])
16404    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16405   "* return output_387_binary_op (insn, operands);"
16406   [(set (attr "type")
16407         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16408            (const_string "ssemul")
16409            (const_string "sseadd")))
16410    (set_attr "mode" "<MODE>")])
16411
16412 (define_insn "*fop_<mode>_comm_i387"
16413   [(set (match_operand:MODEF 0 "register_operand" "=f")
16414         (match_operator:MODEF 3 "binary_fp_operator"
16415           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16416            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16417   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16418    && COMMUTATIVE_ARITH_P (operands[3])
16419    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16420   "* return output_387_binary_op (insn, operands);"
16421   [(set (attr "type")
16422         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16423            (const_string "fmul")
16424            (const_string "fop")))
16425    (set_attr "mode" "<MODE>")])
16426
16427 (define_insn "*fop_<mode>_1_mixed_avx"
16428   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16429         (match_operator:MODEF 3 "binary_fp_operator"
16430           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16431            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16432   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16433    && !COMMUTATIVE_ARITH_P (operands[3])
16434    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16435   "* return output_387_binary_op (insn, operands);"
16436   [(set (attr "type")
16437         (cond [(and (eq_attr "alternative" "2")
16438                     (match_operand:MODEF 3 "mult_operator" ""))
16439                  (const_string "ssemul")
16440                (and (eq_attr "alternative" "2")
16441                     (match_operand:MODEF 3 "div_operator" ""))
16442                  (const_string "ssediv")
16443                (eq_attr "alternative" "2")
16444                  (const_string "sseadd")
16445                (match_operand:MODEF 3 "mult_operator" "")
16446                  (const_string "fmul")
16447                (match_operand:MODEF 3 "div_operator" "")
16448                  (const_string "fdiv")
16449               ]
16450               (const_string "fop")))
16451    (set_attr "prefix" "orig,orig,maybe_vex")
16452    (set_attr "mode" "<MODE>")])
16453
16454 (define_insn "*fop_<mode>_1_mixed"
16455   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16456         (match_operator:MODEF 3 "binary_fp_operator"
16457           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16458            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16459   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16460    && !COMMUTATIVE_ARITH_P (operands[3])
16461    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16462   "* return output_387_binary_op (insn, operands);"
16463   [(set (attr "type")
16464         (cond [(and (eq_attr "alternative" "2")
16465                     (match_operand:MODEF 3 "mult_operator" ""))
16466                  (const_string "ssemul")
16467                (and (eq_attr "alternative" "2")
16468                     (match_operand:MODEF 3 "div_operator" ""))
16469                  (const_string "ssediv")
16470                (eq_attr "alternative" "2")
16471                  (const_string "sseadd")
16472                (match_operand:MODEF 3 "mult_operator" "")
16473                  (const_string "fmul")
16474                (match_operand:MODEF 3 "div_operator" "")
16475                  (const_string "fdiv")
16476               ]
16477               (const_string "fop")))
16478    (set_attr "mode" "<MODE>")])
16479
16480 (define_insn "*rcpsf2_sse"
16481   [(set (match_operand:SF 0 "register_operand" "=x")
16482         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16483                    UNSPEC_RCP))]
16484   "TARGET_SSE_MATH"
16485   "%vrcpss\t{%1, %d0|%d0, %1}"
16486   [(set_attr "type" "sse")
16487    (set_attr "atom_sse_attr" "rcp")
16488    (set_attr "prefix" "maybe_vex")
16489    (set_attr "mode" "SF")])
16490
16491 (define_insn "*fop_<mode>_1_avx"
16492   [(set (match_operand:MODEF 0 "register_operand" "=x")
16493         (match_operator:MODEF 3 "binary_fp_operator"
16494           [(match_operand:MODEF 1 "register_operand" "x")
16495            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16496   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16497    && !COMMUTATIVE_ARITH_P (operands[3])"
16498   "* return output_387_binary_op (insn, operands);"
16499   [(set (attr "type")
16500         (cond [(match_operand:MODEF 3 "mult_operator" "")
16501                  (const_string "ssemul")
16502                (match_operand:MODEF 3 "div_operator" "")
16503                  (const_string "ssediv")
16504               ]
16505               (const_string "sseadd")))
16506    (set_attr "prefix" "vex")
16507    (set_attr "mode" "<MODE>")])
16508
16509 (define_insn "*fop_<mode>_1_sse"
16510   [(set (match_operand:MODEF 0 "register_operand" "=x")
16511         (match_operator:MODEF 3 "binary_fp_operator"
16512           [(match_operand:MODEF 1 "register_operand" "0")
16513            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16514   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16515    && !COMMUTATIVE_ARITH_P (operands[3])"
16516   "* return output_387_binary_op (insn, operands);"
16517   [(set (attr "type")
16518         (cond [(match_operand:MODEF 3 "mult_operator" "")
16519                  (const_string "ssemul")
16520                (match_operand:MODEF 3 "div_operator" "")
16521                  (const_string "ssediv")
16522               ]
16523               (const_string "sseadd")))
16524    (set_attr "mode" "<MODE>")])
16525
16526 ;; This pattern is not fully shadowed by the pattern above.
16527 (define_insn "*fop_<mode>_1_i387"
16528   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16529         (match_operator:MODEF 3 "binary_fp_operator"
16530           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16531            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16532   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16533    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16534    && !COMMUTATIVE_ARITH_P (operands[3])
16535    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16536   "* return output_387_binary_op (insn, operands);"
16537   [(set (attr "type")
16538         (cond [(match_operand:MODEF 3 "mult_operator" "")
16539                  (const_string "fmul")
16540                (match_operand:MODEF 3 "div_operator" "")
16541                  (const_string "fdiv")
16542               ]
16543               (const_string "fop")))
16544    (set_attr "mode" "<MODE>")])
16545
16546 ;; ??? Add SSE splitters for these!
16547 (define_insn "*fop_<MODEF:mode>_2_i387"
16548   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16549         (match_operator:MODEF 3 "binary_fp_operator"
16550           [(float:MODEF
16551              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16552            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16553   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16554    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16555    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16556   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16557   [(set (attr "type")
16558         (cond [(match_operand:MODEF 3 "mult_operator" "")
16559                  (const_string "fmul")
16560                (match_operand:MODEF 3 "div_operator" "")
16561                  (const_string "fdiv")
16562               ]
16563               (const_string "fop")))
16564    (set_attr "fp_int_src" "true")
16565    (set_attr "mode" "<X87MODEI12:MODE>")])
16566
16567 (define_insn "*fop_<MODEF:mode>_3_i387"
16568   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16569         (match_operator:MODEF 3 "binary_fp_operator"
16570           [(match_operand:MODEF 1 "register_operand" "0,0")
16571            (float:MODEF
16572              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16573   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16574    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16575    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16576   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16577   [(set (attr "type")
16578         (cond [(match_operand:MODEF 3 "mult_operator" "")
16579                  (const_string "fmul")
16580                (match_operand:MODEF 3 "div_operator" "")
16581                  (const_string "fdiv")
16582               ]
16583               (const_string "fop")))
16584    (set_attr "fp_int_src" "true")
16585    (set_attr "mode" "<MODE>")])
16586
16587 (define_insn "*fop_df_4_i387"
16588   [(set (match_operand:DF 0 "register_operand" "=f,f")
16589         (match_operator:DF 3 "binary_fp_operator"
16590            [(float_extend:DF
16591              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16592             (match_operand:DF 2 "register_operand" "0,f")]))]
16593   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16594    && !(TARGET_SSE2 && TARGET_SSE_MATH)
16595    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16596   "* return output_387_binary_op (insn, operands);"
16597   [(set (attr "type")
16598         (cond [(match_operand:DF 3 "mult_operator" "")
16599                  (const_string "fmul")
16600                (match_operand:DF 3 "div_operator" "")
16601                  (const_string "fdiv")
16602               ]
16603               (const_string "fop")))
16604    (set_attr "mode" "SF")])
16605
16606 (define_insn "*fop_df_5_i387"
16607   [(set (match_operand:DF 0 "register_operand" "=f,f")
16608         (match_operator:DF 3 "binary_fp_operator"
16609           [(match_operand:DF 1 "register_operand" "0,f")
16610            (float_extend:DF
16611             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16612   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16613    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16614   "* return output_387_binary_op (insn, operands);"
16615   [(set (attr "type")
16616         (cond [(match_operand:DF 3 "mult_operator" "")
16617                  (const_string "fmul")
16618                (match_operand:DF 3 "div_operator" "")
16619                  (const_string "fdiv")
16620               ]
16621               (const_string "fop")))
16622    (set_attr "mode" "SF")])
16623
16624 (define_insn "*fop_df_6_i387"
16625   [(set (match_operand:DF 0 "register_operand" "=f,f")
16626         (match_operator:DF 3 "binary_fp_operator"
16627           [(float_extend:DF
16628             (match_operand:SF 1 "register_operand" "0,f"))
16629            (float_extend:DF
16630             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16631   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16632    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16633   "* return output_387_binary_op (insn, operands);"
16634   [(set (attr "type")
16635         (cond [(match_operand:DF 3 "mult_operator" "")
16636                  (const_string "fmul")
16637                (match_operand:DF 3 "div_operator" "")
16638                  (const_string "fdiv")
16639               ]
16640               (const_string "fop")))
16641    (set_attr "mode" "SF")])
16642
16643 (define_insn "*fop_xf_comm_i387"
16644   [(set (match_operand:XF 0 "register_operand" "=f")
16645         (match_operator:XF 3 "binary_fp_operator"
16646                         [(match_operand:XF 1 "register_operand" "%0")
16647                          (match_operand:XF 2 "register_operand" "f")]))]
16648   "TARGET_80387
16649    && COMMUTATIVE_ARITH_P (operands[3])"
16650   "* return output_387_binary_op (insn, operands);"
16651   [(set (attr "type")
16652         (if_then_else (match_operand:XF 3 "mult_operator" "")
16653            (const_string "fmul")
16654            (const_string "fop")))
16655    (set_attr "mode" "XF")])
16656
16657 (define_insn "*fop_xf_1_i387"
16658   [(set (match_operand:XF 0 "register_operand" "=f,f")
16659         (match_operator:XF 3 "binary_fp_operator"
16660                         [(match_operand:XF 1 "register_operand" "0,f")
16661                          (match_operand:XF 2 "register_operand" "f,0")]))]
16662   "TARGET_80387
16663    && !COMMUTATIVE_ARITH_P (operands[3])"
16664   "* return output_387_binary_op (insn, operands);"
16665   [(set (attr "type")
16666         (cond [(match_operand:XF 3 "mult_operator" "")
16667                  (const_string "fmul")
16668                (match_operand:XF 3 "div_operator" "")
16669                  (const_string "fdiv")
16670               ]
16671               (const_string "fop")))
16672    (set_attr "mode" "XF")])
16673
16674 (define_insn "*fop_xf_2_i387"
16675   [(set (match_operand:XF 0 "register_operand" "=f,f")
16676         (match_operator:XF 3 "binary_fp_operator"
16677           [(float:XF
16678              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16679            (match_operand:XF 2 "register_operand" "0,0")]))]
16680   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16681   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16682   [(set (attr "type")
16683         (cond [(match_operand:XF 3 "mult_operator" "")
16684                  (const_string "fmul")
16685                (match_operand:XF 3 "div_operator" "")
16686                  (const_string "fdiv")
16687               ]
16688               (const_string "fop")))
16689    (set_attr "fp_int_src" "true")
16690    (set_attr "mode" "<MODE>")])
16691
16692 (define_insn "*fop_xf_3_i387"
16693   [(set (match_operand:XF 0 "register_operand" "=f,f")
16694         (match_operator:XF 3 "binary_fp_operator"
16695           [(match_operand:XF 1 "register_operand" "0,0")
16696            (float:XF
16697              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16698   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16699   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16700   [(set (attr "type")
16701         (cond [(match_operand:XF 3 "mult_operator" "")
16702                  (const_string "fmul")
16703                (match_operand:XF 3 "div_operator" "")
16704                  (const_string "fdiv")
16705               ]
16706               (const_string "fop")))
16707    (set_attr "fp_int_src" "true")
16708    (set_attr "mode" "<MODE>")])
16709
16710 (define_insn "*fop_xf_4_i387"
16711   [(set (match_operand:XF 0 "register_operand" "=f,f")
16712         (match_operator:XF 3 "binary_fp_operator"
16713            [(float_extend:XF
16714               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16715             (match_operand:XF 2 "register_operand" "0,f")]))]
16716   "TARGET_80387"
16717   "* return output_387_binary_op (insn, operands);"
16718   [(set (attr "type")
16719         (cond [(match_operand:XF 3 "mult_operator" "")
16720                  (const_string "fmul")
16721                (match_operand:XF 3 "div_operator" "")
16722                  (const_string "fdiv")
16723               ]
16724               (const_string "fop")))
16725    (set_attr "mode" "<MODE>")])
16726
16727 (define_insn "*fop_xf_5_i387"
16728   [(set (match_operand:XF 0 "register_operand" "=f,f")
16729         (match_operator:XF 3 "binary_fp_operator"
16730           [(match_operand:XF 1 "register_operand" "0,f")
16731            (float_extend:XF
16732              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16733   "TARGET_80387"
16734   "* return output_387_binary_op (insn, operands);"
16735   [(set (attr "type")
16736         (cond [(match_operand:XF 3 "mult_operator" "")
16737                  (const_string "fmul")
16738                (match_operand:XF 3 "div_operator" "")
16739                  (const_string "fdiv")
16740               ]
16741               (const_string "fop")))
16742    (set_attr "mode" "<MODE>")])
16743
16744 (define_insn "*fop_xf_6_i387"
16745   [(set (match_operand:XF 0 "register_operand" "=f,f")
16746         (match_operator:XF 3 "binary_fp_operator"
16747           [(float_extend:XF
16748              (match_operand:MODEF 1 "register_operand" "0,f"))
16749            (float_extend:XF
16750              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16751   "TARGET_80387"
16752   "* return output_387_binary_op (insn, operands);"
16753   [(set (attr "type")
16754         (cond [(match_operand:XF 3 "mult_operator" "")
16755                  (const_string "fmul")
16756                (match_operand:XF 3 "div_operator" "")
16757                  (const_string "fdiv")
16758               ]
16759               (const_string "fop")))
16760    (set_attr "mode" "<MODE>")])
16761
16762 (define_split
16763   [(set (match_operand 0 "register_operand" "")
16764         (match_operator 3 "binary_fp_operator"
16765            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16766             (match_operand 2 "register_operand" "")]))]
16767   "reload_completed
16768    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16769    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16770   [(const_int 0)]
16771 {
16772   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16773   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16774   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16775                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16776                                           GET_MODE (operands[3]),
16777                                           operands[4],
16778                                           operands[2])));
16779   ix86_free_from_memory (GET_MODE (operands[1]));
16780   DONE;
16781 })
16782
16783 (define_split
16784   [(set (match_operand 0 "register_operand" "")
16785         (match_operator 3 "binary_fp_operator"
16786            [(match_operand 1 "register_operand" "")
16787             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16788   "reload_completed
16789    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16790    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16791   [(const_int 0)]
16792 {
16793   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16794   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16795   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16796                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16797                                           GET_MODE (operands[3]),
16798                                           operands[1],
16799                                           operands[4])));
16800   ix86_free_from_memory (GET_MODE (operands[2]));
16801   DONE;
16802 })
16803 \f
16804 ;; FPU special functions.
16805
16806 ;; This pattern implements a no-op XFmode truncation for
16807 ;; all fancy i386 XFmode math functions.
16808
16809 (define_insn "truncxf<mode>2_i387_noop_unspec"
16810   [(set (match_operand:MODEF 0 "register_operand" "=f")
16811         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16812         UNSPEC_TRUNC_NOOP))]
16813   "TARGET_USE_FANCY_MATH_387"
16814   "* return output_387_reg_move (insn, operands);"
16815   [(set_attr "type" "fmov")
16816    (set_attr "mode" "<MODE>")])
16817
16818 (define_insn "sqrtxf2"
16819   [(set (match_operand:XF 0 "register_operand" "=f")
16820         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16821   "TARGET_USE_FANCY_MATH_387"
16822   "fsqrt"
16823   [(set_attr "type" "fpspc")
16824    (set_attr "mode" "XF")
16825    (set_attr "athlon_decode" "direct")
16826    (set_attr "amdfam10_decode" "direct")])
16827
16828 (define_insn "sqrt_extend<mode>xf2_i387"
16829   [(set (match_operand:XF 0 "register_operand" "=f")
16830         (sqrt:XF
16831           (float_extend:XF
16832             (match_operand:MODEF 1 "register_operand" "0"))))]
16833   "TARGET_USE_FANCY_MATH_387"
16834   "fsqrt"
16835   [(set_attr "type" "fpspc")
16836    (set_attr "mode" "XF")
16837    (set_attr "athlon_decode" "direct")
16838    (set_attr "amdfam10_decode" "direct")])
16839
16840 (define_insn "*rsqrtsf2_sse"
16841   [(set (match_operand:SF 0 "register_operand" "=x")
16842         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16843                    UNSPEC_RSQRT))]
16844   "TARGET_SSE_MATH"
16845   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16846   [(set_attr "type" "sse")
16847    (set_attr "atom_sse_attr" "rcp")
16848    (set_attr "prefix" "maybe_vex")
16849    (set_attr "mode" "SF")])
16850
16851 (define_expand "rsqrtsf2"
16852   [(set (match_operand:SF 0 "register_operand" "")
16853         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16854                    UNSPEC_RSQRT))]
16855   "TARGET_SSE_MATH"
16856 {
16857   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16858   DONE;
16859 })
16860
16861 (define_insn "*sqrt<mode>2_sse"
16862   [(set (match_operand:MODEF 0 "register_operand" "=x")
16863         (sqrt:MODEF
16864           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16865   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16866   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16867   [(set_attr "type" "sse")
16868    (set_attr "atom_sse_attr" "sqrt")
16869    (set_attr "prefix" "maybe_vex")
16870    (set_attr "mode" "<MODE>")
16871    (set_attr "athlon_decode" "*")
16872    (set_attr "amdfam10_decode" "*")])
16873
16874 (define_expand "sqrt<mode>2"
16875   [(set (match_operand:MODEF 0 "register_operand" "")
16876         (sqrt:MODEF
16877           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16878   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16879    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16880 {
16881   if (<MODE>mode == SFmode
16882       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16883       && flag_finite_math_only && !flag_trapping_math
16884       && flag_unsafe_math_optimizations)
16885     {
16886       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16887       DONE;
16888     }
16889
16890   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16891     {
16892       rtx op0 = gen_reg_rtx (XFmode);
16893       rtx op1 = force_reg (<MODE>mode, operands[1]);
16894
16895       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16896       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16897       DONE;
16898    }
16899 })
16900
16901 (define_insn "fpremxf4_i387"
16902   [(set (match_operand:XF 0 "register_operand" "=f")
16903         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16904                     (match_operand:XF 3 "register_operand" "1")]
16905                    UNSPEC_FPREM_F))
16906    (set (match_operand:XF 1 "register_operand" "=u")
16907         (unspec:XF [(match_dup 2) (match_dup 3)]
16908                    UNSPEC_FPREM_U))
16909    (set (reg:CCFP FPSR_REG)
16910         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16911                      UNSPEC_C2_FLAG))]
16912   "TARGET_USE_FANCY_MATH_387"
16913   "fprem"
16914   [(set_attr "type" "fpspc")
16915    (set_attr "mode" "XF")])
16916
16917 (define_expand "fmodxf3"
16918   [(use (match_operand:XF 0 "register_operand" ""))
16919    (use (match_operand:XF 1 "general_operand" ""))
16920    (use (match_operand:XF 2 "general_operand" ""))]
16921   "TARGET_USE_FANCY_MATH_387"
16922 {
16923   rtx label = gen_label_rtx ();
16924
16925   rtx op1 = gen_reg_rtx (XFmode);
16926   rtx op2 = gen_reg_rtx (XFmode);
16927
16928   emit_move_insn (op2, operands[2]);
16929   emit_move_insn (op1, operands[1]);
16930
16931   emit_label (label);
16932   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16933   ix86_emit_fp_unordered_jump (label);
16934   LABEL_NUSES (label) = 1;
16935
16936   emit_move_insn (operands[0], op1);
16937   DONE;
16938 })
16939
16940 (define_expand "fmod<mode>3"
16941   [(use (match_operand:MODEF 0 "register_operand" ""))
16942    (use (match_operand:MODEF 1 "general_operand" ""))
16943    (use (match_operand:MODEF 2 "general_operand" ""))]
16944   "TARGET_USE_FANCY_MATH_387"
16945 {
16946   rtx label = gen_label_rtx ();
16947
16948   rtx op1 = gen_reg_rtx (XFmode);
16949   rtx op2 = gen_reg_rtx (XFmode);
16950
16951   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16952   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16953
16954   emit_label (label);
16955   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16956   ix86_emit_fp_unordered_jump (label);
16957   LABEL_NUSES (label) = 1;
16958
16959   /* Truncate the result properly for strict SSE math.  */
16960   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16961       && !TARGET_MIX_SSE_I387)
16962     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16963   else
16964     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16965
16966   DONE;
16967 })
16968
16969 (define_insn "fprem1xf4_i387"
16970   [(set (match_operand:XF 0 "register_operand" "=f")
16971         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16972                     (match_operand:XF 3 "register_operand" "1")]
16973                    UNSPEC_FPREM1_F))
16974    (set (match_operand:XF 1 "register_operand" "=u")
16975         (unspec:XF [(match_dup 2) (match_dup 3)]
16976                    UNSPEC_FPREM1_U))
16977    (set (reg:CCFP FPSR_REG)
16978         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16979                      UNSPEC_C2_FLAG))]
16980   "TARGET_USE_FANCY_MATH_387"
16981   "fprem1"
16982   [(set_attr "type" "fpspc")
16983    (set_attr "mode" "XF")])
16984
16985 (define_expand "remainderxf3"
16986   [(use (match_operand:XF 0 "register_operand" ""))
16987    (use (match_operand:XF 1 "general_operand" ""))
16988    (use (match_operand:XF 2 "general_operand" ""))]
16989   "TARGET_USE_FANCY_MATH_387"
16990 {
16991   rtx label = gen_label_rtx ();
16992
16993   rtx op1 = gen_reg_rtx (XFmode);
16994   rtx op2 = gen_reg_rtx (XFmode);
16995
16996   emit_move_insn (op2, operands[2]);
16997   emit_move_insn (op1, operands[1]);
16998
16999   emit_label (label);
17000   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17001   ix86_emit_fp_unordered_jump (label);
17002   LABEL_NUSES (label) = 1;
17003
17004   emit_move_insn (operands[0], op1);
17005   DONE;
17006 })
17007
17008 (define_expand "remainder<mode>3"
17009   [(use (match_operand:MODEF 0 "register_operand" ""))
17010    (use (match_operand:MODEF 1 "general_operand" ""))
17011    (use (match_operand:MODEF 2 "general_operand" ""))]
17012   "TARGET_USE_FANCY_MATH_387"
17013 {
17014   rtx label = gen_label_rtx ();
17015
17016   rtx op1 = gen_reg_rtx (XFmode);
17017   rtx op2 = gen_reg_rtx (XFmode);
17018
17019   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17020   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17021
17022   emit_label (label);
17023
17024   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17025   ix86_emit_fp_unordered_jump (label);
17026   LABEL_NUSES (label) = 1;
17027
17028   /* Truncate the result properly for strict SSE math.  */
17029   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17030       && !TARGET_MIX_SSE_I387)
17031     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17032   else
17033     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17034
17035   DONE;
17036 })
17037
17038 (define_insn "*sinxf2_i387"
17039   [(set (match_operand:XF 0 "register_operand" "=f")
17040         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17041   "TARGET_USE_FANCY_MATH_387
17042    && flag_unsafe_math_optimizations"
17043   "fsin"
17044   [(set_attr "type" "fpspc")
17045    (set_attr "mode" "XF")])
17046
17047 (define_insn "*sin_extend<mode>xf2_i387"
17048   [(set (match_operand:XF 0 "register_operand" "=f")
17049         (unspec:XF [(float_extend:XF
17050                       (match_operand:MODEF 1 "register_operand" "0"))]
17051                    UNSPEC_SIN))]
17052   "TARGET_USE_FANCY_MATH_387
17053    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17054        || TARGET_MIX_SSE_I387)
17055    && flag_unsafe_math_optimizations"
17056   "fsin"
17057   [(set_attr "type" "fpspc")
17058    (set_attr "mode" "XF")])
17059
17060 (define_insn "*cosxf2_i387"
17061   [(set (match_operand:XF 0 "register_operand" "=f")
17062         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17063   "TARGET_USE_FANCY_MATH_387
17064    && flag_unsafe_math_optimizations"
17065   "fcos"
17066   [(set_attr "type" "fpspc")
17067    (set_attr "mode" "XF")])
17068
17069 (define_insn "*cos_extend<mode>xf2_i387"
17070   [(set (match_operand:XF 0 "register_operand" "=f")
17071         (unspec:XF [(float_extend:XF
17072                       (match_operand:MODEF 1 "register_operand" "0"))]
17073                    UNSPEC_COS))]
17074   "TARGET_USE_FANCY_MATH_387
17075    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17076        || TARGET_MIX_SSE_I387)
17077    && flag_unsafe_math_optimizations"
17078   "fcos"
17079   [(set_attr "type" "fpspc")
17080    (set_attr "mode" "XF")])
17081
17082 ;; When sincos pattern is defined, sin and cos builtin functions will be
17083 ;; expanded to sincos pattern with one of its outputs left unused.
17084 ;; CSE pass will figure out if two sincos patterns can be combined,
17085 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17086 ;; depending on the unused output.
17087
17088 (define_insn "sincosxf3"
17089   [(set (match_operand:XF 0 "register_operand" "=f")
17090         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17091                    UNSPEC_SINCOS_COS))
17092    (set (match_operand:XF 1 "register_operand" "=u")
17093         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17094   "TARGET_USE_FANCY_MATH_387
17095    && flag_unsafe_math_optimizations"
17096   "fsincos"
17097   [(set_attr "type" "fpspc")
17098    (set_attr "mode" "XF")])
17099
17100 (define_split
17101   [(set (match_operand:XF 0 "register_operand" "")
17102         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17103                    UNSPEC_SINCOS_COS))
17104    (set (match_operand:XF 1 "register_operand" "")
17105         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17106   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17107    && !(reload_completed || reload_in_progress)"
17108   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17109   "")
17110
17111 (define_split
17112   [(set (match_operand:XF 0 "register_operand" "")
17113         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17114                    UNSPEC_SINCOS_COS))
17115    (set (match_operand:XF 1 "register_operand" "")
17116         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17117   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17118    && !(reload_completed || reload_in_progress)"
17119   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17120   "")
17121
17122 (define_insn "sincos_extend<mode>xf3_i387"
17123   [(set (match_operand:XF 0 "register_operand" "=f")
17124         (unspec:XF [(float_extend:XF
17125                       (match_operand:MODEF 2 "register_operand" "0"))]
17126                    UNSPEC_SINCOS_COS))
17127    (set (match_operand:XF 1 "register_operand" "=u")
17128         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17129   "TARGET_USE_FANCY_MATH_387
17130    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17131        || TARGET_MIX_SSE_I387)
17132    && flag_unsafe_math_optimizations"
17133   "fsincos"
17134   [(set_attr "type" "fpspc")
17135    (set_attr "mode" "XF")])
17136
17137 (define_split
17138   [(set (match_operand:XF 0 "register_operand" "")
17139         (unspec:XF [(float_extend:XF
17140                       (match_operand:MODEF 2 "register_operand" ""))]
17141                    UNSPEC_SINCOS_COS))
17142    (set (match_operand:XF 1 "register_operand" "")
17143         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17144   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17145    && !(reload_completed || reload_in_progress)"
17146   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17147   "")
17148
17149 (define_split
17150   [(set (match_operand:XF 0 "register_operand" "")
17151         (unspec:XF [(float_extend:XF
17152                       (match_operand:MODEF 2 "register_operand" ""))]
17153                    UNSPEC_SINCOS_COS))
17154    (set (match_operand:XF 1 "register_operand" "")
17155         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17156   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17157    && !(reload_completed || reload_in_progress)"
17158   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17159   "")
17160
17161 (define_expand "sincos<mode>3"
17162   [(use (match_operand:MODEF 0 "register_operand" ""))
17163    (use (match_operand:MODEF 1 "register_operand" ""))
17164    (use (match_operand:MODEF 2 "register_operand" ""))]
17165   "TARGET_USE_FANCY_MATH_387
17166    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17167        || TARGET_MIX_SSE_I387)
17168    && flag_unsafe_math_optimizations"
17169 {
17170   rtx op0 = gen_reg_rtx (XFmode);
17171   rtx op1 = gen_reg_rtx (XFmode);
17172
17173   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17174   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17175   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17176   DONE;
17177 })
17178
17179 (define_insn "fptanxf4_i387"
17180   [(set (match_operand:XF 0 "register_operand" "=f")
17181         (match_operand:XF 3 "const_double_operand" "F"))
17182    (set (match_operand:XF 1 "register_operand" "=u")
17183         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17184                    UNSPEC_TAN))]
17185   "TARGET_USE_FANCY_MATH_387
17186    && flag_unsafe_math_optimizations
17187    && standard_80387_constant_p (operands[3]) == 2"
17188   "fptan"
17189   [(set_attr "type" "fpspc")
17190    (set_attr "mode" "XF")])
17191
17192 (define_insn "fptan_extend<mode>xf4_i387"
17193   [(set (match_operand:MODEF 0 "register_operand" "=f")
17194         (match_operand:MODEF 3 "const_double_operand" "F"))
17195    (set (match_operand:XF 1 "register_operand" "=u")
17196         (unspec:XF [(float_extend:XF
17197                       (match_operand:MODEF 2 "register_operand" "0"))]
17198                    UNSPEC_TAN))]
17199   "TARGET_USE_FANCY_MATH_387
17200    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17201        || TARGET_MIX_SSE_I387)
17202    && flag_unsafe_math_optimizations
17203    && standard_80387_constant_p (operands[3]) == 2"
17204   "fptan"
17205   [(set_attr "type" "fpspc")
17206    (set_attr "mode" "XF")])
17207
17208 (define_expand "tanxf2"
17209   [(use (match_operand:XF 0 "register_operand" ""))
17210    (use (match_operand:XF 1 "register_operand" ""))]
17211   "TARGET_USE_FANCY_MATH_387
17212    && flag_unsafe_math_optimizations"
17213 {
17214   rtx one = gen_reg_rtx (XFmode);
17215   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17216
17217   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17218   DONE;
17219 })
17220
17221 (define_expand "tan<mode>2"
17222   [(use (match_operand:MODEF 0 "register_operand" ""))
17223    (use (match_operand:MODEF 1 "register_operand" ""))]
17224   "TARGET_USE_FANCY_MATH_387
17225    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17226        || TARGET_MIX_SSE_I387)
17227    && flag_unsafe_math_optimizations"
17228 {
17229   rtx op0 = gen_reg_rtx (XFmode);
17230
17231   rtx one = gen_reg_rtx (<MODE>mode);
17232   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17233
17234   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17235                                              operands[1], op2));
17236   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17237   DONE;
17238 })
17239
17240 (define_insn "*fpatanxf3_i387"
17241   [(set (match_operand:XF 0 "register_operand" "=f")
17242         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17243                     (match_operand:XF 2 "register_operand" "u")]
17244                    UNSPEC_FPATAN))
17245    (clobber (match_scratch:XF 3 "=2"))]
17246   "TARGET_USE_FANCY_MATH_387
17247    && flag_unsafe_math_optimizations"
17248   "fpatan"
17249   [(set_attr "type" "fpspc")
17250    (set_attr "mode" "XF")])
17251
17252 (define_insn "fpatan_extend<mode>xf3_i387"
17253   [(set (match_operand:XF 0 "register_operand" "=f")
17254         (unspec:XF [(float_extend:XF
17255                       (match_operand:MODEF 1 "register_operand" "0"))
17256                     (float_extend:XF
17257                       (match_operand:MODEF 2 "register_operand" "u"))]
17258                    UNSPEC_FPATAN))
17259    (clobber (match_scratch:XF 3 "=2"))]
17260   "TARGET_USE_FANCY_MATH_387
17261    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17262        || TARGET_MIX_SSE_I387)
17263    && flag_unsafe_math_optimizations"
17264   "fpatan"
17265   [(set_attr "type" "fpspc")
17266    (set_attr "mode" "XF")])
17267
17268 (define_expand "atan2xf3"
17269   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17270                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17271                                (match_operand:XF 1 "register_operand" "")]
17272                               UNSPEC_FPATAN))
17273               (clobber (match_scratch:XF 3 ""))])]
17274   "TARGET_USE_FANCY_MATH_387
17275    && flag_unsafe_math_optimizations"
17276   "")
17277
17278 (define_expand "atan2<mode>3"
17279   [(use (match_operand:MODEF 0 "register_operand" ""))
17280    (use (match_operand:MODEF 1 "register_operand" ""))
17281    (use (match_operand:MODEF 2 "register_operand" ""))]
17282   "TARGET_USE_FANCY_MATH_387
17283    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17284        || TARGET_MIX_SSE_I387)
17285    && flag_unsafe_math_optimizations"
17286 {
17287   rtx op0 = gen_reg_rtx (XFmode);
17288
17289   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17290   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17291   DONE;
17292 })
17293
17294 (define_expand "atanxf2"
17295   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17296                    (unspec:XF [(match_dup 2)
17297                                (match_operand:XF 1 "register_operand" "")]
17298                               UNSPEC_FPATAN))
17299               (clobber (match_scratch:XF 3 ""))])]
17300   "TARGET_USE_FANCY_MATH_387
17301    && flag_unsafe_math_optimizations"
17302 {
17303   operands[2] = gen_reg_rtx (XFmode);
17304   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17305 })
17306
17307 (define_expand "atan<mode>2"
17308   [(use (match_operand:MODEF 0 "register_operand" ""))
17309    (use (match_operand:MODEF 1 "register_operand" ""))]
17310   "TARGET_USE_FANCY_MATH_387
17311    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17312        || TARGET_MIX_SSE_I387)
17313    && flag_unsafe_math_optimizations"
17314 {
17315   rtx op0 = gen_reg_rtx (XFmode);
17316
17317   rtx op2 = gen_reg_rtx (<MODE>mode);
17318   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17319
17320   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17321   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17322   DONE;
17323 })
17324
17325 (define_expand "asinxf2"
17326   [(set (match_dup 2)
17327         (mult:XF (match_operand:XF 1 "register_operand" "")
17328                  (match_dup 1)))
17329    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17330    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17331    (parallel [(set (match_operand:XF 0 "register_operand" "")
17332                    (unspec:XF [(match_dup 5) (match_dup 1)]
17333                               UNSPEC_FPATAN))
17334               (clobber (match_scratch:XF 6 ""))])]
17335   "TARGET_USE_FANCY_MATH_387
17336    && flag_unsafe_math_optimizations"
17337 {
17338   int i;
17339
17340   if (optimize_insn_for_size_p ())
17341     FAIL;
17342
17343   for (i = 2; i < 6; i++)
17344     operands[i] = gen_reg_rtx (XFmode);
17345
17346   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17347 })
17348
17349 (define_expand "asin<mode>2"
17350   [(use (match_operand:MODEF 0 "register_operand" ""))
17351    (use (match_operand:MODEF 1 "general_operand" ""))]
17352  "TARGET_USE_FANCY_MATH_387
17353    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17354        || TARGET_MIX_SSE_I387)
17355    && flag_unsafe_math_optimizations"
17356 {
17357   rtx op0 = gen_reg_rtx (XFmode);
17358   rtx op1 = gen_reg_rtx (XFmode);
17359
17360   if (optimize_insn_for_size_p ())
17361     FAIL;
17362
17363   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17364   emit_insn (gen_asinxf2 (op0, op1));
17365   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17366   DONE;
17367 })
17368
17369 (define_expand "acosxf2"
17370   [(set (match_dup 2)
17371         (mult:XF (match_operand:XF 1 "register_operand" "")
17372                  (match_dup 1)))
17373    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17374    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17375    (parallel [(set (match_operand:XF 0 "register_operand" "")
17376                    (unspec:XF [(match_dup 1) (match_dup 5)]
17377                               UNSPEC_FPATAN))
17378               (clobber (match_scratch:XF 6 ""))])]
17379   "TARGET_USE_FANCY_MATH_387
17380    && flag_unsafe_math_optimizations"
17381 {
17382   int i;
17383
17384   if (optimize_insn_for_size_p ())
17385     FAIL;
17386
17387   for (i = 2; i < 6; i++)
17388     operands[i] = gen_reg_rtx (XFmode);
17389
17390   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17391 })
17392
17393 (define_expand "acos<mode>2"
17394   [(use (match_operand:MODEF 0 "register_operand" ""))
17395    (use (match_operand:MODEF 1 "general_operand" ""))]
17396  "TARGET_USE_FANCY_MATH_387
17397    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17398        || TARGET_MIX_SSE_I387)
17399    && flag_unsafe_math_optimizations"
17400 {
17401   rtx op0 = gen_reg_rtx (XFmode);
17402   rtx op1 = gen_reg_rtx (XFmode);
17403
17404   if (optimize_insn_for_size_p ())
17405     FAIL;
17406
17407   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17408   emit_insn (gen_acosxf2 (op0, op1));
17409   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17410   DONE;
17411 })
17412
17413 (define_insn "fyl2xxf3_i387"
17414   [(set (match_operand:XF 0 "register_operand" "=f")
17415         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17416                     (match_operand:XF 2 "register_operand" "u")]
17417                    UNSPEC_FYL2X))
17418    (clobber (match_scratch:XF 3 "=2"))]
17419   "TARGET_USE_FANCY_MATH_387
17420    && flag_unsafe_math_optimizations"
17421   "fyl2x"
17422   [(set_attr "type" "fpspc")
17423    (set_attr "mode" "XF")])
17424
17425 (define_insn "fyl2x_extend<mode>xf3_i387"
17426   [(set (match_operand:XF 0 "register_operand" "=f")
17427         (unspec:XF [(float_extend:XF
17428                       (match_operand:MODEF 1 "register_operand" "0"))
17429                     (match_operand:XF 2 "register_operand" "u")]
17430                    UNSPEC_FYL2X))
17431    (clobber (match_scratch:XF 3 "=2"))]
17432   "TARGET_USE_FANCY_MATH_387
17433    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17434        || TARGET_MIX_SSE_I387)
17435    && flag_unsafe_math_optimizations"
17436   "fyl2x"
17437   [(set_attr "type" "fpspc")
17438    (set_attr "mode" "XF")])
17439
17440 (define_expand "logxf2"
17441   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17442                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17443                                (match_dup 2)] UNSPEC_FYL2X))
17444               (clobber (match_scratch:XF 3 ""))])]
17445   "TARGET_USE_FANCY_MATH_387
17446    && flag_unsafe_math_optimizations"
17447 {
17448   operands[2] = gen_reg_rtx (XFmode);
17449   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17450 })
17451
17452 (define_expand "log<mode>2"
17453   [(use (match_operand:MODEF 0 "register_operand" ""))
17454    (use (match_operand:MODEF 1 "register_operand" ""))]
17455   "TARGET_USE_FANCY_MATH_387
17456    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17457        || TARGET_MIX_SSE_I387)
17458    && flag_unsafe_math_optimizations"
17459 {
17460   rtx op0 = gen_reg_rtx (XFmode);
17461
17462   rtx op2 = gen_reg_rtx (XFmode);
17463   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17464
17465   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17466   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17467   DONE;
17468 })
17469
17470 (define_expand "log10xf2"
17471   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17472                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17473                                (match_dup 2)] UNSPEC_FYL2X))
17474               (clobber (match_scratch:XF 3 ""))])]
17475   "TARGET_USE_FANCY_MATH_387
17476    && flag_unsafe_math_optimizations"
17477 {
17478   operands[2] = gen_reg_rtx (XFmode);
17479   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17480 })
17481
17482 (define_expand "log10<mode>2"
17483   [(use (match_operand:MODEF 0 "register_operand" ""))
17484    (use (match_operand:MODEF 1 "register_operand" ""))]
17485   "TARGET_USE_FANCY_MATH_387
17486    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17487        || TARGET_MIX_SSE_I387)
17488    && flag_unsafe_math_optimizations"
17489 {
17490   rtx op0 = gen_reg_rtx (XFmode);
17491
17492   rtx op2 = gen_reg_rtx (XFmode);
17493   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17494
17495   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17496   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17497   DONE;
17498 })
17499
17500 (define_expand "log2xf2"
17501   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17502                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17503                                (match_dup 2)] UNSPEC_FYL2X))
17504               (clobber (match_scratch:XF 3 ""))])]
17505   "TARGET_USE_FANCY_MATH_387
17506    && flag_unsafe_math_optimizations"
17507 {
17508   operands[2] = gen_reg_rtx (XFmode);
17509   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17510 })
17511
17512 (define_expand "log2<mode>2"
17513   [(use (match_operand:MODEF 0 "register_operand" ""))
17514    (use (match_operand:MODEF 1 "register_operand" ""))]
17515   "TARGET_USE_FANCY_MATH_387
17516    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17517        || TARGET_MIX_SSE_I387)
17518    && flag_unsafe_math_optimizations"
17519 {
17520   rtx op0 = gen_reg_rtx (XFmode);
17521
17522   rtx op2 = gen_reg_rtx (XFmode);
17523   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17524
17525   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17526   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17527   DONE;
17528 })
17529
17530 (define_insn "fyl2xp1xf3_i387"
17531   [(set (match_operand:XF 0 "register_operand" "=f")
17532         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17533                     (match_operand:XF 2 "register_operand" "u")]
17534                    UNSPEC_FYL2XP1))
17535    (clobber (match_scratch:XF 3 "=2"))]
17536   "TARGET_USE_FANCY_MATH_387
17537    && flag_unsafe_math_optimizations"
17538   "fyl2xp1"
17539   [(set_attr "type" "fpspc")
17540    (set_attr "mode" "XF")])
17541
17542 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17543   [(set (match_operand:XF 0 "register_operand" "=f")
17544         (unspec:XF [(float_extend:XF
17545                       (match_operand:MODEF 1 "register_operand" "0"))
17546                     (match_operand:XF 2 "register_operand" "u")]
17547                    UNSPEC_FYL2XP1))
17548    (clobber (match_scratch:XF 3 "=2"))]
17549   "TARGET_USE_FANCY_MATH_387
17550    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17551        || TARGET_MIX_SSE_I387)
17552    && flag_unsafe_math_optimizations"
17553   "fyl2xp1"
17554   [(set_attr "type" "fpspc")
17555    (set_attr "mode" "XF")])
17556
17557 (define_expand "log1pxf2"
17558   [(use (match_operand:XF 0 "register_operand" ""))
17559    (use (match_operand:XF 1 "register_operand" ""))]
17560   "TARGET_USE_FANCY_MATH_387
17561    && flag_unsafe_math_optimizations"
17562 {
17563   if (optimize_insn_for_size_p ())
17564     FAIL;
17565
17566   ix86_emit_i387_log1p (operands[0], operands[1]);
17567   DONE;
17568 })
17569
17570 (define_expand "log1p<mode>2"
17571   [(use (match_operand:MODEF 0 "register_operand" ""))
17572    (use (match_operand:MODEF 1 "register_operand" ""))]
17573   "TARGET_USE_FANCY_MATH_387
17574    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17575        || TARGET_MIX_SSE_I387)
17576    && flag_unsafe_math_optimizations"
17577 {
17578   rtx op0;
17579
17580   if (optimize_insn_for_size_p ())
17581     FAIL;
17582
17583   op0 = gen_reg_rtx (XFmode);
17584
17585   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17586
17587   ix86_emit_i387_log1p (op0, operands[1]);
17588   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17589   DONE;
17590 })
17591
17592 (define_insn "fxtractxf3_i387"
17593   [(set (match_operand:XF 0 "register_operand" "=f")
17594         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17595                    UNSPEC_XTRACT_FRACT))
17596    (set (match_operand:XF 1 "register_operand" "=u")
17597         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17598   "TARGET_USE_FANCY_MATH_387
17599    && flag_unsafe_math_optimizations"
17600   "fxtract"
17601   [(set_attr "type" "fpspc")
17602    (set_attr "mode" "XF")])
17603
17604 (define_insn "fxtract_extend<mode>xf3_i387"
17605   [(set (match_operand:XF 0 "register_operand" "=f")
17606         (unspec:XF [(float_extend:XF
17607                       (match_operand:MODEF 2 "register_operand" "0"))]
17608                    UNSPEC_XTRACT_FRACT))
17609    (set (match_operand:XF 1 "register_operand" "=u")
17610         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17611   "TARGET_USE_FANCY_MATH_387
17612    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17613        || TARGET_MIX_SSE_I387)
17614    && flag_unsafe_math_optimizations"
17615   "fxtract"
17616   [(set_attr "type" "fpspc")
17617    (set_attr "mode" "XF")])
17618
17619 (define_expand "logbxf2"
17620   [(parallel [(set (match_dup 2)
17621                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17622                               UNSPEC_XTRACT_FRACT))
17623               (set (match_operand:XF 0 "register_operand" "")
17624                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17625   "TARGET_USE_FANCY_MATH_387
17626    && flag_unsafe_math_optimizations"
17627 {
17628   operands[2] = gen_reg_rtx (XFmode);
17629 })
17630
17631 (define_expand "logb<mode>2"
17632   [(use (match_operand:MODEF 0 "register_operand" ""))
17633    (use (match_operand:MODEF 1 "register_operand" ""))]
17634   "TARGET_USE_FANCY_MATH_387
17635    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17636        || TARGET_MIX_SSE_I387)
17637    && flag_unsafe_math_optimizations"
17638 {
17639   rtx op0 = gen_reg_rtx (XFmode);
17640   rtx op1 = gen_reg_rtx (XFmode);
17641
17642   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17643   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17644   DONE;
17645 })
17646
17647 (define_expand "ilogbxf2"
17648   [(use (match_operand:SI 0 "register_operand" ""))
17649    (use (match_operand:XF 1 "register_operand" ""))]
17650   "TARGET_USE_FANCY_MATH_387
17651    && flag_unsafe_math_optimizations"
17652 {
17653   rtx op0, op1;
17654
17655   if (optimize_insn_for_size_p ())
17656     FAIL;
17657
17658   op0 = gen_reg_rtx (XFmode);
17659   op1 = gen_reg_rtx (XFmode);
17660
17661   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17662   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17663   DONE;
17664 })
17665
17666 (define_expand "ilogb<mode>2"
17667   [(use (match_operand:SI 0 "register_operand" ""))
17668    (use (match_operand:MODEF 1 "register_operand" ""))]
17669   "TARGET_USE_FANCY_MATH_387
17670    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17671        || TARGET_MIX_SSE_I387)
17672    && flag_unsafe_math_optimizations"
17673 {
17674   rtx op0, op1;
17675
17676   if (optimize_insn_for_size_p ())
17677     FAIL;
17678
17679   op0 = gen_reg_rtx (XFmode);
17680   op1 = gen_reg_rtx (XFmode);
17681
17682   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17683   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17684   DONE;
17685 })
17686
17687 (define_insn "*f2xm1xf2_i387"
17688   [(set (match_operand:XF 0 "register_operand" "=f")
17689         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17690                    UNSPEC_F2XM1))]
17691   "TARGET_USE_FANCY_MATH_387
17692    && flag_unsafe_math_optimizations"
17693   "f2xm1"
17694   [(set_attr "type" "fpspc")
17695    (set_attr "mode" "XF")])
17696
17697 (define_insn "*fscalexf4_i387"
17698   [(set (match_operand:XF 0 "register_operand" "=f")
17699         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17700                     (match_operand:XF 3 "register_operand" "1")]
17701                    UNSPEC_FSCALE_FRACT))
17702    (set (match_operand:XF 1 "register_operand" "=u")
17703         (unspec:XF [(match_dup 2) (match_dup 3)]
17704                    UNSPEC_FSCALE_EXP))]
17705   "TARGET_USE_FANCY_MATH_387
17706    && flag_unsafe_math_optimizations"
17707   "fscale"
17708   [(set_attr "type" "fpspc")
17709    (set_attr "mode" "XF")])
17710
17711 (define_expand "expNcorexf3"
17712   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17713                                (match_operand:XF 2 "register_operand" "")))
17714    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17715    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17716    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17717    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17718    (parallel [(set (match_operand:XF 0 "register_operand" "")
17719                    (unspec:XF [(match_dup 8) (match_dup 4)]
17720                               UNSPEC_FSCALE_FRACT))
17721               (set (match_dup 9)
17722                    (unspec:XF [(match_dup 8) (match_dup 4)]
17723                               UNSPEC_FSCALE_EXP))])]
17724   "TARGET_USE_FANCY_MATH_387
17725    && flag_unsafe_math_optimizations"
17726 {
17727   int i;
17728
17729   if (optimize_insn_for_size_p ())
17730     FAIL;
17731
17732   for (i = 3; i < 10; i++)
17733     operands[i] = gen_reg_rtx (XFmode);
17734
17735   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17736 })
17737
17738 (define_expand "expxf2"
17739   [(use (match_operand:XF 0 "register_operand" ""))
17740    (use (match_operand:XF 1 "register_operand" ""))]
17741   "TARGET_USE_FANCY_MATH_387
17742    && flag_unsafe_math_optimizations"
17743 {
17744   rtx op2;
17745
17746   if (optimize_insn_for_size_p ())
17747     FAIL;
17748
17749   op2 = gen_reg_rtx (XFmode);
17750   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17751
17752   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17753   DONE;
17754 })
17755
17756 (define_expand "exp<mode>2"
17757   [(use (match_operand:MODEF 0 "register_operand" ""))
17758    (use (match_operand:MODEF 1 "general_operand" ""))]
17759  "TARGET_USE_FANCY_MATH_387
17760    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17761        || TARGET_MIX_SSE_I387)
17762    && flag_unsafe_math_optimizations"
17763 {
17764   rtx op0, op1;
17765
17766   if (optimize_insn_for_size_p ())
17767     FAIL;
17768
17769   op0 = gen_reg_rtx (XFmode);
17770   op1 = gen_reg_rtx (XFmode);
17771
17772   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17773   emit_insn (gen_expxf2 (op0, op1));
17774   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17775   DONE;
17776 })
17777
17778 (define_expand "exp10xf2"
17779   [(use (match_operand:XF 0 "register_operand" ""))
17780    (use (match_operand:XF 1 "register_operand" ""))]
17781   "TARGET_USE_FANCY_MATH_387
17782    && flag_unsafe_math_optimizations"
17783 {
17784   rtx op2;
17785
17786   if (optimize_insn_for_size_p ())
17787     FAIL;
17788
17789   op2 = gen_reg_rtx (XFmode);
17790   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17791
17792   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17793   DONE;
17794 })
17795
17796 (define_expand "exp10<mode>2"
17797   [(use (match_operand:MODEF 0 "register_operand" ""))
17798    (use (match_operand:MODEF 1 "general_operand" ""))]
17799  "TARGET_USE_FANCY_MATH_387
17800    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17801        || TARGET_MIX_SSE_I387)
17802    && flag_unsafe_math_optimizations"
17803 {
17804   rtx op0, op1;
17805
17806   if (optimize_insn_for_size_p ())
17807     FAIL;
17808
17809   op0 = gen_reg_rtx (XFmode);
17810   op1 = gen_reg_rtx (XFmode);
17811
17812   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17813   emit_insn (gen_exp10xf2 (op0, op1));
17814   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17815   DONE;
17816 })
17817
17818 (define_expand "exp2xf2"
17819   [(use (match_operand:XF 0 "register_operand" ""))
17820    (use (match_operand:XF 1 "register_operand" ""))]
17821   "TARGET_USE_FANCY_MATH_387
17822    && flag_unsafe_math_optimizations"
17823 {
17824   rtx op2;
17825
17826   if (optimize_insn_for_size_p ())
17827     FAIL;
17828
17829   op2 = gen_reg_rtx (XFmode);
17830   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17831
17832   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17833   DONE;
17834 })
17835
17836 (define_expand "exp2<mode>2"
17837   [(use (match_operand:MODEF 0 "register_operand" ""))
17838    (use (match_operand:MODEF 1 "general_operand" ""))]
17839  "TARGET_USE_FANCY_MATH_387
17840    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17841        || TARGET_MIX_SSE_I387)
17842    && flag_unsafe_math_optimizations"
17843 {
17844   rtx op0, op1;
17845
17846   if (optimize_insn_for_size_p ())
17847     FAIL;
17848
17849   op0 = gen_reg_rtx (XFmode);
17850   op1 = gen_reg_rtx (XFmode);
17851
17852   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17853   emit_insn (gen_exp2xf2 (op0, op1));
17854   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17855   DONE;
17856 })
17857
17858 (define_expand "expm1xf2"
17859   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17860                                (match_dup 2)))
17861    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17862    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17863    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17864    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17865    (parallel [(set (match_dup 7)
17866                    (unspec:XF [(match_dup 6) (match_dup 4)]
17867                               UNSPEC_FSCALE_FRACT))
17868               (set (match_dup 8)
17869                    (unspec:XF [(match_dup 6) (match_dup 4)]
17870                               UNSPEC_FSCALE_EXP))])
17871    (parallel [(set (match_dup 10)
17872                    (unspec:XF [(match_dup 9) (match_dup 8)]
17873                               UNSPEC_FSCALE_FRACT))
17874               (set (match_dup 11)
17875                    (unspec:XF [(match_dup 9) (match_dup 8)]
17876                               UNSPEC_FSCALE_EXP))])
17877    (set (match_dup 12) (minus:XF (match_dup 10)
17878                                  (float_extend:XF (match_dup 13))))
17879    (set (match_operand:XF 0 "register_operand" "")
17880         (plus:XF (match_dup 12) (match_dup 7)))]
17881   "TARGET_USE_FANCY_MATH_387
17882    && flag_unsafe_math_optimizations"
17883 {
17884   int i;
17885
17886   if (optimize_insn_for_size_p ())
17887     FAIL;
17888
17889   for (i = 2; i < 13; i++)
17890     operands[i] = gen_reg_rtx (XFmode);
17891
17892   operands[13]
17893     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17894
17895   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17896 })
17897
17898 (define_expand "expm1<mode>2"
17899   [(use (match_operand:MODEF 0 "register_operand" ""))
17900    (use (match_operand:MODEF 1 "general_operand" ""))]
17901  "TARGET_USE_FANCY_MATH_387
17902    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17903        || TARGET_MIX_SSE_I387)
17904    && flag_unsafe_math_optimizations"
17905 {
17906   rtx op0, op1;
17907
17908   if (optimize_insn_for_size_p ())
17909     FAIL;
17910
17911   op0 = gen_reg_rtx (XFmode);
17912   op1 = gen_reg_rtx (XFmode);
17913
17914   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17915   emit_insn (gen_expm1xf2 (op0, op1));
17916   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17917   DONE;
17918 })
17919
17920 (define_expand "ldexpxf3"
17921   [(set (match_dup 3)
17922         (float:XF (match_operand:SI 2 "register_operand" "")))
17923    (parallel [(set (match_operand:XF 0 " register_operand" "")
17924                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17925                                (match_dup 3)]
17926                               UNSPEC_FSCALE_FRACT))
17927               (set (match_dup 4)
17928                    (unspec:XF [(match_dup 1) (match_dup 3)]
17929                               UNSPEC_FSCALE_EXP))])]
17930   "TARGET_USE_FANCY_MATH_387
17931    && flag_unsafe_math_optimizations"
17932 {
17933   if (optimize_insn_for_size_p ())
17934     FAIL;
17935
17936   operands[3] = gen_reg_rtx (XFmode);
17937   operands[4] = gen_reg_rtx (XFmode);
17938 })
17939
17940 (define_expand "ldexp<mode>3"
17941   [(use (match_operand:MODEF 0 "register_operand" ""))
17942    (use (match_operand:MODEF 1 "general_operand" ""))
17943    (use (match_operand:SI 2 "register_operand" ""))]
17944  "TARGET_USE_FANCY_MATH_387
17945    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17946        || TARGET_MIX_SSE_I387)
17947    && flag_unsafe_math_optimizations"
17948 {
17949   rtx op0, op1;
17950
17951   if (optimize_insn_for_size_p ())
17952     FAIL;
17953
17954   op0 = gen_reg_rtx (XFmode);
17955   op1 = gen_reg_rtx (XFmode);
17956
17957   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17958   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17959   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17960   DONE;
17961 })
17962
17963 (define_expand "scalbxf3"
17964   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17965                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17966                                (match_operand:XF 2 "register_operand" "")]
17967                               UNSPEC_FSCALE_FRACT))
17968               (set (match_dup 3)
17969                    (unspec:XF [(match_dup 1) (match_dup 2)]
17970                               UNSPEC_FSCALE_EXP))])]
17971   "TARGET_USE_FANCY_MATH_387
17972    && flag_unsafe_math_optimizations"
17973 {
17974   if (optimize_insn_for_size_p ())
17975     FAIL;
17976
17977   operands[3] = gen_reg_rtx (XFmode);
17978 })
17979
17980 (define_expand "scalb<mode>3"
17981   [(use (match_operand:MODEF 0 "register_operand" ""))
17982    (use (match_operand:MODEF 1 "general_operand" ""))
17983    (use (match_operand:MODEF 2 "register_operand" ""))]
17984  "TARGET_USE_FANCY_MATH_387
17985    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17986        || TARGET_MIX_SSE_I387)
17987    && flag_unsafe_math_optimizations"
17988 {
17989   rtx op0, op1, op2;
17990
17991   if (optimize_insn_for_size_p ())
17992     FAIL;
17993
17994   op0 = gen_reg_rtx (XFmode);
17995   op1 = gen_reg_rtx (XFmode);
17996   op2 = gen_reg_rtx (XFmode);
17997
17998   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17999   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18000   emit_insn (gen_scalbxf3 (op0, op1, op2));
18001   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18002   DONE;
18003 })
18004 \f
18005
18006 (define_insn "sse4_1_round<mode>2"
18007   [(set (match_operand:MODEF 0 "register_operand" "=x")
18008         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18009                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
18010                       UNSPEC_ROUND))]
18011   "TARGET_ROUND"
18012   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
18013   [(set_attr "type" "ssecvt")
18014    (set_attr "prefix_extra" "1")
18015    (set_attr "prefix" "maybe_vex")
18016    (set_attr "mode" "<MODE>")])
18017
18018 (define_insn "rintxf2"
18019   [(set (match_operand:XF 0 "register_operand" "=f")
18020         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18021                    UNSPEC_FRNDINT))]
18022   "TARGET_USE_FANCY_MATH_387
18023    && flag_unsafe_math_optimizations"
18024   "frndint"
18025   [(set_attr "type" "fpspc")
18026    (set_attr "mode" "XF")])
18027
18028 (define_expand "rint<mode>2"
18029   [(use (match_operand:MODEF 0 "register_operand" ""))
18030    (use (match_operand:MODEF 1 "register_operand" ""))]
18031   "(TARGET_USE_FANCY_MATH_387
18032     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18033         || TARGET_MIX_SSE_I387)
18034     && flag_unsafe_math_optimizations)
18035    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18036        && !flag_trapping_math)"
18037 {
18038   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18039       && !flag_trapping_math)
18040     {
18041       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18042         FAIL;
18043       if (TARGET_ROUND)
18044         emit_insn (gen_sse4_1_round<mode>2
18045                    (operands[0], operands[1], GEN_INT (0x04)));
18046       else
18047         ix86_expand_rint (operand0, operand1);
18048     }
18049   else
18050     {
18051       rtx op0 = gen_reg_rtx (XFmode);
18052       rtx op1 = gen_reg_rtx (XFmode);
18053
18054       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18055       emit_insn (gen_rintxf2 (op0, op1));
18056
18057       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18058     }
18059   DONE;
18060 })
18061
18062 (define_expand "round<mode>2"
18063   [(match_operand:MODEF 0 "register_operand" "")
18064    (match_operand:MODEF 1 "nonimmediate_operand" "")]
18065   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18066    && !flag_trapping_math && !flag_rounding_math"
18067 {
18068   if (optimize_insn_for_size_p ())
18069     FAIL;
18070   if (TARGET_64BIT || (<MODE>mode != DFmode))
18071     ix86_expand_round (operand0, operand1);
18072   else
18073     ix86_expand_rounddf_32 (operand0, operand1);
18074   DONE;
18075 })
18076
18077 (define_insn_and_split "*fistdi2_1"
18078   [(set (match_operand:DI 0 "nonimmediate_operand" "")
18079         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18080                    UNSPEC_FIST))]
18081   "TARGET_USE_FANCY_MATH_387
18082    && !(reload_completed || reload_in_progress)"
18083   "#"
18084   "&& 1"
18085   [(const_int 0)]
18086 {
18087   if (memory_operand (operands[0], VOIDmode))
18088     emit_insn (gen_fistdi2 (operands[0], operands[1]));
18089   else
18090     {
18091       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18092       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18093                                          operands[2]));
18094     }
18095   DONE;
18096 }
18097   [(set_attr "type" "fpspc")
18098    (set_attr "mode" "DI")])
18099
18100 (define_insn "fistdi2"
18101   [(set (match_operand:DI 0 "memory_operand" "=m")
18102         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18103                    UNSPEC_FIST))
18104    (clobber (match_scratch:XF 2 "=&1f"))]
18105   "TARGET_USE_FANCY_MATH_387"
18106   "* return output_fix_trunc (insn, operands, 0);"
18107   [(set_attr "type" "fpspc")
18108    (set_attr "mode" "DI")])
18109
18110 (define_insn "fistdi2_with_temp"
18111   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18112         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18113                    UNSPEC_FIST))
18114    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18115    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18116   "TARGET_USE_FANCY_MATH_387"
18117   "#"
18118   [(set_attr "type" "fpspc")
18119    (set_attr "mode" "DI")])
18120
18121 (define_split
18122   [(set (match_operand:DI 0 "register_operand" "")
18123         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18124                    UNSPEC_FIST))
18125    (clobber (match_operand:DI 2 "memory_operand" ""))
18126    (clobber (match_scratch 3 ""))]
18127   "reload_completed"
18128   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18129               (clobber (match_dup 3))])
18130    (set (match_dup 0) (match_dup 2))]
18131   "")
18132
18133 (define_split
18134   [(set (match_operand:DI 0 "memory_operand" "")
18135         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18136                    UNSPEC_FIST))
18137    (clobber (match_operand:DI 2 "memory_operand" ""))
18138    (clobber (match_scratch 3 ""))]
18139   "reload_completed"
18140   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18141               (clobber (match_dup 3))])]
18142   "")
18143
18144 (define_insn_and_split "*fist<mode>2_1"
18145   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18146         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18147                            UNSPEC_FIST))]
18148   "TARGET_USE_FANCY_MATH_387
18149    && !(reload_completed || reload_in_progress)"
18150   "#"
18151   "&& 1"
18152   [(const_int 0)]
18153 {
18154   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18155   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18156                                         operands[2]));
18157   DONE;
18158 }
18159   [(set_attr "type" "fpspc")
18160    (set_attr "mode" "<MODE>")])
18161
18162 (define_insn "fist<mode>2"
18163   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18164         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18165                            UNSPEC_FIST))]
18166   "TARGET_USE_FANCY_MATH_387"
18167   "* return output_fix_trunc (insn, operands, 0);"
18168   [(set_attr "type" "fpspc")
18169    (set_attr "mode" "<MODE>")])
18170
18171 (define_insn "fist<mode>2_with_temp"
18172   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18173         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18174                            UNSPEC_FIST))
18175    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18176   "TARGET_USE_FANCY_MATH_387"
18177   "#"
18178   [(set_attr "type" "fpspc")
18179    (set_attr "mode" "<MODE>")])
18180
18181 (define_split
18182   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18183         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18184                            UNSPEC_FIST))
18185    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18186   "reload_completed"
18187   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18188    (set (match_dup 0) (match_dup 2))]
18189   "")
18190
18191 (define_split
18192   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18193         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18194                            UNSPEC_FIST))
18195    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18196   "reload_completed"
18197   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18198   "")
18199
18200 (define_expand "lrintxf<mode>2"
18201   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18202      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18203                       UNSPEC_FIST))]
18204   "TARGET_USE_FANCY_MATH_387"
18205   "")
18206
18207 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18208   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18209      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18210                         UNSPEC_FIX_NOTRUNC))]
18211   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18212    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18213   "")
18214
18215 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18216   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18217    (match_operand:MODEF 1 "register_operand" "")]
18218   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18219    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18220    && !flag_trapping_math && !flag_rounding_math"
18221 {
18222   if (optimize_insn_for_size_p ())
18223     FAIL;
18224   ix86_expand_lround (operand0, operand1);
18225   DONE;
18226 })
18227
18228 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18229 (define_insn_and_split "frndintxf2_floor"
18230   [(set (match_operand:XF 0 "register_operand" "")
18231         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18232          UNSPEC_FRNDINT_FLOOR))
18233    (clobber (reg:CC FLAGS_REG))]
18234   "TARGET_USE_FANCY_MATH_387
18235    && flag_unsafe_math_optimizations
18236    && !(reload_completed || reload_in_progress)"
18237   "#"
18238   "&& 1"
18239   [(const_int 0)]
18240 {
18241   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18242
18243   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18244   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18245
18246   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18247                                         operands[2], operands[3]));
18248   DONE;
18249 }
18250   [(set_attr "type" "frndint")
18251    (set_attr "i387_cw" "floor")
18252    (set_attr "mode" "XF")])
18253
18254 (define_insn "frndintxf2_floor_i387"
18255   [(set (match_operand:XF 0 "register_operand" "=f")
18256         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18257          UNSPEC_FRNDINT_FLOOR))
18258    (use (match_operand:HI 2 "memory_operand" "m"))
18259    (use (match_operand:HI 3 "memory_operand" "m"))]
18260   "TARGET_USE_FANCY_MATH_387
18261    && flag_unsafe_math_optimizations"
18262   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18263   [(set_attr "type" "frndint")
18264    (set_attr "i387_cw" "floor")
18265    (set_attr "mode" "XF")])
18266
18267 (define_expand "floorxf2"
18268   [(use (match_operand:XF 0 "register_operand" ""))
18269    (use (match_operand:XF 1 "register_operand" ""))]
18270   "TARGET_USE_FANCY_MATH_387
18271    && flag_unsafe_math_optimizations"
18272 {
18273   if (optimize_insn_for_size_p ())
18274     FAIL;
18275   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18276   DONE;
18277 })
18278
18279 (define_expand "floor<mode>2"
18280   [(use (match_operand:MODEF 0 "register_operand" ""))
18281    (use (match_operand:MODEF 1 "register_operand" ""))]
18282   "(TARGET_USE_FANCY_MATH_387
18283     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18284         || TARGET_MIX_SSE_I387)
18285     && flag_unsafe_math_optimizations)
18286    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18287        && !flag_trapping_math)"
18288 {
18289   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18290       && !flag_trapping_math
18291       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18292     {
18293       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18294         FAIL;
18295       if (TARGET_ROUND)
18296         emit_insn (gen_sse4_1_round<mode>2
18297                    (operands[0], operands[1], GEN_INT (0x01)));
18298       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18299         ix86_expand_floorceil (operand0, operand1, true);
18300       else
18301         ix86_expand_floorceildf_32 (operand0, operand1, true);
18302     }
18303   else
18304     {
18305       rtx op0, op1;
18306
18307       if (optimize_insn_for_size_p ())
18308         FAIL;
18309
18310       op0 = gen_reg_rtx (XFmode);
18311       op1 = gen_reg_rtx (XFmode);
18312       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18313       emit_insn (gen_frndintxf2_floor (op0, op1));
18314
18315       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18316     }
18317   DONE;
18318 })
18319
18320 (define_insn_and_split "*fist<mode>2_floor_1"
18321   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18322         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18323          UNSPEC_FIST_FLOOR))
18324    (clobber (reg:CC FLAGS_REG))]
18325   "TARGET_USE_FANCY_MATH_387
18326    && flag_unsafe_math_optimizations
18327    && !(reload_completed || reload_in_progress)"
18328   "#"
18329   "&& 1"
18330   [(const_int 0)]
18331 {
18332   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18333
18334   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18335   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18336   if (memory_operand (operands[0], VOIDmode))
18337     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18338                                       operands[2], operands[3]));
18339   else
18340     {
18341       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18342       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18343                                                   operands[2], operands[3],
18344                                                   operands[4]));
18345     }
18346   DONE;
18347 }
18348   [(set_attr "type" "fistp")
18349    (set_attr "i387_cw" "floor")
18350    (set_attr "mode" "<MODE>")])
18351
18352 (define_insn "fistdi2_floor"
18353   [(set (match_operand:DI 0 "memory_operand" "=m")
18354         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18355          UNSPEC_FIST_FLOOR))
18356    (use (match_operand:HI 2 "memory_operand" "m"))
18357    (use (match_operand:HI 3 "memory_operand" "m"))
18358    (clobber (match_scratch:XF 4 "=&1f"))]
18359   "TARGET_USE_FANCY_MATH_387
18360    && flag_unsafe_math_optimizations"
18361   "* return output_fix_trunc (insn, operands, 0);"
18362   [(set_attr "type" "fistp")
18363    (set_attr "i387_cw" "floor")
18364    (set_attr "mode" "DI")])
18365
18366 (define_insn "fistdi2_floor_with_temp"
18367   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18368         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18369          UNSPEC_FIST_FLOOR))
18370    (use (match_operand:HI 2 "memory_operand" "m,m"))
18371    (use (match_operand:HI 3 "memory_operand" "m,m"))
18372    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18373    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18374   "TARGET_USE_FANCY_MATH_387
18375    && flag_unsafe_math_optimizations"
18376   "#"
18377   [(set_attr "type" "fistp")
18378    (set_attr "i387_cw" "floor")
18379    (set_attr "mode" "DI")])
18380
18381 (define_split
18382   [(set (match_operand:DI 0 "register_operand" "")
18383         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18384          UNSPEC_FIST_FLOOR))
18385    (use (match_operand:HI 2 "memory_operand" ""))
18386    (use (match_operand:HI 3 "memory_operand" ""))
18387    (clobber (match_operand:DI 4 "memory_operand" ""))
18388    (clobber (match_scratch 5 ""))]
18389   "reload_completed"
18390   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18391               (use (match_dup 2))
18392               (use (match_dup 3))
18393               (clobber (match_dup 5))])
18394    (set (match_dup 0) (match_dup 4))]
18395   "")
18396
18397 (define_split
18398   [(set (match_operand:DI 0 "memory_operand" "")
18399         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18400          UNSPEC_FIST_FLOOR))
18401    (use (match_operand:HI 2 "memory_operand" ""))
18402    (use (match_operand:HI 3 "memory_operand" ""))
18403    (clobber (match_operand:DI 4 "memory_operand" ""))
18404    (clobber (match_scratch 5 ""))]
18405   "reload_completed"
18406   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18407               (use (match_dup 2))
18408               (use (match_dup 3))
18409               (clobber (match_dup 5))])]
18410   "")
18411
18412 (define_insn "fist<mode>2_floor"
18413   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18414         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18415          UNSPEC_FIST_FLOOR))
18416    (use (match_operand:HI 2 "memory_operand" "m"))
18417    (use (match_operand:HI 3 "memory_operand" "m"))]
18418   "TARGET_USE_FANCY_MATH_387
18419    && flag_unsafe_math_optimizations"
18420   "* return output_fix_trunc (insn, operands, 0);"
18421   [(set_attr "type" "fistp")
18422    (set_attr "i387_cw" "floor")
18423    (set_attr "mode" "<MODE>")])
18424
18425 (define_insn "fist<mode>2_floor_with_temp"
18426   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18427         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18428          UNSPEC_FIST_FLOOR))
18429    (use (match_operand:HI 2 "memory_operand" "m,m"))
18430    (use (match_operand:HI 3 "memory_operand" "m,m"))
18431    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18432   "TARGET_USE_FANCY_MATH_387
18433    && flag_unsafe_math_optimizations"
18434   "#"
18435   [(set_attr "type" "fistp")
18436    (set_attr "i387_cw" "floor")
18437    (set_attr "mode" "<MODE>")])
18438
18439 (define_split
18440   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18441         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18442          UNSPEC_FIST_FLOOR))
18443    (use (match_operand:HI 2 "memory_operand" ""))
18444    (use (match_operand:HI 3 "memory_operand" ""))
18445    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18446   "reload_completed"
18447   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18448                                   UNSPEC_FIST_FLOOR))
18449               (use (match_dup 2))
18450               (use (match_dup 3))])
18451    (set (match_dup 0) (match_dup 4))]
18452   "")
18453
18454 (define_split
18455   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18456         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18457          UNSPEC_FIST_FLOOR))
18458    (use (match_operand:HI 2 "memory_operand" ""))
18459    (use (match_operand:HI 3 "memory_operand" ""))
18460    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18461   "reload_completed"
18462   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18463                                   UNSPEC_FIST_FLOOR))
18464               (use (match_dup 2))
18465               (use (match_dup 3))])]
18466   "")
18467
18468 (define_expand "lfloorxf<mode>2"
18469   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18470                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18471                     UNSPEC_FIST_FLOOR))
18472               (clobber (reg:CC FLAGS_REG))])]
18473   "TARGET_USE_FANCY_MATH_387
18474    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18475    && flag_unsafe_math_optimizations"
18476   "")
18477
18478 (define_expand "lfloor<mode>di2"
18479   [(match_operand:DI 0 "nonimmediate_operand" "")
18480    (match_operand:MODEF 1 "register_operand" "")]
18481   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18482    && !flag_trapping_math"
18483 {
18484   if (optimize_insn_for_size_p ())
18485     FAIL;
18486   ix86_expand_lfloorceil (operand0, operand1, true);
18487   DONE;
18488 })
18489
18490 (define_expand "lfloor<mode>si2"
18491   [(match_operand:SI 0 "nonimmediate_operand" "")
18492    (match_operand:MODEF 1 "register_operand" "")]
18493   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18494    && !flag_trapping_math"
18495 {
18496   if (optimize_insn_for_size_p () && TARGET_64BIT)
18497     FAIL;
18498   ix86_expand_lfloorceil (operand0, operand1, true);
18499   DONE;
18500 })
18501
18502 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18503 (define_insn_and_split "frndintxf2_ceil"
18504   [(set (match_operand:XF 0 "register_operand" "")
18505         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18506          UNSPEC_FRNDINT_CEIL))
18507    (clobber (reg:CC FLAGS_REG))]
18508   "TARGET_USE_FANCY_MATH_387
18509    && flag_unsafe_math_optimizations
18510    && !(reload_completed || reload_in_progress)"
18511   "#"
18512   "&& 1"
18513   [(const_int 0)]
18514 {
18515   ix86_optimize_mode_switching[I387_CEIL] = 1;
18516
18517   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18518   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18519
18520   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18521                                        operands[2], operands[3]));
18522   DONE;
18523 }
18524   [(set_attr "type" "frndint")
18525    (set_attr "i387_cw" "ceil")
18526    (set_attr "mode" "XF")])
18527
18528 (define_insn "frndintxf2_ceil_i387"
18529   [(set (match_operand:XF 0 "register_operand" "=f")
18530         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18531          UNSPEC_FRNDINT_CEIL))
18532    (use (match_operand:HI 2 "memory_operand" "m"))
18533    (use (match_operand:HI 3 "memory_operand" "m"))]
18534   "TARGET_USE_FANCY_MATH_387
18535    && flag_unsafe_math_optimizations"
18536   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18537   [(set_attr "type" "frndint")
18538    (set_attr "i387_cw" "ceil")
18539    (set_attr "mode" "XF")])
18540
18541 (define_expand "ceilxf2"
18542   [(use (match_operand:XF 0 "register_operand" ""))
18543    (use (match_operand:XF 1 "register_operand" ""))]
18544   "TARGET_USE_FANCY_MATH_387
18545    && flag_unsafe_math_optimizations"
18546 {
18547   if (optimize_insn_for_size_p ())
18548     FAIL;
18549   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18550   DONE;
18551 })
18552
18553 (define_expand "ceil<mode>2"
18554   [(use (match_operand:MODEF 0 "register_operand" ""))
18555    (use (match_operand:MODEF 1 "register_operand" ""))]
18556   "(TARGET_USE_FANCY_MATH_387
18557     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18558         || TARGET_MIX_SSE_I387)
18559     && flag_unsafe_math_optimizations)
18560    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18561        && !flag_trapping_math)"
18562 {
18563   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18564       && !flag_trapping_math
18565       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18566     {
18567       if (TARGET_ROUND)
18568         emit_insn (gen_sse4_1_round<mode>2
18569                    (operands[0], operands[1], GEN_INT (0x02)));
18570       else if (optimize_insn_for_size_p ())
18571         FAIL;
18572       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18573         ix86_expand_floorceil (operand0, operand1, false);
18574       else
18575         ix86_expand_floorceildf_32 (operand0, operand1, false);
18576     }
18577   else
18578     {
18579       rtx op0, op1;
18580
18581       if (optimize_insn_for_size_p ())
18582         FAIL;
18583
18584       op0 = gen_reg_rtx (XFmode);
18585       op1 = gen_reg_rtx (XFmode);
18586       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18587       emit_insn (gen_frndintxf2_ceil (op0, op1));
18588
18589       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18590     }
18591   DONE;
18592 })
18593
18594 (define_insn_and_split "*fist<mode>2_ceil_1"
18595   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18596         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18597          UNSPEC_FIST_CEIL))
18598    (clobber (reg:CC FLAGS_REG))]
18599   "TARGET_USE_FANCY_MATH_387
18600    && flag_unsafe_math_optimizations
18601    && !(reload_completed || reload_in_progress)"
18602   "#"
18603   "&& 1"
18604   [(const_int 0)]
18605 {
18606   ix86_optimize_mode_switching[I387_CEIL] = 1;
18607
18608   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18609   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18610   if (memory_operand (operands[0], VOIDmode))
18611     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18612                                      operands[2], operands[3]));
18613   else
18614     {
18615       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18616       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18617                                                  operands[2], operands[3],
18618                                                  operands[4]));
18619     }
18620   DONE;
18621 }
18622   [(set_attr "type" "fistp")
18623    (set_attr "i387_cw" "ceil")
18624    (set_attr "mode" "<MODE>")])
18625
18626 (define_insn "fistdi2_ceil"
18627   [(set (match_operand:DI 0 "memory_operand" "=m")
18628         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18629          UNSPEC_FIST_CEIL))
18630    (use (match_operand:HI 2 "memory_operand" "m"))
18631    (use (match_operand:HI 3 "memory_operand" "m"))
18632    (clobber (match_scratch:XF 4 "=&1f"))]
18633   "TARGET_USE_FANCY_MATH_387
18634    && flag_unsafe_math_optimizations"
18635   "* return output_fix_trunc (insn, operands, 0);"
18636   [(set_attr "type" "fistp")
18637    (set_attr "i387_cw" "ceil")
18638    (set_attr "mode" "DI")])
18639
18640 (define_insn "fistdi2_ceil_with_temp"
18641   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18642         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18643          UNSPEC_FIST_CEIL))
18644    (use (match_operand:HI 2 "memory_operand" "m,m"))
18645    (use (match_operand:HI 3 "memory_operand" "m,m"))
18646    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18647    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18648   "TARGET_USE_FANCY_MATH_387
18649    && flag_unsafe_math_optimizations"
18650   "#"
18651   [(set_attr "type" "fistp")
18652    (set_attr "i387_cw" "ceil")
18653    (set_attr "mode" "DI")])
18654
18655 (define_split
18656   [(set (match_operand:DI 0 "register_operand" "")
18657         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18658          UNSPEC_FIST_CEIL))
18659    (use (match_operand:HI 2 "memory_operand" ""))
18660    (use (match_operand:HI 3 "memory_operand" ""))
18661    (clobber (match_operand:DI 4 "memory_operand" ""))
18662    (clobber (match_scratch 5 ""))]
18663   "reload_completed"
18664   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18665               (use (match_dup 2))
18666               (use (match_dup 3))
18667               (clobber (match_dup 5))])
18668    (set (match_dup 0) (match_dup 4))]
18669   "")
18670
18671 (define_split
18672   [(set (match_operand:DI 0 "memory_operand" "")
18673         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18674          UNSPEC_FIST_CEIL))
18675    (use (match_operand:HI 2 "memory_operand" ""))
18676    (use (match_operand:HI 3 "memory_operand" ""))
18677    (clobber (match_operand:DI 4 "memory_operand" ""))
18678    (clobber (match_scratch 5 ""))]
18679   "reload_completed"
18680   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18681               (use (match_dup 2))
18682               (use (match_dup 3))
18683               (clobber (match_dup 5))])]
18684   "")
18685
18686 (define_insn "fist<mode>2_ceil"
18687   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18688         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18689          UNSPEC_FIST_CEIL))
18690    (use (match_operand:HI 2 "memory_operand" "m"))
18691    (use (match_operand:HI 3 "memory_operand" "m"))]
18692   "TARGET_USE_FANCY_MATH_387
18693    && flag_unsafe_math_optimizations"
18694   "* return output_fix_trunc (insn, operands, 0);"
18695   [(set_attr "type" "fistp")
18696    (set_attr "i387_cw" "ceil")
18697    (set_attr "mode" "<MODE>")])
18698
18699 (define_insn "fist<mode>2_ceil_with_temp"
18700   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18701         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18702          UNSPEC_FIST_CEIL))
18703    (use (match_operand:HI 2 "memory_operand" "m,m"))
18704    (use (match_operand:HI 3 "memory_operand" "m,m"))
18705    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18706   "TARGET_USE_FANCY_MATH_387
18707    && flag_unsafe_math_optimizations"
18708   "#"
18709   [(set_attr "type" "fistp")
18710    (set_attr "i387_cw" "ceil")
18711    (set_attr "mode" "<MODE>")])
18712
18713 (define_split
18714   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18715         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18716          UNSPEC_FIST_CEIL))
18717    (use (match_operand:HI 2 "memory_operand" ""))
18718    (use (match_operand:HI 3 "memory_operand" ""))
18719    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18720   "reload_completed"
18721   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18722                                   UNSPEC_FIST_CEIL))
18723               (use (match_dup 2))
18724               (use (match_dup 3))])
18725    (set (match_dup 0) (match_dup 4))]
18726   "")
18727
18728 (define_split
18729   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18730         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18731          UNSPEC_FIST_CEIL))
18732    (use (match_operand:HI 2 "memory_operand" ""))
18733    (use (match_operand:HI 3 "memory_operand" ""))
18734    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18735   "reload_completed"
18736   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18737                                   UNSPEC_FIST_CEIL))
18738               (use (match_dup 2))
18739               (use (match_dup 3))])]
18740   "")
18741
18742 (define_expand "lceilxf<mode>2"
18743   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18744                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18745                     UNSPEC_FIST_CEIL))
18746               (clobber (reg:CC FLAGS_REG))])]
18747   "TARGET_USE_FANCY_MATH_387
18748    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18749    && flag_unsafe_math_optimizations"
18750   "")
18751
18752 (define_expand "lceil<mode>di2"
18753   [(match_operand:DI 0 "nonimmediate_operand" "")
18754    (match_operand:MODEF 1 "register_operand" "")]
18755   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18756    && !flag_trapping_math"
18757 {
18758   ix86_expand_lfloorceil (operand0, operand1, false);
18759   DONE;
18760 })
18761
18762 (define_expand "lceil<mode>si2"
18763   [(match_operand:SI 0 "nonimmediate_operand" "")
18764    (match_operand:MODEF 1 "register_operand" "")]
18765   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18766    && !flag_trapping_math"
18767 {
18768   ix86_expand_lfloorceil (operand0, operand1, false);
18769   DONE;
18770 })
18771
18772 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18773 (define_insn_and_split "frndintxf2_trunc"
18774   [(set (match_operand:XF 0 "register_operand" "")
18775         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18776          UNSPEC_FRNDINT_TRUNC))
18777    (clobber (reg:CC FLAGS_REG))]
18778   "TARGET_USE_FANCY_MATH_387
18779    && flag_unsafe_math_optimizations
18780    && !(reload_completed || reload_in_progress)"
18781   "#"
18782   "&& 1"
18783   [(const_int 0)]
18784 {
18785   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18786
18787   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18788   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18789
18790   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18791                                         operands[2], operands[3]));
18792   DONE;
18793 }
18794   [(set_attr "type" "frndint")
18795    (set_attr "i387_cw" "trunc")
18796    (set_attr "mode" "XF")])
18797
18798 (define_insn "frndintxf2_trunc_i387"
18799   [(set (match_operand:XF 0 "register_operand" "=f")
18800         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18801          UNSPEC_FRNDINT_TRUNC))
18802    (use (match_operand:HI 2 "memory_operand" "m"))
18803    (use (match_operand:HI 3 "memory_operand" "m"))]
18804   "TARGET_USE_FANCY_MATH_387
18805    && flag_unsafe_math_optimizations"
18806   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18807   [(set_attr "type" "frndint")
18808    (set_attr "i387_cw" "trunc")
18809    (set_attr "mode" "XF")])
18810
18811 (define_expand "btruncxf2"
18812   [(use (match_operand:XF 0 "register_operand" ""))
18813    (use (match_operand:XF 1 "register_operand" ""))]
18814   "TARGET_USE_FANCY_MATH_387
18815    && flag_unsafe_math_optimizations"
18816 {
18817   if (optimize_insn_for_size_p ())
18818     FAIL;
18819   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18820   DONE;
18821 })
18822
18823 (define_expand "btrunc<mode>2"
18824   [(use (match_operand:MODEF 0 "register_operand" ""))
18825    (use (match_operand:MODEF 1 "register_operand" ""))]
18826   "(TARGET_USE_FANCY_MATH_387
18827     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18828         || TARGET_MIX_SSE_I387)
18829     && flag_unsafe_math_optimizations)
18830    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18831        && !flag_trapping_math)"
18832 {
18833   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18834       && !flag_trapping_math
18835       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18836     {
18837       if (TARGET_ROUND)
18838         emit_insn (gen_sse4_1_round<mode>2
18839                    (operands[0], operands[1], GEN_INT (0x03)));
18840       else if (optimize_insn_for_size_p ())
18841         FAIL;
18842       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18843         ix86_expand_trunc (operand0, operand1);
18844       else
18845         ix86_expand_truncdf_32 (operand0, operand1);
18846     }
18847   else
18848     {
18849       rtx op0, op1;
18850
18851       if (optimize_insn_for_size_p ())
18852         FAIL;
18853
18854       op0 = gen_reg_rtx (XFmode);
18855       op1 = gen_reg_rtx (XFmode);
18856       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18857       emit_insn (gen_frndintxf2_trunc (op0, op1));
18858
18859       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18860     }
18861   DONE;
18862 })
18863
18864 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18865 (define_insn_and_split "frndintxf2_mask_pm"
18866   [(set (match_operand:XF 0 "register_operand" "")
18867         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18868          UNSPEC_FRNDINT_MASK_PM))
18869    (clobber (reg:CC FLAGS_REG))]
18870   "TARGET_USE_FANCY_MATH_387
18871    && flag_unsafe_math_optimizations
18872    && !(reload_completed || reload_in_progress)"
18873   "#"
18874   "&& 1"
18875   [(const_int 0)]
18876 {
18877   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18878
18879   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18880   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18881
18882   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18883                                           operands[2], operands[3]));
18884   DONE;
18885 }
18886   [(set_attr "type" "frndint")
18887    (set_attr "i387_cw" "mask_pm")
18888    (set_attr "mode" "XF")])
18889
18890 (define_insn "frndintxf2_mask_pm_i387"
18891   [(set (match_operand:XF 0 "register_operand" "=f")
18892         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18893          UNSPEC_FRNDINT_MASK_PM))
18894    (use (match_operand:HI 2 "memory_operand" "m"))
18895    (use (match_operand:HI 3 "memory_operand" "m"))]
18896   "TARGET_USE_FANCY_MATH_387
18897    && flag_unsafe_math_optimizations"
18898   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18899   [(set_attr "type" "frndint")
18900    (set_attr "i387_cw" "mask_pm")
18901    (set_attr "mode" "XF")])
18902
18903 (define_expand "nearbyintxf2"
18904   [(use (match_operand:XF 0 "register_operand" ""))
18905    (use (match_operand:XF 1 "register_operand" ""))]
18906   "TARGET_USE_FANCY_MATH_387
18907    && flag_unsafe_math_optimizations"
18908 {
18909   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18910
18911   DONE;
18912 })
18913
18914 (define_expand "nearbyint<mode>2"
18915   [(use (match_operand:MODEF 0 "register_operand" ""))
18916    (use (match_operand:MODEF 1 "register_operand" ""))]
18917   "TARGET_USE_FANCY_MATH_387
18918    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18919        || TARGET_MIX_SSE_I387)
18920    && flag_unsafe_math_optimizations"
18921 {
18922   rtx op0 = gen_reg_rtx (XFmode);
18923   rtx op1 = gen_reg_rtx (XFmode);
18924
18925   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18926   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18927
18928   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18929   DONE;
18930 })
18931
18932 (define_insn "fxam<mode>2_i387"
18933   [(set (match_operand:HI 0 "register_operand" "=a")
18934         (unspec:HI
18935           [(match_operand:X87MODEF 1 "register_operand" "f")]
18936           UNSPEC_FXAM))]
18937   "TARGET_USE_FANCY_MATH_387"
18938   "fxam\n\tfnstsw\t%0"
18939   [(set_attr "type" "multi")
18940    (set_attr "unit" "i387")
18941    (set_attr "mode" "<MODE>")])
18942
18943 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18944   [(set (match_operand:HI 0 "register_operand" "")
18945         (unspec:HI
18946           [(match_operand:MODEF 1 "memory_operand" "")]
18947           UNSPEC_FXAM_MEM))]
18948   "TARGET_USE_FANCY_MATH_387
18949    && !(reload_completed || reload_in_progress)"
18950   "#"
18951   "&& 1"
18952   [(set (match_dup 2)(match_dup 1))
18953    (set (match_dup 0)
18954         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18955 {
18956   operands[2] = gen_reg_rtx (<MODE>mode);
18957
18958   MEM_VOLATILE_P (operands[1]) = 1;
18959 }
18960   [(set_attr "type" "multi")
18961    (set_attr "unit" "i387")
18962    (set_attr "mode" "<MODE>")])
18963
18964 (define_expand "isinfxf2"
18965   [(use (match_operand:SI 0 "register_operand" ""))
18966    (use (match_operand:XF 1 "register_operand" ""))]
18967   "TARGET_USE_FANCY_MATH_387
18968    && TARGET_C99_FUNCTIONS"
18969 {
18970   rtx mask = GEN_INT (0x45);
18971   rtx val = GEN_INT (0x05);
18972
18973   rtx cond;
18974
18975   rtx scratch = gen_reg_rtx (HImode);
18976   rtx res = gen_reg_rtx (QImode);
18977
18978   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18979
18980   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18981   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18982   cond = gen_rtx_fmt_ee (EQ, QImode,
18983                          gen_rtx_REG (CCmode, FLAGS_REG),
18984                          const0_rtx);
18985   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18986   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18987   DONE;
18988 })
18989
18990 (define_expand "isinf<mode>2"
18991   [(use (match_operand:SI 0 "register_operand" ""))
18992    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18993   "TARGET_USE_FANCY_MATH_387
18994    && TARGET_C99_FUNCTIONS
18995    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18996 {
18997   rtx mask = GEN_INT (0x45);
18998   rtx val = GEN_INT (0x05);
18999
19000   rtx cond;
19001
19002   rtx scratch = gen_reg_rtx (HImode);
19003   rtx res = gen_reg_rtx (QImode);
19004
19005   /* Remove excess precision by forcing value through memory. */
19006   if (memory_operand (operands[1], VOIDmode))
19007     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19008   else
19009     {
19010       enum ix86_stack_slot slot = (virtuals_instantiated
19011                                    ? SLOT_TEMP
19012                                    : SLOT_VIRTUAL);
19013       rtx temp = assign_386_stack_local (<MODE>mode, slot);
19014
19015       emit_move_insn (temp, operands[1]);
19016       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19017     }
19018
19019   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19020   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19021   cond = gen_rtx_fmt_ee (EQ, QImode,
19022                          gen_rtx_REG (CCmode, FLAGS_REG),
19023                          const0_rtx);
19024   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19025   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19026   DONE;
19027 })
19028
19029 (define_expand "signbit<mode>2"
19030   [(use (match_operand:SI 0 "register_operand" ""))
19031    (use (match_operand:X87MODEF 1 "register_operand" ""))]
19032   "TARGET_USE_FANCY_MATH_387
19033    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19034 {
19035   rtx mask = GEN_INT (0x0200);
19036
19037   rtx scratch = gen_reg_rtx (HImode);
19038
19039   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19040   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19041   DONE;
19042 })
19043 \f
19044 ;; Block operation instructions
19045
19046 (define_insn "cld"
19047   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19048   ""
19049   "cld"
19050   [(set_attr "length" "1")
19051    (set_attr "length_immediate" "0")
19052    (set_attr "modrm" "0")])
19053
19054 (define_expand "movmemsi"
19055   [(use (match_operand:BLK 0 "memory_operand" ""))
19056    (use (match_operand:BLK 1 "memory_operand" ""))
19057    (use (match_operand:SI 2 "nonmemory_operand" ""))
19058    (use (match_operand:SI 3 "const_int_operand" ""))
19059    (use (match_operand:SI 4 "const_int_operand" ""))
19060    (use (match_operand:SI 5 "const_int_operand" ""))]
19061   ""
19062 {
19063  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19064                          operands[4], operands[5]))
19065    DONE;
19066  else
19067    FAIL;
19068 })
19069
19070 (define_expand "movmemdi"
19071   [(use (match_operand:BLK 0 "memory_operand" ""))
19072    (use (match_operand:BLK 1 "memory_operand" ""))
19073    (use (match_operand:DI 2 "nonmemory_operand" ""))
19074    (use (match_operand:DI 3 "const_int_operand" ""))
19075    (use (match_operand:SI 4 "const_int_operand" ""))
19076    (use (match_operand:SI 5 "const_int_operand" ""))]
19077   "TARGET_64BIT"
19078 {
19079  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19080                          operands[4], operands[5]))
19081    DONE;
19082  else
19083    FAIL;
19084 })
19085
19086 ;; Most CPUs don't like single string operations
19087 ;; Handle this case here to simplify previous expander.
19088
19089 (define_expand "strmov"
19090   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19091    (set (match_operand 1 "memory_operand" "") (match_dup 4))
19092    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19093               (clobber (reg:CC FLAGS_REG))])
19094    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19095               (clobber (reg:CC FLAGS_REG))])]
19096   ""
19097 {
19098   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19099
19100   /* If .md ever supports :P for Pmode, these can be directly
19101      in the pattern above.  */
19102   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19103   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19104
19105   /* Can't use this if the user has appropriated esi or edi.  */
19106   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19107       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19108     {
19109       emit_insn (gen_strmov_singleop (operands[0], operands[1],
19110                                       operands[2], operands[3],
19111                                       operands[5], operands[6]));
19112       DONE;
19113     }
19114
19115   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19116 })
19117
19118 (define_expand "strmov_singleop"
19119   [(parallel [(set (match_operand 1 "memory_operand" "")
19120                    (match_operand 3 "memory_operand" ""))
19121               (set (match_operand 0 "register_operand" "")
19122                    (match_operand 4 "" ""))
19123               (set (match_operand 2 "register_operand" "")
19124                    (match_operand 5 "" ""))])]
19125   ""
19126   "ix86_current_function_needs_cld = 1;")
19127
19128 (define_insn "*strmovdi_rex_1"
19129   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19130         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19131    (set (match_operand:DI 0 "register_operand" "=D")
19132         (plus:DI (match_dup 2)
19133                  (const_int 8)))
19134    (set (match_operand:DI 1 "register_operand" "=S")
19135         (plus:DI (match_dup 3)
19136                  (const_int 8)))]
19137   "TARGET_64BIT"
19138   "movsq"
19139   [(set_attr "type" "str")
19140    (set_attr "mode" "DI")
19141    (set_attr "memory" "both")])
19142
19143 (define_insn "*strmovsi_1"
19144   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19145         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19146    (set (match_operand:SI 0 "register_operand" "=D")
19147         (plus:SI (match_dup 2)
19148                  (const_int 4)))
19149    (set (match_operand:SI 1 "register_operand" "=S")
19150         (plus:SI (match_dup 3)
19151                  (const_int 4)))]
19152   "!TARGET_64BIT"
19153   "movs{l|d}"
19154   [(set_attr "type" "str")
19155    (set_attr "mode" "SI")
19156    (set_attr "memory" "both")])
19157
19158 (define_insn "*strmovsi_rex_1"
19159   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19160         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19161    (set (match_operand:DI 0 "register_operand" "=D")
19162         (plus:DI (match_dup 2)
19163                  (const_int 4)))
19164    (set (match_operand:DI 1 "register_operand" "=S")
19165         (plus:DI (match_dup 3)
19166                  (const_int 4)))]
19167   "TARGET_64BIT"
19168   "movs{l|d}"
19169   [(set_attr "type" "str")
19170    (set_attr "mode" "SI")
19171    (set_attr "memory" "both")])
19172
19173 (define_insn "*strmovhi_1"
19174   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19175         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19176    (set (match_operand:SI 0 "register_operand" "=D")
19177         (plus:SI (match_dup 2)
19178                  (const_int 2)))
19179    (set (match_operand:SI 1 "register_operand" "=S")
19180         (plus:SI (match_dup 3)
19181                  (const_int 2)))]
19182   "!TARGET_64BIT"
19183   "movsw"
19184   [(set_attr "type" "str")
19185    (set_attr "memory" "both")
19186    (set_attr "mode" "HI")])
19187
19188 (define_insn "*strmovhi_rex_1"
19189   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19190         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19191    (set (match_operand:DI 0 "register_operand" "=D")
19192         (plus:DI (match_dup 2)
19193                  (const_int 2)))
19194    (set (match_operand:DI 1 "register_operand" "=S")
19195         (plus:DI (match_dup 3)
19196                  (const_int 2)))]
19197   "TARGET_64BIT"
19198   "movsw"
19199   [(set_attr "type" "str")
19200    (set_attr "memory" "both")
19201    (set_attr "mode" "HI")])
19202
19203 (define_insn "*strmovqi_1"
19204   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19205         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19206    (set (match_operand:SI 0 "register_operand" "=D")
19207         (plus:SI (match_dup 2)
19208                  (const_int 1)))
19209    (set (match_operand:SI 1 "register_operand" "=S")
19210         (plus:SI (match_dup 3)
19211                  (const_int 1)))]
19212   "!TARGET_64BIT"
19213   "movsb"
19214   [(set_attr "type" "str")
19215    (set_attr "memory" "both")
19216    (set_attr "mode" "QI")])
19217
19218 (define_insn "*strmovqi_rex_1"
19219   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19220         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19221    (set (match_operand:DI 0 "register_operand" "=D")
19222         (plus:DI (match_dup 2)
19223                  (const_int 1)))
19224    (set (match_operand:DI 1 "register_operand" "=S")
19225         (plus:DI (match_dup 3)
19226                  (const_int 1)))]
19227   "TARGET_64BIT"
19228   "movsb"
19229   [(set_attr "type" "str")
19230    (set_attr "memory" "both")
19231    (set_attr "mode" "QI")])
19232
19233 (define_expand "rep_mov"
19234   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19235               (set (match_operand 0 "register_operand" "")
19236                    (match_operand 5 "" ""))
19237               (set (match_operand 2 "register_operand" "")
19238                    (match_operand 6 "" ""))
19239               (set (match_operand 1 "memory_operand" "")
19240                    (match_operand 3 "memory_operand" ""))
19241               (use (match_dup 4))])]
19242   ""
19243   "ix86_current_function_needs_cld = 1;")
19244
19245 (define_insn "*rep_movdi_rex64"
19246   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19247    (set (match_operand:DI 0 "register_operand" "=D")
19248         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19249                             (const_int 3))
19250                  (match_operand:DI 3 "register_operand" "0")))
19251    (set (match_operand:DI 1 "register_operand" "=S")
19252         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19253                  (match_operand:DI 4 "register_operand" "1")))
19254    (set (mem:BLK (match_dup 3))
19255         (mem:BLK (match_dup 4)))
19256    (use (match_dup 5))]
19257   "TARGET_64BIT"
19258   "rep movsq"
19259   [(set_attr "type" "str")
19260    (set_attr "prefix_rep" "1")
19261    (set_attr "memory" "both")
19262    (set_attr "mode" "DI")])
19263
19264 (define_insn "*rep_movsi"
19265   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19266    (set (match_operand:SI 0 "register_operand" "=D")
19267         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19268                             (const_int 2))
19269                  (match_operand:SI 3 "register_operand" "0")))
19270    (set (match_operand:SI 1 "register_operand" "=S")
19271         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19272                  (match_operand:SI 4 "register_operand" "1")))
19273    (set (mem:BLK (match_dup 3))
19274         (mem:BLK (match_dup 4)))
19275    (use (match_dup 5))]
19276   "!TARGET_64BIT"
19277   "rep movs{l|d}"
19278   [(set_attr "type" "str")
19279    (set_attr "prefix_rep" "1")
19280    (set_attr "memory" "both")
19281    (set_attr "mode" "SI")])
19282
19283 (define_insn "*rep_movsi_rex64"
19284   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19285    (set (match_operand:DI 0 "register_operand" "=D")
19286         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19287                             (const_int 2))
19288                  (match_operand:DI 3 "register_operand" "0")))
19289    (set (match_operand:DI 1 "register_operand" "=S")
19290         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19291                  (match_operand:DI 4 "register_operand" "1")))
19292    (set (mem:BLK (match_dup 3))
19293         (mem:BLK (match_dup 4)))
19294    (use (match_dup 5))]
19295   "TARGET_64BIT"
19296   "rep movs{l|d}"
19297   [(set_attr "type" "str")
19298    (set_attr "prefix_rep" "1")
19299    (set_attr "memory" "both")
19300    (set_attr "mode" "SI")])
19301
19302 (define_insn "*rep_movqi"
19303   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19304    (set (match_operand:SI 0 "register_operand" "=D")
19305         (plus:SI (match_operand:SI 3 "register_operand" "0")
19306                  (match_operand:SI 5 "register_operand" "2")))
19307    (set (match_operand:SI 1 "register_operand" "=S")
19308         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19309    (set (mem:BLK (match_dup 3))
19310         (mem:BLK (match_dup 4)))
19311    (use (match_dup 5))]
19312   "!TARGET_64BIT"
19313   "rep movsb"
19314   [(set_attr "type" "str")
19315    (set_attr "prefix_rep" "1")
19316    (set_attr "memory" "both")
19317    (set_attr "mode" "SI")])
19318
19319 (define_insn "*rep_movqi_rex64"
19320   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19321    (set (match_operand:DI 0 "register_operand" "=D")
19322         (plus:DI (match_operand:DI 3 "register_operand" "0")
19323                  (match_operand:DI 5 "register_operand" "2")))
19324    (set (match_operand:DI 1 "register_operand" "=S")
19325         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19326    (set (mem:BLK (match_dup 3))
19327         (mem:BLK (match_dup 4)))
19328    (use (match_dup 5))]
19329   "TARGET_64BIT"
19330   "rep movsb"
19331   [(set_attr "type" "str")
19332    (set_attr "prefix_rep" "1")
19333    (set_attr "memory" "both")
19334    (set_attr "mode" "SI")])
19335
19336 (define_expand "setmemsi"
19337    [(use (match_operand:BLK 0 "memory_operand" ""))
19338     (use (match_operand:SI 1 "nonmemory_operand" ""))
19339     (use (match_operand 2 "const_int_operand" ""))
19340     (use (match_operand 3 "const_int_operand" ""))
19341     (use (match_operand:SI 4 "const_int_operand" ""))
19342     (use (match_operand:SI 5 "const_int_operand" ""))]
19343   ""
19344 {
19345  if (ix86_expand_setmem (operands[0], operands[1],
19346                          operands[2], operands[3],
19347                          operands[4], operands[5]))
19348    DONE;
19349  else
19350    FAIL;
19351 })
19352
19353 (define_expand "setmemdi"
19354    [(use (match_operand:BLK 0 "memory_operand" ""))
19355     (use (match_operand:DI 1 "nonmemory_operand" ""))
19356     (use (match_operand 2 "const_int_operand" ""))
19357     (use (match_operand 3 "const_int_operand" ""))
19358     (use (match_operand 4 "const_int_operand" ""))
19359     (use (match_operand 5 "const_int_operand" ""))]
19360   "TARGET_64BIT"
19361 {
19362  if (ix86_expand_setmem (operands[0], operands[1],
19363                          operands[2], operands[3],
19364                          operands[4], operands[5]))
19365    DONE;
19366  else
19367    FAIL;
19368 })
19369
19370 ;; Most CPUs don't like single string operations
19371 ;; Handle this case here to simplify previous expander.
19372
19373 (define_expand "strset"
19374   [(set (match_operand 1 "memory_operand" "")
19375         (match_operand 2 "register_operand" ""))
19376    (parallel [(set (match_operand 0 "register_operand" "")
19377                    (match_dup 3))
19378               (clobber (reg:CC FLAGS_REG))])]
19379   ""
19380 {
19381   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19382     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19383
19384   /* If .md ever supports :P for Pmode, this can be directly
19385      in the pattern above.  */
19386   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19387                               GEN_INT (GET_MODE_SIZE (GET_MODE
19388                                                       (operands[2]))));
19389   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19390     {
19391       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19392                                       operands[3]));
19393       DONE;
19394     }
19395 })
19396
19397 (define_expand "strset_singleop"
19398   [(parallel [(set (match_operand 1 "memory_operand" "")
19399                    (match_operand 2 "register_operand" ""))
19400               (set (match_operand 0 "register_operand" "")
19401                    (match_operand 3 "" ""))])]
19402   ""
19403   "ix86_current_function_needs_cld = 1;")
19404
19405 (define_insn "*strsetdi_rex_1"
19406   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19407         (match_operand:DI 2 "register_operand" "a"))
19408    (set (match_operand:DI 0 "register_operand" "=D")
19409         (plus:DI (match_dup 1)
19410                  (const_int 8)))]
19411   "TARGET_64BIT"
19412   "stosq"
19413   [(set_attr "type" "str")
19414    (set_attr "memory" "store")
19415    (set_attr "mode" "DI")])
19416
19417 (define_insn "*strsetsi_1"
19418   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19419         (match_operand:SI 2 "register_operand" "a"))
19420    (set (match_operand:SI 0 "register_operand" "=D")
19421         (plus:SI (match_dup 1)
19422                  (const_int 4)))]
19423   "!TARGET_64BIT"
19424   "stos{l|d}"
19425   [(set_attr "type" "str")
19426    (set_attr "memory" "store")
19427    (set_attr "mode" "SI")])
19428
19429 (define_insn "*strsetsi_rex_1"
19430   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19431         (match_operand:SI 2 "register_operand" "a"))
19432    (set (match_operand:DI 0 "register_operand" "=D")
19433         (plus:DI (match_dup 1)
19434                  (const_int 4)))]
19435   "TARGET_64BIT"
19436   "stos{l|d}"
19437   [(set_attr "type" "str")
19438    (set_attr "memory" "store")
19439    (set_attr "mode" "SI")])
19440
19441 (define_insn "*strsethi_1"
19442   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19443         (match_operand:HI 2 "register_operand" "a"))
19444    (set (match_operand:SI 0 "register_operand" "=D")
19445         (plus:SI (match_dup 1)
19446                  (const_int 2)))]
19447   "!TARGET_64BIT"
19448   "stosw"
19449   [(set_attr "type" "str")
19450    (set_attr "memory" "store")
19451    (set_attr "mode" "HI")])
19452
19453 (define_insn "*strsethi_rex_1"
19454   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19455         (match_operand:HI 2 "register_operand" "a"))
19456    (set (match_operand:DI 0 "register_operand" "=D")
19457         (plus:DI (match_dup 1)
19458                  (const_int 2)))]
19459   "TARGET_64BIT"
19460   "stosw"
19461   [(set_attr "type" "str")
19462    (set_attr "memory" "store")
19463    (set_attr "mode" "HI")])
19464
19465 (define_insn "*strsetqi_1"
19466   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19467         (match_operand:QI 2 "register_operand" "a"))
19468    (set (match_operand:SI 0 "register_operand" "=D")
19469         (plus:SI (match_dup 1)
19470                  (const_int 1)))]
19471   "!TARGET_64BIT"
19472   "stosb"
19473   [(set_attr "type" "str")
19474    (set_attr "memory" "store")
19475    (set_attr "mode" "QI")])
19476
19477 (define_insn "*strsetqi_rex_1"
19478   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19479         (match_operand:QI 2 "register_operand" "a"))
19480    (set (match_operand:DI 0 "register_operand" "=D")
19481         (plus:DI (match_dup 1)
19482                  (const_int 1)))]
19483   "TARGET_64BIT"
19484   "stosb"
19485   [(set_attr "type" "str")
19486    (set_attr "memory" "store")
19487    (set_attr "mode" "QI")])
19488
19489 (define_expand "rep_stos"
19490   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19491               (set (match_operand 0 "register_operand" "")
19492                    (match_operand 4 "" ""))
19493               (set (match_operand 2 "memory_operand" "") (const_int 0))
19494               (use (match_operand 3 "register_operand" ""))
19495               (use (match_dup 1))])]
19496   ""
19497   "ix86_current_function_needs_cld = 1;")
19498
19499 (define_insn "*rep_stosdi_rex64"
19500   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19501    (set (match_operand:DI 0 "register_operand" "=D")
19502         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19503                             (const_int 3))
19504                  (match_operand:DI 3 "register_operand" "0")))
19505    (set (mem:BLK (match_dup 3))
19506         (const_int 0))
19507    (use (match_operand:DI 2 "register_operand" "a"))
19508    (use (match_dup 4))]
19509   "TARGET_64BIT"
19510   "rep stosq"
19511   [(set_attr "type" "str")
19512    (set_attr "prefix_rep" "1")
19513    (set_attr "memory" "store")
19514    (set_attr "mode" "DI")])
19515
19516 (define_insn "*rep_stossi"
19517   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19518    (set (match_operand:SI 0 "register_operand" "=D")
19519         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19520                             (const_int 2))
19521                  (match_operand:SI 3 "register_operand" "0")))
19522    (set (mem:BLK (match_dup 3))
19523         (const_int 0))
19524    (use (match_operand:SI 2 "register_operand" "a"))
19525    (use (match_dup 4))]
19526   "!TARGET_64BIT"
19527   "rep stos{l|d}"
19528   [(set_attr "type" "str")
19529    (set_attr "prefix_rep" "1")
19530    (set_attr "memory" "store")
19531    (set_attr "mode" "SI")])
19532
19533 (define_insn "*rep_stossi_rex64"
19534   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19535    (set (match_operand:DI 0 "register_operand" "=D")
19536         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19537                             (const_int 2))
19538                  (match_operand:DI 3 "register_operand" "0")))
19539    (set (mem:BLK (match_dup 3))
19540         (const_int 0))
19541    (use (match_operand:SI 2 "register_operand" "a"))
19542    (use (match_dup 4))]
19543   "TARGET_64BIT"
19544   "rep stos{l|d}"
19545   [(set_attr "type" "str")
19546    (set_attr "prefix_rep" "1")
19547    (set_attr "memory" "store")
19548    (set_attr "mode" "SI")])
19549
19550 (define_insn "*rep_stosqi"
19551   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19552    (set (match_operand:SI 0 "register_operand" "=D")
19553         (plus:SI (match_operand:SI 3 "register_operand" "0")
19554                  (match_operand:SI 4 "register_operand" "1")))
19555    (set (mem:BLK (match_dup 3))
19556         (const_int 0))
19557    (use (match_operand:QI 2 "register_operand" "a"))
19558    (use (match_dup 4))]
19559   "!TARGET_64BIT"
19560   "rep stosb"
19561   [(set_attr "type" "str")
19562    (set_attr "prefix_rep" "1")
19563    (set_attr "memory" "store")
19564    (set_attr "mode" "QI")])
19565
19566 (define_insn "*rep_stosqi_rex64"
19567   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19568    (set (match_operand:DI 0 "register_operand" "=D")
19569         (plus:DI (match_operand:DI 3 "register_operand" "0")
19570                  (match_operand:DI 4 "register_operand" "1")))
19571    (set (mem:BLK (match_dup 3))
19572         (const_int 0))
19573    (use (match_operand:QI 2 "register_operand" "a"))
19574    (use (match_dup 4))]
19575   "TARGET_64BIT"
19576   "rep stosb"
19577   [(set_attr "type" "str")
19578    (set_attr "prefix_rep" "1")
19579    (set_attr "memory" "store")
19580    (set_attr "mode" "QI")])
19581
19582 (define_expand "cmpstrnsi"
19583   [(set (match_operand:SI 0 "register_operand" "")
19584         (compare:SI (match_operand:BLK 1 "general_operand" "")
19585                     (match_operand:BLK 2 "general_operand" "")))
19586    (use (match_operand 3 "general_operand" ""))
19587    (use (match_operand 4 "immediate_operand" ""))]
19588   ""
19589 {
19590   rtx addr1, addr2, out, outlow, count, countreg, align;
19591
19592   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19593     FAIL;
19594
19595   /* Can't use this if the user has appropriated esi or edi.  */
19596   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19597     FAIL;
19598
19599   out = operands[0];
19600   if (!REG_P (out))
19601     out = gen_reg_rtx (SImode);
19602
19603   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19604   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19605   if (addr1 != XEXP (operands[1], 0))
19606     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19607   if (addr2 != XEXP (operands[2], 0))
19608     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19609
19610   count = operands[3];
19611   countreg = ix86_zero_extend_to_Pmode (count);
19612
19613   /* %%% Iff we are testing strict equality, we can use known alignment
19614      to good advantage.  This may be possible with combine, particularly
19615      once cc0 is dead.  */
19616   align = operands[4];
19617
19618   if (CONST_INT_P (count))
19619     {
19620       if (INTVAL (count) == 0)
19621         {
19622           emit_move_insn (operands[0], const0_rtx);
19623           DONE;
19624         }
19625       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19626                                      operands[1], operands[2]));
19627     }
19628   else
19629     {
19630       if (TARGET_64BIT)
19631         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19632       else
19633         emit_insn (gen_cmpsi_1 (countreg, countreg));
19634       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19635                                   operands[1], operands[2]));
19636     }
19637
19638   outlow = gen_lowpart (QImode, out);
19639   emit_insn (gen_cmpintqi (outlow));
19640   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19641
19642   if (operands[0] != out)
19643     emit_move_insn (operands[0], out);
19644
19645   DONE;
19646 })
19647
19648 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19649
19650 (define_expand "cmpintqi"
19651   [(set (match_dup 1)
19652         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19653    (set (match_dup 2)
19654         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19655    (parallel [(set (match_operand:QI 0 "register_operand" "")
19656                    (minus:QI (match_dup 1)
19657                              (match_dup 2)))
19658               (clobber (reg:CC FLAGS_REG))])]
19659   ""
19660   "operands[1] = gen_reg_rtx (QImode);
19661    operands[2] = gen_reg_rtx (QImode);")
19662
19663 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19664 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19665
19666 (define_expand "cmpstrnqi_nz_1"
19667   [(parallel [(set (reg:CC FLAGS_REG)
19668                    (compare:CC (match_operand 4 "memory_operand" "")
19669                                (match_operand 5 "memory_operand" "")))
19670               (use (match_operand 2 "register_operand" ""))
19671               (use (match_operand:SI 3 "immediate_operand" ""))
19672               (clobber (match_operand 0 "register_operand" ""))
19673               (clobber (match_operand 1 "register_operand" ""))
19674               (clobber (match_dup 2))])]
19675   ""
19676   "ix86_current_function_needs_cld = 1;")
19677
19678 (define_insn "*cmpstrnqi_nz_1"
19679   [(set (reg:CC FLAGS_REG)
19680         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19681                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19682    (use (match_operand:SI 6 "register_operand" "2"))
19683    (use (match_operand:SI 3 "immediate_operand" "i"))
19684    (clobber (match_operand:SI 0 "register_operand" "=S"))
19685    (clobber (match_operand:SI 1 "register_operand" "=D"))
19686    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19687   "!TARGET_64BIT"
19688   "repz cmpsb"
19689   [(set_attr "type" "str")
19690    (set_attr "mode" "QI")
19691    (set_attr "prefix_rep" "1")])
19692
19693 (define_insn "*cmpstrnqi_nz_rex_1"
19694   [(set (reg:CC FLAGS_REG)
19695         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19696                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19697    (use (match_operand:DI 6 "register_operand" "2"))
19698    (use (match_operand:SI 3 "immediate_operand" "i"))
19699    (clobber (match_operand:DI 0 "register_operand" "=S"))
19700    (clobber (match_operand:DI 1 "register_operand" "=D"))
19701    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19702   "TARGET_64BIT"
19703   "repz cmpsb"
19704   [(set_attr "type" "str")
19705    (set_attr "mode" "QI")
19706    (set_attr "prefix_rep" "1")])
19707
19708 ;; The same, but the count is not known to not be zero.
19709
19710 (define_expand "cmpstrnqi_1"
19711   [(parallel [(set (reg:CC FLAGS_REG)
19712                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19713                                      (const_int 0))
19714                   (compare:CC (match_operand 4 "memory_operand" "")
19715                               (match_operand 5 "memory_operand" ""))
19716                   (const_int 0)))
19717               (use (match_operand:SI 3 "immediate_operand" ""))
19718               (use (reg:CC FLAGS_REG))
19719               (clobber (match_operand 0 "register_operand" ""))
19720               (clobber (match_operand 1 "register_operand" ""))
19721               (clobber (match_dup 2))])]
19722   ""
19723   "ix86_current_function_needs_cld = 1;")
19724
19725 (define_insn "*cmpstrnqi_1"
19726   [(set (reg:CC FLAGS_REG)
19727         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19728                              (const_int 0))
19729           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19730                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19731           (const_int 0)))
19732    (use (match_operand:SI 3 "immediate_operand" "i"))
19733    (use (reg:CC FLAGS_REG))
19734    (clobber (match_operand:SI 0 "register_operand" "=S"))
19735    (clobber (match_operand:SI 1 "register_operand" "=D"))
19736    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19737   "!TARGET_64BIT"
19738   "repz cmpsb"
19739   [(set_attr "type" "str")
19740    (set_attr "mode" "QI")
19741    (set_attr "prefix_rep" "1")])
19742
19743 (define_insn "*cmpstrnqi_rex_1"
19744   [(set (reg:CC FLAGS_REG)
19745         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19746                              (const_int 0))
19747           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19748                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19749           (const_int 0)))
19750    (use (match_operand:SI 3 "immediate_operand" "i"))
19751    (use (reg:CC FLAGS_REG))
19752    (clobber (match_operand:DI 0 "register_operand" "=S"))
19753    (clobber (match_operand:DI 1 "register_operand" "=D"))
19754    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19755   "TARGET_64BIT"
19756   "repz cmpsb"
19757   [(set_attr "type" "str")
19758    (set_attr "mode" "QI")
19759    (set_attr "prefix_rep" "1")])
19760
19761 (define_expand "strlensi"
19762   [(set (match_operand:SI 0 "register_operand" "")
19763         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19764                     (match_operand:QI 2 "immediate_operand" "")
19765                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19766   ""
19767 {
19768  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19769    DONE;
19770  else
19771    FAIL;
19772 })
19773
19774 (define_expand "strlendi"
19775   [(set (match_operand:DI 0 "register_operand" "")
19776         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19777                     (match_operand:QI 2 "immediate_operand" "")
19778                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19779   ""
19780 {
19781  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19782    DONE;
19783  else
19784    FAIL;
19785 })
19786
19787 (define_expand "strlenqi_1"
19788   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19789               (clobber (match_operand 1 "register_operand" ""))
19790               (clobber (reg:CC FLAGS_REG))])]
19791   ""
19792   "ix86_current_function_needs_cld = 1;")
19793
19794 (define_insn "*strlenqi_1"
19795   [(set (match_operand:SI 0 "register_operand" "=&c")
19796         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19797                     (match_operand:QI 2 "register_operand" "a")
19798                     (match_operand:SI 3 "immediate_operand" "i")
19799                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19800    (clobber (match_operand:SI 1 "register_operand" "=D"))
19801    (clobber (reg:CC FLAGS_REG))]
19802   "!TARGET_64BIT"
19803   "repnz scasb"
19804   [(set_attr "type" "str")
19805    (set_attr "mode" "QI")
19806    (set_attr "prefix_rep" "1")])
19807
19808 (define_insn "*strlenqi_rex_1"
19809   [(set (match_operand:DI 0 "register_operand" "=&c")
19810         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19811                     (match_operand:QI 2 "register_operand" "a")
19812                     (match_operand:DI 3 "immediate_operand" "i")
19813                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19814    (clobber (match_operand:DI 1 "register_operand" "=D"))
19815    (clobber (reg:CC FLAGS_REG))]
19816   "TARGET_64BIT"
19817   "repnz scasb"
19818   [(set_attr "type" "str")
19819    (set_attr "mode" "QI")
19820    (set_attr "prefix_rep" "1")])
19821
19822 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19823 ;; handled in combine, but it is not currently up to the task.
19824 ;; When used for their truth value, the cmpstrn* expanders generate
19825 ;; code like this:
19826 ;;
19827 ;;   repz cmpsb
19828 ;;   seta       %al
19829 ;;   setb       %dl
19830 ;;   cmpb       %al, %dl
19831 ;;   jcc        label
19832 ;;
19833 ;; The intermediate three instructions are unnecessary.
19834
19835 ;; This one handles cmpstrn*_nz_1...
19836 (define_peephole2
19837   [(parallel[
19838      (set (reg:CC FLAGS_REG)
19839           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19840                       (mem:BLK (match_operand 5 "register_operand" ""))))
19841      (use (match_operand 6 "register_operand" ""))
19842      (use (match_operand:SI 3 "immediate_operand" ""))
19843      (clobber (match_operand 0 "register_operand" ""))
19844      (clobber (match_operand 1 "register_operand" ""))
19845      (clobber (match_operand 2 "register_operand" ""))])
19846    (set (match_operand:QI 7 "register_operand" "")
19847         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19848    (set (match_operand:QI 8 "register_operand" "")
19849         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19850    (set (reg FLAGS_REG)
19851         (compare (match_dup 7) (match_dup 8)))
19852   ]
19853   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19854   [(parallel[
19855      (set (reg:CC FLAGS_REG)
19856           (compare:CC (mem:BLK (match_dup 4))
19857                       (mem:BLK (match_dup 5))))
19858      (use (match_dup 6))
19859      (use (match_dup 3))
19860      (clobber (match_dup 0))
19861      (clobber (match_dup 1))
19862      (clobber (match_dup 2))])]
19863   "")
19864
19865 ;; ...and this one handles cmpstrn*_1.
19866 (define_peephole2
19867   [(parallel[
19868      (set (reg:CC FLAGS_REG)
19869           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19870                                (const_int 0))
19871             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19872                         (mem:BLK (match_operand 5 "register_operand" "")))
19873             (const_int 0)))
19874      (use (match_operand:SI 3 "immediate_operand" ""))
19875      (use (reg:CC FLAGS_REG))
19876      (clobber (match_operand 0 "register_operand" ""))
19877      (clobber (match_operand 1 "register_operand" ""))
19878      (clobber (match_operand 2 "register_operand" ""))])
19879    (set (match_operand:QI 7 "register_operand" "")
19880         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19881    (set (match_operand:QI 8 "register_operand" "")
19882         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19883    (set (reg FLAGS_REG)
19884         (compare (match_dup 7) (match_dup 8)))
19885   ]
19886   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19887   [(parallel[
19888      (set (reg:CC FLAGS_REG)
19889           (if_then_else:CC (ne (match_dup 6)
19890                                (const_int 0))
19891             (compare:CC (mem:BLK (match_dup 4))
19892                         (mem:BLK (match_dup 5)))
19893             (const_int 0)))
19894      (use (match_dup 3))
19895      (use (reg:CC FLAGS_REG))
19896      (clobber (match_dup 0))
19897      (clobber (match_dup 1))
19898      (clobber (match_dup 2))])]
19899   "")
19900
19901
19902 \f
19903 ;; Conditional move instructions.
19904
19905 (define_expand "movdicc"
19906   [(set (match_operand:DI 0 "register_operand" "")
19907         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19908                          (match_operand:DI 2 "general_operand" "")
19909                          (match_operand:DI 3 "general_operand" "")))]
19910   "TARGET_64BIT"
19911   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19912
19913 (define_insn "x86_movdicc_0_m1_rex64"
19914   [(set (match_operand:DI 0 "register_operand" "=r")
19915         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19916           (const_int -1)
19917           (const_int 0)))
19918    (clobber (reg:CC FLAGS_REG))]
19919   "TARGET_64BIT"
19920   "sbb{q}\t%0, %0"
19921   ; Since we don't have the proper number of operands for an alu insn,
19922   ; fill in all the blanks.
19923   [(set_attr "type" "alu")
19924    (set_attr "use_carry" "1")
19925    (set_attr "pent_pair" "pu")
19926    (set_attr "memory" "none")
19927    (set_attr "imm_disp" "false")
19928    (set_attr "mode" "DI")
19929    (set_attr "length_immediate" "0")])
19930
19931 (define_insn "*x86_movdicc_0_m1_se"
19932   [(set (match_operand:DI 0 "register_operand" "=r")
19933         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19934                          (const_int 1)
19935                          (const_int 0)))
19936    (clobber (reg:CC FLAGS_REG))]
19937   ""
19938   "sbb{q}\t%0, %0"
19939   [(set_attr "type" "alu")
19940    (set_attr "use_carry" "1")
19941    (set_attr "pent_pair" "pu")
19942    (set_attr "memory" "none")
19943    (set_attr "imm_disp" "false")
19944    (set_attr "mode" "DI")
19945    (set_attr "length_immediate" "0")])
19946
19947 (define_insn "*movdicc_c_rex64"
19948   [(set (match_operand:DI 0 "register_operand" "=r,r")
19949         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19950                                 [(reg FLAGS_REG) (const_int 0)])
19951                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19952                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19953   "TARGET_64BIT && TARGET_CMOVE
19954    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19955   "@
19956    cmov%O2%C1\t{%2, %0|%0, %2}
19957    cmov%O2%c1\t{%3, %0|%0, %3}"
19958   [(set_attr "type" "icmov")
19959    (set_attr "mode" "DI")])
19960
19961 (define_expand "movsicc"
19962   [(set (match_operand:SI 0 "register_operand" "")
19963         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19964                          (match_operand:SI 2 "general_operand" "")
19965                          (match_operand:SI 3 "general_operand" "")))]
19966   ""
19967   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19968
19969 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19970 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19971 ;; So just document what we're doing explicitly.
19972
19973 (define_insn "x86_movsicc_0_m1"
19974   [(set (match_operand:SI 0 "register_operand" "=r")
19975         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19976           (const_int -1)
19977           (const_int 0)))
19978    (clobber (reg:CC FLAGS_REG))]
19979   ""
19980   "sbb{l}\t%0, %0"
19981   ; Since we don't have the proper number of operands for an alu insn,
19982   ; fill in all the blanks.
19983   [(set_attr "type" "alu")
19984    (set_attr "use_carry" "1")
19985    (set_attr "pent_pair" "pu")
19986    (set_attr "memory" "none")
19987    (set_attr "imm_disp" "false")
19988    (set_attr "mode" "SI")
19989    (set_attr "length_immediate" "0")])
19990
19991 (define_insn "*x86_movsicc_0_m1_se"
19992   [(set (match_operand:SI 0 "register_operand" "=r")
19993         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19994                          (const_int 1)
19995                          (const_int 0)))
19996    (clobber (reg:CC FLAGS_REG))]
19997   ""
19998   "sbb{l}\t%0, %0"
19999   [(set_attr "type" "alu")
20000    (set_attr "use_carry" "1")
20001    (set_attr "pent_pair" "pu")
20002    (set_attr "memory" "none")
20003    (set_attr "imm_disp" "false")
20004    (set_attr "mode" "SI")
20005    (set_attr "length_immediate" "0")])
20006
20007 (define_insn "*movsicc_noc"
20008   [(set (match_operand:SI 0 "register_operand" "=r,r")
20009         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
20010                                 [(reg FLAGS_REG) (const_int 0)])
20011                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20012                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
20013   "TARGET_CMOVE
20014    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20015   "@
20016    cmov%O2%C1\t{%2, %0|%0, %2}
20017    cmov%O2%c1\t{%3, %0|%0, %3}"
20018   [(set_attr "type" "icmov")
20019    (set_attr "mode" "SI")])
20020
20021 (define_expand "movhicc"
20022   [(set (match_operand:HI 0 "register_operand" "")
20023         (if_then_else:HI (match_operand 1 "comparison_operator" "")
20024                          (match_operand:HI 2 "general_operand" "")
20025                          (match_operand:HI 3 "general_operand" "")))]
20026   "TARGET_HIMODE_MATH"
20027   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20028
20029 (define_insn "*movhicc_noc"
20030   [(set (match_operand:HI 0 "register_operand" "=r,r")
20031         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
20032                                 [(reg FLAGS_REG) (const_int 0)])
20033                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20034                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20035   "TARGET_CMOVE
20036    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20037   "@
20038    cmov%O2%C1\t{%2, %0|%0, %2}
20039    cmov%O2%c1\t{%3, %0|%0, %3}"
20040   [(set_attr "type" "icmov")
20041    (set_attr "mode" "HI")])
20042
20043 (define_expand "movqicc"
20044   [(set (match_operand:QI 0 "register_operand" "")
20045         (if_then_else:QI (match_operand 1 "comparison_operator" "")
20046                          (match_operand:QI 2 "general_operand" "")
20047                          (match_operand:QI 3 "general_operand" "")))]
20048   "TARGET_QIMODE_MATH"
20049   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20050
20051 (define_insn_and_split "*movqicc_noc"
20052   [(set (match_operand:QI 0 "register_operand" "=r,r")
20053         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20054                                 [(match_operand 4 "flags_reg_operand" "")
20055                                  (const_int 0)])
20056                       (match_operand:QI 2 "register_operand" "r,0")
20057                       (match_operand:QI 3 "register_operand" "0,r")))]
20058   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20059   "#"
20060   "&& reload_completed"
20061   [(set (match_dup 0)
20062         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20063                       (match_dup 2)
20064                       (match_dup 3)))]
20065   "operands[0] = gen_lowpart (SImode, operands[0]);
20066    operands[2] = gen_lowpart (SImode, operands[2]);
20067    operands[3] = gen_lowpart (SImode, operands[3]);"
20068   [(set_attr "type" "icmov")
20069    (set_attr "mode" "SI")])
20070
20071 (define_expand "mov<mode>cc"
20072   [(set (match_operand:X87MODEF 0 "register_operand" "")
20073         (if_then_else:X87MODEF
20074           (match_operand 1 "comparison_operator" "")
20075           (match_operand:X87MODEF 2 "register_operand" "")
20076           (match_operand:X87MODEF 3 "register_operand" "")))]
20077   "(TARGET_80387 && TARGET_CMOVE)
20078    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20079   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20080
20081 (define_insn "*movsfcc_1_387"
20082   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20083         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20084                                 [(reg FLAGS_REG) (const_int 0)])
20085                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20086                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20087   "TARGET_80387 && TARGET_CMOVE
20088    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20089   "@
20090    fcmov%F1\t{%2, %0|%0, %2}
20091    fcmov%f1\t{%3, %0|%0, %3}
20092    cmov%O2%C1\t{%2, %0|%0, %2}
20093    cmov%O2%c1\t{%3, %0|%0, %3}"
20094   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20095    (set_attr "mode" "SF,SF,SI,SI")])
20096
20097 (define_insn "*movdfcc_1"
20098   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20099         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20100                                 [(reg FLAGS_REG) (const_int 0)])
20101                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20102                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20103   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20104    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20105   "@
20106    fcmov%F1\t{%2, %0|%0, %2}
20107    fcmov%f1\t{%3, %0|%0, %3}
20108    #
20109    #"
20110   [(set_attr "type" "fcmov,fcmov,multi,multi")
20111    (set_attr "mode" "DF")])
20112
20113 (define_insn "*movdfcc_1_rex64"
20114   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20115         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20116                                 [(reg FLAGS_REG) (const_int 0)])
20117                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20118                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20119   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20120    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20121   "@
20122    fcmov%F1\t{%2, %0|%0, %2}
20123    fcmov%f1\t{%3, %0|%0, %3}
20124    cmov%O2%C1\t{%2, %0|%0, %2}
20125    cmov%O2%c1\t{%3, %0|%0, %3}"
20126   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20127    (set_attr "mode" "DF")])
20128
20129 (define_split
20130   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20131         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20132                                 [(match_operand 4 "flags_reg_operand" "")
20133                                  (const_int 0)])
20134                       (match_operand:DF 2 "nonimmediate_operand" "")
20135                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20136   "!TARGET_64BIT && reload_completed"
20137   [(set (match_dup 2)
20138         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20139                       (match_dup 5)
20140                       (match_dup 6)))
20141    (set (match_dup 3)
20142         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20143                       (match_dup 7)
20144                       (match_dup 8)))]
20145   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20146    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20147
20148 (define_insn "*movxfcc_1"
20149   [(set (match_operand:XF 0 "register_operand" "=f,f")
20150         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20151                                 [(reg FLAGS_REG) (const_int 0)])
20152                       (match_operand:XF 2 "register_operand" "f,0")
20153                       (match_operand:XF 3 "register_operand" "0,f")))]
20154   "TARGET_80387 && TARGET_CMOVE"
20155   "@
20156    fcmov%F1\t{%2, %0|%0, %2}
20157    fcmov%f1\t{%3, %0|%0, %3}"
20158   [(set_attr "type" "fcmov")
20159    (set_attr "mode" "XF")])
20160
20161 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20162 ;; the scalar versions to have only XMM registers as operands.
20163
20164 ;; SSE5 conditional move
20165 (define_insn "*sse5_pcmov_<mode>"
20166   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20167         (if_then_else:MODEF
20168           (match_operand:MODEF 1 "register_operand" "x,0")
20169           (match_operand:MODEF 2 "register_operand" "0,x")
20170           (match_operand:MODEF 3 "register_operand" "x,x")))]
20171   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20172   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20173   [(set_attr "type" "sse4arg")])
20174
20175 ;; These versions of the min/max patterns are intentionally ignorant of
20176 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20177 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20178 ;; are undefined in this condition, we're certain this is correct.
20179
20180 (define_insn "*avx_<code><mode>3"
20181   [(set (match_operand:MODEF 0 "register_operand" "=x")
20182         (smaxmin:MODEF
20183           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20184           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20185   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20186   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20187   [(set_attr "type" "sseadd")
20188    (set_attr "prefix" "vex")
20189    (set_attr "mode" "<MODE>")])
20190
20191 (define_insn "<code><mode>3"
20192   [(set (match_operand:MODEF 0 "register_operand" "=x")
20193         (smaxmin:MODEF
20194           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20195           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20196   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20197   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20198   [(set_attr "type" "sseadd")
20199    (set_attr "mode" "<MODE>")])
20200
20201 ;; These versions of the min/max patterns implement exactly the operations
20202 ;;   min = (op1 < op2 ? op1 : op2)
20203 ;;   max = (!(op1 < op2) ? op1 : op2)
20204 ;; Their operands are not commutative, and thus they may be used in the
20205 ;; presence of -0.0 and NaN.
20206
20207 (define_insn "*avx_ieee_smin<mode>3"
20208   [(set (match_operand:MODEF 0 "register_operand" "=x")
20209         (unspec:MODEF
20210           [(match_operand:MODEF 1 "register_operand" "x")
20211            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20212          UNSPEC_IEEE_MIN))]
20213   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20214   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20215   [(set_attr "type" "sseadd")
20216    (set_attr "prefix" "vex")
20217    (set_attr "mode" "<MODE>")])
20218
20219 (define_insn "*ieee_smin<mode>3"
20220   [(set (match_operand:MODEF 0 "register_operand" "=x")
20221         (unspec:MODEF
20222           [(match_operand:MODEF 1 "register_operand" "0")
20223            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20224          UNSPEC_IEEE_MIN))]
20225   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20226   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20227   [(set_attr "type" "sseadd")
20228    (set_attr "mode" "<MODE>")])
20229
20230 (define_insn "*avx_ieee_smax<mode>3"
20231   [(set (match_operand:MODEF 0 "register_operand" "=x")
20232         (unspec:MODEF
20233           [(match_operand:MODEF 1 "register_operand" "0")
20234            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20235          UNSPEC_IEEE_MAX))]
20236   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20237   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20238   [(set_attr "type" "sseadd")
20239    (set_attr "prefix" "vex")
20240    (set_attr "mode" "<MODE>")])
20241
20242 (define_insn "*ieee_smax<mode>3"
20243   [(set (match_operand:MODEF 0 "register_operand" "=x")
20244         (unspec:MODEF
20245           [(match_operand:MODEF 1 "register_operand" "0")
20246            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20247          UNSPEC_IEEE_MAX))]
20248   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20249   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20250   [(set_attr "type" "sseadd")
20251    (set_attr "mode" "<MODE>")])
20252
20253 ;; Make two stack loads independent:
20254 ;;   fld aa              fld aa
20255 ;;   fld %st(0)     ->   fld bb
20256 ;;   fmul bb             fmul %st(1), %st
20257 ;;
20258 ;; Actually we only match the last two instructions for simplicity.
20259 (define_peephole2
20260   [(set (match_operand 0 "fp_register_operand" "")
20261         (match_operand 1 "fp_register_operand" ""))
20262    (set (match_dup 0)
20263         (match_operator 2 "binary_fp_operator"
20264            [(match_dup 0)
20265             (match_operand 3 "memory_operand" "")]))]
20266   "REGNO (operands[0]) != REGNO (operands[1])"
20267   [(set (match_dup 0) (match_dup 3))
20268    (set (match_dup 0) (match_dup 4))]
20269
20270   ;; The % modifier is not operational anymore in peephole2's, so we have to
20271   ;; swap the operands manually in the case of addition and multiplication.
20272   "if (COMMUTATIVE_ARITH_P (operands[2]))
20273      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20274                                  operands[0], operands[1]);
20275    else
20276      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20277                                  operands[1], operands[0]);")
20278
20279 ;; Conditional addition patterns
20280 (define_expand "add<mode>cc"
20281   [(match_operand:SWI 0 "register_operand" "")
20282    (match_operand 1 "comparison_operator" "")
20283    (match_operand:SWI 2 "register_operand" "")
20284    (match_operand:SWI 3 "const_int_operand" "")]
20285   ""
20286   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20287
20288 \f
20289 ;; Misc patterns (?)
20290
20291 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20292 ;; Otherwise there will be nothing to keep
20293 ;;
20294 ;; [(set (reg ebp) (reg esp))]
20295 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20296 ;;  (clobber (eflags)]
20297 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20298 ;;
20299 ;; in proper program order.
20300 (define_insn "pro_epilogue_adjust_stack_1"
20301   [(set (match_operand:SI 0 "register_operand" "=r,r")
20302         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20303                  (match_operand:SI 2 "immediate_operand" "i,i")))
20304    (clobber (reg:CC FLAGS_REG))
20305    (clobber (mem:BLK (scratch)))]
20306   "!TARGET_64BIT"
20307 {
20308   switch (get_attr_type (insn))
20309     {
20310     case TYPE_IMOV:
20311       return "mov{l}\t{%1, %0|%0, %1}";
20312
20313     case TYPE_ALU:
20314       if (CONST_INT_P (operands[2])
20315           && (INTVAL (operands[2]) == 128
20316               || (INTVAL (operands[2]) < 0
20317                   && INTVAL (operands[2]) != -128)))
20318         {
20319           operands[2] = GEN_INT (-INTVAL (operands[2]));
20320           return "sub{l}\t{%2, %0|%0, %2}";
20321         }
20322       return "add{l}\t{%2, %0|%0, %2}";
20323
20324     case TYPE_LEA:
20325       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20326       return "lea{l}\t{%a2, %0|%0, %a2}";
20327
20328     default:
20329       gcc_unreachable ();
20330     }
20331 }
20332   [(set (attr "type")
20333         (cond [(and (eq_attr "alternative" "0") 
20334                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20335                  (const_string "alu")
20336                (match_operand:SI 2 "const0_operand" "")
20337                  (const_string "imov")
20338               ]
20339               (const_string "lea")))
20340    (set_attr "mode" "SI")])
20341
20342 (define_insn "pro_epilogue_adjust_stack_rex64"
20343   [(set (match_operand:DI 0 "register_operand" "=r,r")
20344         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20345                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20346    (clobber (reg:CC FLAGS_REG))
20347    (clobber (mem:BLK (scratch)))]
20348   "TARGET_64BIT"
20349 {
20350   switch (get_attr_type (insn))
20351     {
20352     case TYPE_IMOV:
20353       return "mov{q}\t{%1, %0|%0, %1}";
20354
20355     case TYPE_ALU:
20356       if (CONST_INT_P (operands[2])
20357           /* Avoid overflows.  */
20358           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20359           && (INTVAL (operands[2]) == 128
20360               || (INTVAL (operands[2]) < 0
20361                   && INTVAL (operands[2]) != -128)))
20362         {
20363           operands[2] = GEN_INT (-INTVAL (operands[2]));
20364           return "sub{q}\t{%2, %0|%0, %2}";
20365         }
20366       return "add{q}\t{%2, %0|%0, %2}";
20367
20368     case TYPE_LEA:
20369       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20370       return "lea{q}\t{%a2, %0|%0, %a2}";
20371
20372     default:
20373       gcc_unreachable ();
20374     }
20375 }
20376   [(set (attr "type")
20377         (cond [(and (eq_attr "alternative" "0")
20378                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20379                  (const_string "alu")
20380                (match_operand:DI 2 "const0_operand" "")
20381                  (const_string "imov")
20382               ]
20383               (const_string "lea")))
20384    (set_attr "mode" "DI")])
20385
20386 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20387   [(set (match_operand:DI 0 "register_operand" "=r,r")
20388         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20389                  (match_operand:DI 3 "immediate_operand" "i,i")))
20390    (use (match_operand:DI 2 "register_operand" "r,r"))
20391    (clobber (reg:CC FLAGS_REG))
20392    (clobber (mem:BLK (scratch)))]
20393   "TARGET_64BIT"
20394 {
20395   switch (get_attr_type (insn))
20396     {
20397     case TYPE_ALU:
20398       return "add{q}\t{%2, %0|%0, %2}";
20399
20400     case TYPE_LEA:
20401       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20402       return "lea{q}\t{%a2, %0|%0, %a2}";
20403
20404     default:
20405       gcc_unreachable ();
20406     }
20407 }
20408   [(set_attr "type" "alu,lea")
20409    (set_attr "mode" "DI")])
20410
20411 (define_insn "allocate_stack_worker_32"
20412   [(set (match_operand:SI 0 "register_operand" "=a")
20413         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20414                             UNSPECV_STACK_PROBE))
20415    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20416    (clobber (reg:CC FLAGS_REG))]
20417   "!TARGET_64BIT && TARGET_STACK_PROBE"
20418   "call\t___chkstk"
20419   [(set_attr "type" "multi")
20420    (set_attr "length" "5")])
20421
20422 (define_insn "allocate_stack_worker_64"
20423   [(set (match_operand:DI 0 "register_operand" "=a")
20424         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20425                             UNSPECV_STACK_PROBE))
20426    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20427    (clobber (reg:DI R10_REG))
20428    (clobber (reg:DI R11_REG))
20429    (clobber (reg:CC FLAGS_REG))]
20430   "TARGET_64BIT && TARGET_STACK_PROBE"
20431   "call\t___chkstk"
20432   [(set_attr "type" "multi")
20433    (set_attr "length" "5")])
20434
20435 (define_expand "allocate_stack"
20436   [(match_operand 0 "register_operand" "")
20437    (match_operand 1 "general_operand" "")]
20438   "TARGET_STACK_PROBE"
20439 {
20440   rtx x;
20441
20442 #ifndef CHECK_STACK_LIMIT
20443 #define CHECK_STACK_LIMIT 0
20444 #endif
20445
20446   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20447       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20448     {
20449       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20450                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20451       if (x != stack_pointer_rtx)
20452         emit_move_insn (stack_pointer_rtx, x);
20453     }
20454   else
20455     {
20456       x = copy_to_mode_reg (Pmode, operands[1]);
20457       if (TARGET_64BIT)
20458         x = gen_allocate_stack_worker_64 (x, x);
20459       else
20460         x = gen_allocate_stack_worker_32 (x, x);
20461       emit_insn (x);
20462     }
20463
20464   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20465   DONE;
20466 })
20467
20468 (define_expand "builtin_setjmp_receiver"
20469   [(label_ref (match_operand 0 "" ""))]
20470   "!TARGET_64BIT && flag_pic"
20471 {
20472 #if TARGET_MACHO
20473   if (TARGET_MACHO)
20474     {
20475       rtx xops[3];
20476       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20477       rtx label_rtx = gen_label_rtx ();
20478       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20479       xops[0] = xops[1] = picreg;
20480       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20481       ix86_expand_binary_operator (MINUS, SImode, xops);
20482     }
20483   else
20484 #endif
20485     emit_insn (gen_set_got (pic_offset_table_rtx));
20486   DONE;
20487 })
20488 \f
20489 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20490
20491 (define_split
20492   [(set (match_operand 0 "register_operand" "")
20493         (match_operator 3 "promotable_binary_operator"
20494            [(match_operand 1 "register_operand" "")
20495             (match_operand 2 "aligned_operand" "")]))
20496    (clobber (reg:CC FLAGS_REG))]
20497   "! TARGET_PARTIAL_REG_STALL && reload_completed
20498    && ((GET_MODE (operands[0]) == HImode
20499         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20500             /* ??? next two lines just !satisfies_constraint_K (...) */
20501             || !CONST_INT_P (operands[2])
20502             || satisfies_constraint_K (operands[2])))
20503        || (GET_MODE (operands[0]) == QImode
20504            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20505   [(parallel [(set (match_dup 0)
20506                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20507               (clobber (reg:CC FLAGS_REG))])]
20508   "operands[0] = gen_lowpart (SImode, operands[0]);
20509    operands[1] = gen_lowpart (SImode, operands[1]);
20510    if (GET_CODE (operands[3]) != ASHIFT)
20511      operands[2] = gen_lowpart (SImode, operands[2]);
20512    PUT_MODE (operands[3], SImode);")
20513
20514 ; Promote the QImode tests, as i386 has encoding of the AND
20515 ; instruction with 32-bit sign-extended immediate and thus the
20516 ; instruction size is unchanged, except in the %eax case for
20517 ; which it is increased by one byte, hence the ! optimize_size.
20518 (define_split
20519   [(set (match_operand 0 "flags_reg_operand" "")
20520         (match_operator 2 "compare_operator"
20521           [(and (match_operand 3 "aligned_operand" "")
20522                 (match_operand 4 "const_int_operand" ""))
20523            (const_int 0)]))
20524    (set (match_operand 1 "register_operand" "")
20525         (and (match_dup 3) (match_dup 4)))]
20526   "! TARGET_PARTIAL_REG_STALL && reload_completed
20527    && optimize_insn_for_speed_p ()
20528    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20529        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20530    /* Ensure that the operand will remain sign-extended immediate.  */
20531    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20532   [(parallel [(set (match_dup 0)
20533                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20534                                     (const_int 0)]))
20535               (set (match_dup 1)
20536                    (and:SI (match_dup 3) (match_dup 4)))])]
20537 {
20538   operands[4]
20539     = gen_int_mode (INTVAL (operands[4])
20540                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20541   operands[1] = gen_lowpart (SImode, operands[1]);
20542   operands[3] = gen_lowpart (SImode, operands[3]);
20543 })
20544
20545 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20546 ; the TEST instruction with 32-bit sign-extended immediate and thus
20547 ; the instruction size would at least double, which is not what we
20548 ; want even with ! optimize_size.
20549 (define_split
20550   [(set (match_operand 0 "flags_reg_operand" "")
20551         (match_operator 1 "compare_operator"
20552           [(and (match_operand:HI 2 "aligned_operand" "")
20553                 (match_operand:HI 3 "const_int_operand" ""))
20554            (const_int 0)]))]
20555   "! TARGET_PARTIAL_REG_STALL && reload_completed
20556    && ! TARGET_FAST_PREFIX
20557    && optimize_insn_for_speed_p ()
20558    /* Ensure that the operand will remain sign-extended immediate.  */
20559    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20560   [(set (match_dup 0)
20561         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20562                          (const_int 0)]))]
20563 {
20564   operands[3]
20565     = gen_int_mode (INTVAL (operands[3])
20566                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20567   operands[2] = gen_lowpart (SImode, operands[2]);
20568 })
20569
20570 (define_split
20571   [(set (match_operand 0 "register_operand" "")
20572         (neg (match_operand 1 "register_operand" "")))
20573    (clobber (reg:CC FLAGS_REG))]
20574   "! TARGET_PARTIAL_REG_STALL && reload_completed
20575    && (GET_MODE (operands[0]) == HImode
20576        || (GET_MODE (operands[0]) == QImode
20577            && (TARGET_PROMOTE_QImode
20578                || optimize_insn_for_size_p ())))"
20579   [(parallel [(set (match_dup 0)
20580                    (neg:SI (match_dup 1)))
20581               (clobber (reg:CC FLAGS_REG))])]
20582   "operands[0] = gen_lowpart (SImode, operands[0]);
20583    operands[1] = gen_lowpart (SImode, operands[1]);")
20584
20585 (define_split
20586   [(set (match_operand 0 "register_operand" "")
20587         (not (match_operand 1 "register_operand" "")))]
20588   "! TARGET_PARTIAL_REG_STALL && reload_completed
20589    && (GET_MODE (operands[0]) == HImode
20590        || (GET_MODE (operands[0]) == QImode
20591            && (TARGET_PROMOTE_QImode
20592                || optimize_insn_for_size_p ())))"
20593   [(set (match_dup 0)
20594         (not:SI (match_dup 1)))]
20595   "operands[0] = gen_lowpart (SImode, operands[0]);
20596    operands[1] = gen_lowpart (SImode, operands[1]);")
20597
20598 (define_split
20599   [(set (match_operand 0 "register_operand" "")
20600         (if_then_else (match_operator 1 "comparison_operator"
20601                                 [(reg FLAGS_REG) (const_int 0)])
20602                       (match_operand 2 "register_operand" "")
20603                       (match_operand 3 "register_operand" "")))]
20604   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20605    && (GET_MODE (operands[0]) == HImode
20606        || (GET_MODE (operands[0]) == QImode
20607            && (TARGET_PROMOTE_QImode
20608                || optimize_insn_for_size_p ())))"
20609   [(set (match_dup 0)
20610         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20611   "operands[0] = gen_lowpart (SImode, operands[0]);
20612    operands[2] = gen_lowpart (SImode, operands[2]);
20613    operands[3] = gen_lowpart (SImode, operands[3]);")
20614
20615 \f
20616 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20617 ;; transform a complex memory operation into two memory to register operations.
20618
20619 ;; Don't push memory operands
20620 (define_peephole2
20621   [(set (match_operand:SI 0 "push_operand" "")
20622         (match_operand:SI 1 "memory_operand" ""))
20623    (match_scratch:SI 2 "r")]
20624   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20625    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20626   [(set (match_dup 2) (match_dup 1))
20627    (set (match_dup 0) (match_dup 2))]
20628   "")
20629
20630 (define_peephole2
20631   [(set (match_operand:DI 0 "push_operand" "")
20632         (match_operand:DI 1 "memory_operand" ""))
20633    (match_scratch:DI 2 "r")]
20634   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20635    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20636   [(set (match_dup 2) (match_dup 1))
20637    (set (match_dup 0) (match_dup 2))]
20638   "")
20639
20640 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20641 ;; SImode pushes.
20642 (define_peephole2
20643   [(set (match_operand:SF 0 "push_operand" "")
20644         (match_operand:SF 1 "memory_operand" ""))
20645    (match_scratch:SF 2 "r")]
20646   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20647    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20648   [(set (match_dup 2) (match_dup 1))
20649    (set (match_dup 0) (match_dup 2))]
20650   "")
20651
20652 (define_peephole2
20653   [(set (match_operand:HI 0 "push_operand" "")
20654         (match_operand:HI 1 "memory_operand" ""))
20655    (match_scratch:HI 2 "r")]
20656   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20657    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20658   [(set (match_dup 2) (match_dup 1))
20659    (set (match_dup 0) (match_dup 2))]
20660   "")
20661
20662 (define_peephole2
20663   [(set (match_operand:QI 0 "push_operand" "")
20664         (match_operand:QI 1 "memory_operand" ""))
20665    (match_scratch:QI 2 "q")]
20666   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20667    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20668   [(set (match_dup 2) (match_dup 1))
20669    (set (match_dup 0) (match_dup 2))]
20670   "")
20671
20672 ;; Don't move an immediate directly to memory when the instruction
20673 ;; gets too big.
20674 (define_peephole2
20675   [(match_scratch:SI 1 "r")
20676    (set (match_operand:SI 0 "memory_operand" "")
20677         (const_int 0))]
20678   "optimize_insn_for_speed_p ()
20679    && ! TARGET_USE_MOV0
20680    && TARGET_SPLIT_LONG_MOVES
20681    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20682    && peep2_regno_dead_p (0, FLAGS_REG)"
20683   [(parallel [(set (match_dup 1) (const_int 0))
20684               (clobber (reg:CC FLAGS_REG))])
20685    (set (match_dup 0) (match_dup 1))]
20686   "")
20687
20688 (define_peephole2
20689   [(match_scratch:HI 1 "r")
20690    (set (match_operand:HI 0 "memory_operand" "")
20691         (const_int 0))]
20692   "optimize_insn_for_speed_p ()
20693    && ! TARGET_USE_MOV0
20694    && TARGET_SPLIT_LONG_MOVES
20695    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20696    && peep2_regno_dead_p (0, FLAGS_REG)"
20697   [(parallel [(set (match_dup 2) (const_int 0))
20698               (clobber (reg:CC FLAGS_REG))])
20699    (set (match_dup 0) (match_dup 1))]
20700   "operands[2] = gen_lowpart (SImode, operands[1]);")
20701
20702 (define_peephole2
20703   [(match_scratch:QI 1 "q")
20704    (set (match_operand:QI 0 "memory_operand" "")
20705         (const_int 0))]
20706   "optimize_insn_for_speed_p ()
20707    && ! TARGET_USE_MOV0
20708    && TARGET_SPLIT_LONG_MOVES
20709    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20710    && peep2_regno_dead_p (0, FLAGS_REG)"
20711   [(parallel [(set (match_dup 2) (const_int 0))
20712               (clobber (reg:CC FLAGS_REG))])
20713    (set (match_dup 0) (match_dup 1))]
20714   "operands[2] = gen_lowpart (SImode, operands[1]);")
20715
20716 (define_peephole2
20717   [(match_scratch:SI 2 "r")
20718    (set (match_operand:SI 0 "memory_operand" "")
20719         (match_operand:SI 1 "immediate_operand" ""))]
20720   "optimize_insn_for_speed_p ()
20721    && TARGET_SPLIT_LONG_MOVES
20722    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20723   [(set (match_dup 2) (match_dup 1))
20724    (set (match_dup 0) (match_dup 2))]
20725   "")
20726
20727 (define_peephole2
20728   [(match_scratch:HI 2 "r")
20729    (set (match_operand:HI 0 "memory_operand" "")
20730         (match_operand:HI 1 "immediate_operand" ""))]
20731   "optimize_insn_for_speed_p ()
20732    && TARGET_SPLIT_LONG_MOVES
20733    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20734   [(set (match_dup 2) (match_dup 1))
20735    (set (match_dup 0) (match_dup 2))]
20736   "")
20737
20738 (define_peephole2
20739   [(match_scratch:QI 2 "q")
20740    (set (match_operand:QI 0 "memory_operand" "")
20741         (match_operand:QI 1 "immediate_operand" ""))]
20742   "optimize_insn_for_speed_p ()
20743    && TARGET_SPLIT_LONG_MOVES
20744    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20745   [(set (match_dup 2) (match_dup 1))
20746    (set (match_dup 0) (match_dup 2))]
20747   "")
20748
20749 ;; Don't compare memory with zero, load and use a test instead.
20750 (define_peephole2
20751   [(set (match_operand 0 "flags_reg_operand" "")
20752         (match_operator 1 "compare_operator"
20753           [(match_operand:SI 2 "memory_operand" "")
20754            (const_int 0)]))
20755    (match_scratch:SI 3 "r")]
20756   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20757   [(set (match_dup 3) (match_dup 2))
20758    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20759   "")
20760
20761 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20762 ;; Don't split NOTs with a displacement operand, because resulting XOR
20763 ;; will not be pairable anyway.
20764 ;;
20765 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20766 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20767 ;; so this split helps here as well.
20768 ;;
20769 ;; Note: Can't do this as a regular split because we can't get proper
20770 ;; lifetime information then.
20771
20772 (define_peephole2
20773   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20774         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20775   "optimize_insn_for_speed_p ()
20776    && ((TARGET_NOT_UNPAIRABLE
20777         && (!MEM_P (operands[0])
20778             || !memory_displacement_operand (operands[0], SImode)))
20779        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20780    && peep2_regno_dead_p (0, FLAGS_REG)"
20781   [(parallel [(set (match_dup 0)
20782                    (xor:SI (match_dup 1) (const_int -1)))
20783               (clobber (reg:CC FLAGS_REG))])]
20784   "")
20785
20786 (define_peephole2
20787   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20788         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20789   "optimize_insn_for_speed_p ()
20790    && ((TARGET_NOT_UNPAIRABLE
20791         && (!MEM_P (operands[0])
20792             || !memory_displacement_operand (operands[0], HImode)))
20793        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20794    && peep2_regno_dead_p (0, FLAGS_REG)"
20795   [(parallel [(set (match_dup 0)
20796                    (xor:HI (match_dup 1) (const_int -1)))
20797               (clobber (reg:CC FLAGS_REG))])]
20798   "")
20799
20800 (define_peephole2
20801   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20802         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20803   "optimize_insn_for_speed_p ()
20804    && ((TARGET_NOT_UNPAIRABLE
20805         && (!MEM_P (operands[0])
20806             || !memory_displacement_operand (operands[0], QImode)))
20807        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20808    && peep2_regno_dead_p (0, FLAGS_REG)"
20809   [(parallel [(set (match_dup 0)
20810                    (xor:QI (match_dup 1) (const_int -1)))
20811               (clobber (reg:CC FLAGS_REG))])]
20812   "")
20813
20814 ;; Non pairable "test imm, reg" instructions can be translated to
20815 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20816 ;; byte opcode instead of two, have a short form for byte operands),
20817 ;; so do it for other CPUs as well.  Given that the value was dead,
20818 ;; this should not create any new dependencies.  Pass on the sub-word
20819 ;; versions if we're concerned about partial register stalls.
20820
20821 (define_peephole2
20822   [(set (match_operand 0 "flags_reg_operand" "")
20823         (match_operator 1 "compare_operator"
20824           [(and:SI (match_operand:SI 2 "register_operand" "")
20825                    (match_operand:SI 3 "immediate_operand" ""))
20826            (const_int 0)]))]
20827   "ix86_match_ccmode (insn, CCNOmode)
20828    && (true_regnum (operands[2]) != AX_REG
20829        || satisfies_constraint_K (operands[3]))
20830    && peep2_reg_dead_p (1, operands[2])"
20831   [(parallel
20832      [(set (match_dup 0)
20833            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20834                             (const_int 0)]))
20835       (set (match_dup 2)
20836            (and:SI (match_dup 2) (match_dup 3)))])]
20837   "")
20838
20839 ;; We don't need to handle HImode case, because it will be promoted to SImode
20840 ;; on ! TARGET_PARTIAL_REG_STALL
20841
20842 (define_peephole2
20843   [(set (match_operand 0 "flags_reg_operand" "")
20844         (match_operator 1 "compare_operator"
20845           [(and:QI (match_operand:QI 2 "register_operand" "")
20846                    (match_operand:QI 3 "immediate_operand" ""))
20847            (const_int 0)]))]
20848   "! TARGET_PARTIAL_REG_STALL
20849    && ix86_match_ccmode (insn, CCNOmode)
20850    && true_regnum (operands[2]) != AX_REG
20851    && peep2_reg_dead_p (1, operands[2])"
20852   [(parallel
20853      [(set (match_dup 0)
20854            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20855                             (const_int 0)]))
20856       (set (match_dup 2)
20857            (and:QI (match_dup 2) (match_dup 3)))])]
20858   "")
20859
20860 (define_peephole2
20861   [(set (match_operand 0 "flags_reg_operand" "")
20862         (match_operator 1 "compare_operator"
20863           [(and:SI
20864              (zero_extract:SI
20865                (match_operand 2 "ext_register_operand" "")
20866                (const_int 8)
20867                (const_int 8))
20868              (match_operand 3 "const_int_operand" ""))
20869            (const_int 0)]))]
20870   "! TARGET_PARTIAL_REG_STALL
20871    && ix86_match_ccmode (insn, CCNOmode)
20872    && true_regnum (operands[2]) != AX_REG
20873    && peep2_reg_dead_p (1, operands[2])"
20874   [(parallel [(set (match_dup 0)
20875                    (match_op_dup 1
20876                      [(and:SI
20877                         (zero_extract:SI
20878                           (match_dup 2)
20879                           (const_int 8)
20880                           (const_int 8))
20881                         (match_dup 3))
20882                       (const_int 0)]))
20883               (set (zero_extract:SI (match_dup 2)
20884                                     (const_int 8)
20885                                     (const_int 8))
20886                    (and:SI
20887                      (zero_extract:SI
20888                        (match_dup 2)
20889                        (const_int 8)
20890                        (const_int 8))
20891                      (match_dup 3)))])]
20892   "")
20893
20894 ;; Don't do logical operations with memory inputs.
20895 (define_peephole2
20896   [(match_scratch:SI 2 "r")
20897    (parallel [(set (match_operand:SI 0 "register_operand" "")
20898                    (match_operator:SI 3 "arith_or_logical_operator"
20899                      [(match_dup 0)
20900                       (match_operand:SI 1 "memory_operand" "")]))
20901               (clobber (reg:CC FLAGS_REG))])]
20902   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20903   [(set (match_dup 2) (match_dup 1))
20904    (parallel [(set (match_dup 0)
20905                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20906               (clobber (reg:CC FLAGS_REG))])]
20907   "")
20908
20909 (define_peephole2
20910   [(match_scratch:SI 2 "r")
20911    (parallel [(set (match_operand:SI 0 "register_operand" "")
20912                    (match_operator:SI 3 "arith_or_logical_operator"
20913                      [(match_operand:SI 1 "memory_operand" "")
20914                       (match_dup 0)]))
20915               (clobber (reg:CC FLAGS_REG))])]
20916   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20917   [(set (match_dup 2) (match_dup 1))
20918    (parallel [(set (match_dup 0)
20919                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20920               (clobber (reg:CC FLAGS_REG))])]
20921   "")
20922
20923 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20924 ;; refers to the destination of the load!
20925
20926 (define_peephole2
20927   [(set (match_operand:SI 0 "register_operand" "")
20928         (match_operand:SI 1 "register_operand" ""))
20929    (parallel [(set (match_dup 0)
20930                    (match_operator:SI 3 "commutative_operator"
20931                      [(match_dup 0)
20932                       (match_operand:SI 2 "memory_operand" "")]))
20933               (clobber (reg:CC FLAGS_REG))])]
20934   "REGNO (operands[0]) != REGNO (operands[1])
20935    && GENERAL_REGNO_P (REGNO (operands[0]))
20936    && GENERAL_REGNO_P (REGNO (operands[1]))"
20937   [(set (match_dup 0) (match_dup 4))
20938    (parallel [(set (match_dup 0)
20939                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20940               (clobber (reg:CC FLAGS_REG))])]
20941   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20942
20943 (define_peephole2
20944   [(set (match_operand 0 "register_operand" "")
20945         (match_operand 1 "register_operand" ""))
20946    (set (match_dup 0)
20947                    (match_operator 3 "commutative_operator"
20948                      [(match_dup 0)
20949                       (match_operand 2 "memory_operand" "")]))]
20950   "REGNO (operands[0]) != REGNO (operands[1])
20951    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
20952        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20953   [(set (match_dup 0) (match_dup 2))
20954    (set (match_dup 0)
20955         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20956   "")
20957
20958 ; Don't do logical operations with memory outputs
20959 ;
20960 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20961 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20962 ; the same decoder scheduling characteristics as the original.
20963
20964 (define_peephole2
20965   [(match_scratch:SI 2 "r")
20966    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20967                    (match_operator:SI 3 "arith_or_logical_operator"
20968                      [(match_dup 0)
20969                       (match_operand:SI 1 "nonmemory_operand" "")]))
20970               (clobber (reg:CC FLAGS_REG))])]
20971   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20972   [(set (match_dup 2) (match_dup 0))
20973    (parallel [(set (match_dup 2)
20974                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20975               (clobber (reg:CC FLAGS_REG))])
20976    (set (match_dup 0) (match_dup 2))]
20977   "")
20978
20979 (define_peephole2
20980   [(match_scratch:SI 2 "r")
20981    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20982                    (match_operator:SI 3 "arith_or_logical_operator"
20983                      [(match_operand:SI 1 "nonmemory_operand" "")
20984                       (match_dup 0)]))
20985               (clobber (reg:CC FLAGS_REG))])]
20986   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20987   [(set (match_dup 2) (match_dup 0))
20988    (parallel [(set (match_dup 2)
20989                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20990               (clobber (reg:CC FLAGS_REG))])
20991    (set (match_dup 0) (match_dup 2))]
20992   "")
20993
20994 ;; Attempt to always use XOR for zeroing registers.
20995 (define_peephole2
20996   [(set (match_operand 0 "register_operand" "")
20997         (match_operand 1 "const0_operand" ""))]
20998   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20999    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21000    && GENERAL_REG_P (operands[0])
21001    && peep2_regno_dead_p (0, FLAGS_REG)"
21002   [(parallel [(set (match_dup 0) (const_int 0))
21003               (clobber (reg:CC FLAGS_REG))])]
21004 {
21005   operands[0] = gen_lowpart (word_mode, operands[0]);
21006 })
21007
21008 (define_peephole2
21009   [(set (strict_low_part (match_operand 0 "register_operand" ""))
21010         (const_int 0))]
21011   "(GET_MODE (operands[0]) == QImode
21012     || GET_MODE (operands[0]) == HImode)
21013    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21014    && peep2_regno_dead_p (0, FLAGS_REG)"
21015   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
21016               (clobber (reg:CC FLAGS_REG))])])
21017
21018 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21019 (define_peephole2
21020   [(set (match_operand 0 "register_operand" "")
21021         (const_int -1))]
21022   "(GET_MODE (operands[0]) == HImode
21023     || GET_MODE (operands[0]) == SImode
21024     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
21025    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
21026    && peep2_regno_dead_p (0, FLAGS_REG)"
21027   [(parallel [(set (match_dup 0) (const_int -1))
21028               (clobber (reg:CC FLAGS_REG))])]
21029   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21030                               operands[0]);")
21031
21032 ;; Attempt to convert simple leas to adds. These can be created by
21033 ;; move expanders.
21034 (define_peephole2
21035   [(set (match_operand:SI 0 "register_operand" "")
21036         (plus:SI (match_dup 0)
21037                  (match_operand:SI 1 "nonmemory_operand" "")))]
21038   "peep2_regno_dead_p (0, FLAGS_REG)"
21039   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21040               (clobber (reg:CC FLAGS_REG))])]
21041   "")
21042
21043 (define_peephole2
21044   [(set (match_operand:SI 0 "register_operand" "")
21045         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21046                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21047   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21048   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21049               (clobber (reg:CC FLAGS_REG))])]
21050   "operands[2] = gen_lowpart (SImode, operands[2]);")
21051
21052 (define_peephole2
21053   [(set (match_operand:DI 0 "register_operand" "")
21054         (plus:DI (match_dup 0)
21055                  (match_operand:DI 1 "x86_64_general_operand" "")))]
21056   "peep2_regno_dead_p (0, FLAGS_REG)"
21057   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21058               (clobber (reg:CC FLAGS_REG))])]
21059   "")
21060
21061 (define_peephole2
21062   [(set (match_operand:SI 0 "register_operand" "")
21063         (mult:SI (match_dup 0)
21064                  (match_operand:SI 1 "const_int_operand" "")))]
21065   "exact_log2 (INTVAL (operands[1])) >= 0
21066    && peep2_regno_dead_p (0, FLAGS_REG)"
21067   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21068               (clobber (reg:CC FLAGS_REG))])]
21069   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21070
21071 (define_peephole2
21072   [(set (match_operand:DI 0 "register_operand" "")
21073         (mult:DI (match_dup 0)
21074                  (match_operand:DI 1 "const_int_operand" "")))]
21075   "exact_log2 (INTVAL (operands[1])) >= 0
21076    && peep2_regno_dead_p (0, FLAGS_REG)"
21077   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21078               (clobber (reg:CC FLAGS_REG))])]
21079   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21080
21081 (define_peephole2
21082   [(set (match_operand:SI 0 "register_operand" "")
21083         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21084                    (match_operand:DI 2 "const_int_operand" "")) 0))]
21085   "exact_log2 (INTVAL (operands[2])) >= 0
21086    && REGNO (operands[0]) == REGNO (operands[1])
21087    && peep2_regno_dead_p (0, FLAGS_REG)"
21088   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21089               (clobber (reg:CC FLAGS_REG))])]
21090   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21091
21092 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
21093 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
21094 ;; many CPUs it is also faster, since special hardware to avoid esp
21095 ;; dependencies is present.
21096
21097 ;; While some of these conversions may be done using splitters, we use peepholes
21098 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21099
21100 ;; Convert prologue esp subtractions to push.
21101 ;; We need register to push.  In order to keep verify_flow_info happy we have
21102 ;; two choices
21103 ;; - use scratch and clobber it in order to avoid dependencies
21104 ;; - use already live register
21105 ;; We can't use the second way right now, since there is no reliable way how to
21106 ;; verify that given register is live.  First choice will also most likely in
21107 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
21108 ;; call clobbered registers are dead.  We may want to use base pointer as an
21109 ;; alternative when no register is available later.
21110
21111 (define_peephole2
21112   [(match_scratch:SI 0 "r")
21113    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21114               (clobber (reg:CC FLAGS_REG))
21115               (clobber (mem:BLK (scratch)))])]
21116   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21117   [(clobber (match_dup 0))
21118    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21119               (clobber (mem:BLK (scratch)))])])
21120
21121 (define_peephole2
21122   [(match_scratch:SI 0 "r")
21123    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21124               (clobber (reg:CC FLAGS_REG))
21125               (clobber (mem:BLK (scratch)))])]
21126   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21127   [(clobber (match_dup 0))
21128    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21129    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21130               (clobber (mem:BLK (scratch)))])])
21131
21132 ;; Convert esp subtractions to push.
21133 (define_peephole2
21134   [(match_scratch:SI 0 "r")
21135    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21136               (clobber (reg:CC FLAGS_REG))])]
21137   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21138   [(clobber (match_dup 0))
21139    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21140
21141 (define_peephole2
21142   [(match_scratch:SI 0 "r")
21143    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21144               (clobber (reg:CC FLAGS_REG))])]
21145   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21146   [(clobber (match_dup 0))
21147    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21148    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21149
21150 ;; Convert epilogue deallocator to pop.
21151 (define_peephole2
21152   [(match_scratch:SI 0 "r")
21153    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21154               (clobber (reg:CC FLAGS_REG))
21155               (clobber (mem:BLK (scratch)))])]
21156   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21157   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21158               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21159               (clobber (mem:BLK (scratch)))])]
21160   "")
21161
21162 ;; Two pops case is tricky, since pop causes dependency on destination register.
21163 ;; We use two registers if available.
21164 (define_peephole2
21165   [(match_scratch:SI 0 "r")
21166    (match_scratch:SI 1 "r")
21167    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21168               (clobber (reg:CC FLAGS_REG))
21169               (clobber (mem:BLK (scratch)))])]
21170   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21171   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21172               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21173               (clobber (mem:BLK (scratch)))])
21174    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21175               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21176   "")
21177
21178 (define_peephole2
21179   [(match_scratch:SI 0 "r")
21180    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21181               (clobber (reg:CC FLAGS_REG))
21182               (clobber (mem:BLK (scratch)))])]
21183   "optimize_insn_for_size_p ()"
21184   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21185               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21186               (clobber (mem:BLK (scratch)))])
21187    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21188               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21189   "")
21190
21191 ;; Convert esp additions to pop.
21192 (define_peephole2
21193   [(match_scratch:SI 0 "r")
21194    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21195               (clobber (reg:CC FLAGS_REG))])]
21196   ""
21197   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21198               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21199   "")
21200
21201 ;; Two pops case is tricky, since pop causes dependency on destination register.
21202 ;; We use two registers if available.
21203 (define_peephole2
21204   [(match_scratch:SI 0 "r")
21205    (match_scratch:SI 1 "r")
21206    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21207               (clobber (reg:CC FLAGS_REG))])]
21208   ""
21209   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21210               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21211    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21212               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21213   "")
21214
21215 (define_peephole2
21216   [(match_scratch:SI 0 "r")
21217    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21218               (clobber (reg:CC FLAGS_REG))])]
21219   "optimize_insn_for_size_p ()"
21220   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21221               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21222    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21223               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21224   "")
21225 \f
21226 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21227 ;; required and register dies.  Similarly for 128 to -128.
21228 (define_peephole2
21229   [(set (match_operand 0 "flags_reg_operand" "")
21230         (match_operator 1 "compare_operator"
21231           [(match_operand 2 "register_operand" "")
21232            (match_operand 3 "const_int_operand" "")]))]
21233   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21234      && incdec_operand (operands[3], GET_MODE (operands[3])))
21235     || (!TARGET_FUSE_CMP_AND_BRANCH
21236         && INTVAL (operands[3]) == 128))
21237    && ix86_match_ccmode (insn, CCGCmode)
21238    && peep2_reg_dead_p (1, operands[2])"
21239   [(parallel [(set (match_dup 0)
21240                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21241               (clobber (match_dup 2))])]
21242   "")
21243 \f
21244 (define_peephole2
21245   [(match_scratch:DI 0 "r")
21246    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21247               (clobber (reg:CC FLAGS_REG))
21248               (clobber (mem:BLK (scratch)))])]
21249   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21250   [(clobber (match_dup 0))
21251    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21252               (clobber (mem:BLK (scratch)))])])
21253
21254 (define_peephole2
21255   [(match_scratch:DI 0 "r")
21256    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21257               (clobber (reg:CC FLAGS_REG))
21258               (clobber (mem:BLK (scratch)))])]
21259   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21260   [(clobber (match_dup 0))
21261    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21262    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21263               (clobber (mem:BLK (scratch)))])])
21264
21265 ;; Convert esp subtractions to push.
21266 (define_peephole2
21267   [(match_scratch:DI 0 "r")
21268    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21269               (clobber (reg:CC FLAGS_REG))])]
21270   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21271   [(clobber (match_dup 0))
21272    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21273
21274 (define_peephole2
21275   [(match_scratch:DI 0 "r")
21276    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21277               (clobber (reg:CC FLAGS_REG))])]
21278   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21279   [(clobber (match_dup 0))
21280    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21281    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21282
21283 ;; Convert epilogue deallocator to pop.
21284 (define_peephole2
21285   [(match_scratch:DI 0 "r")
21286    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21287               (clobber (reg:CC FLAGS_REG))
21288               (clobber (mem:BLK (scratch)))])]
21289   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21290   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21291               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21292               (clobber (mem:BLK (scratch)))])]
21293   "")
21294
21295 ;; Two pops case is tricky, since pop causes dependency on destination register.
21296 ;; We use two registers if available.
21297 (define_peephole2
21298   [(match_scratch:DI 0 "r")
21299    (match_scratch:DI 1 "r")
21300    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21301               (clobber (reg:CC FLAGS_REG))
21302               (clobber (mem:BLK (scratch)))])]
21303   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21304   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21305               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21306               (clobber (mem:BLK (scratch)))])
21307    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21308               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21309   "")
21310
21311 (define_peephole2
21312   [(match_scratch:DI 0 "r")
21313    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21314               (clobber (reg:CC FLAGS_REG))
21315               (clobber (mem:BLK (scratch)))])]
21316   "optimize_insn_for_size_p ()"
21317   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21318               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21319               (clobber (mem:BLK (scratch)))])
21320    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21321               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21322   "")
21323
21324 ;; Convert esp additions to pop.
21325 (define_peephole2
21326   [(match_scratch:DI 0 "r")
21327    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21328               (clobber (reg:CC FLAGS_REG))])]
21329   ""
21330   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21331               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21332   "")
21333
21334 ;; Two pops case is tricky, since pop causes dependency on destination register.
21335 ;; We use two registers if available.
21336 (define_peephole2
21337   [(match_scratch:DI 0 "r")
21338    (match_scratch:DI 1 "r")
21339    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21340               (clobber (reg:CC FLAGS_REG))])]
21341   ""
21342   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21343               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21344    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21345               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21346   "")
21347
21348 (define_peephole2
21349   [(match_scratch:DI 0 "r")
21350    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21351               (clobber (reg:CC FLAGS_REG))])]
21352   "optimize_insn_for_size_p ()"
21353   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21354               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21355    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21356               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21357   "")
21358 \f
21359 ;; Convert imul by three, five and nine into lea
21360 (define_peephole2
21361   [(parallel
21362     [(set (match_operand:SI 0 "register_operand" "")
21363           (mult:SI (match_operand:SI 1 "register_operand" "")
21364                    (match_operand:SI 2 "const_int_operand" "")))
21365      (clobber (reg:CC FLAGS_REG))])]
21366   "INTVAL (operands[2]) == 3
21367    || INTVAL (operands[2]) == 5
21368    || INTVAL (operands[2]) == 9"
21369   [(set (match_dup 0)
21370         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21371                  (match_dup 1)))]
21372   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21373
21374 (define_peephole2
21375   [(parallel
21376     [(set (match_operand:SI 0 "register_operand" "")
21377           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21378                    (match_operand:SI 2 "const_int_operand" "")))
21379      (clobber (reg:CC FLAGS_REG))])]
21380   "optimize_insn_for_speed_p ()
21381    && (INTVAL (operands[2]) == 3
21382        || INTVAL (operands[2]) == 5
21383        || INTVAL (operands[2]) == 9)"
21384   [(set (match_dup 0) (match_dup 1))
21385    (set (match_dup 0)
21386         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21387                  (match_dup 0)))]
21388   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21389
21390 (define_peephole2
21391   [(parallel
21392     [(set (match_operand:DI 0 "register_operand" "")
21393           (mult:DI (match_operand:DI 1 "register_operand" "")
21394                    (match_operand:DI 2 "const_int_operand" "")))
21395      (clobber (reg:CC FLAGS_REG))])]
21396   "TARGET_64BIT
21397    && (INTVAL (operands[2]) == 3
21398        || INTVAL (operands[2]) == 5
21399        || INTVAL (operands[2]) == 9)"
21400   [(set (match_dup 0)
21401         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21402                  (match_dup 1)))]
21403   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21404
21405 (define_peephole2
21406   [(parallel
21407     [(set (match_operand:DI 0 "register_operand" "")
21408           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21409                    (match_operand:DI 2 "const_int_operand" "")))
21410      (clobber (reg:CC FLAGS_REG))])]
21411   "TARGET_64BIT
21412    && optimize_insn_for_speed_p ()
21413    && (INTVAL (operands[2]) == 3
21414        || INTVAL (operands[2]) == 5
21415        || INTVAL (operands[2]) == 9)"
21416   [(set (match_dup 0) (match_dup 1))
21417    (set (match_dup 0)
21418         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21419                  (match_dup 0)))]
21420   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21421
21422 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21423 ;; imul $32bit_imm, reg, reg is direct decoded.
21424 (define_peephole2
21425   [(match_scratch:DI 3 "r")
21426    (parallel [(set (match_operand:DI 0 "register_operand" "")
21427                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21428                             (match_operand:DI 2 "immediate_operand" "")))
21429               (clobber (reg:CC FLAGS_REG))])]
21430   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21431    && !satisfies_constraint_K (operands[2])"
21432   [(set (match_dup 3) (match_dup 1))
21433    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21434               (clobber (reg:CC FLAGS_REG))])]
21435 "")
21436
21437 (define_peephole2
21438   [(match_scratch:SI 3 "r")
21439    (parallel [(set (match_operand:SI 0 "register_operand" "")
21440                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21441                             (match_operand:SI 2 "immediate_operand" "")))
21442               (clobber (reg:CC FLAGS_REG))])]
21443   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21444    && !satisfies_constraint_K (operands[2])"
21445   [(set (match_dup 3) (match_dup 1))
21446    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21447               (clobber (reg:CC FLAGS_REG))])]
21448 "")
21449
21450 (define_peephole2
21451   [(match_scratch:SI 3 "r")
21452    (parallel [(set (match_operand:DI 0 "register_operand" "")
21453                    (zero_extend:DI
21454                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21455                               (match_operand:SI 2 "immediate_operand" ""))))
21456               (clobber (reg:CC FLAGS_REG))])]
21457   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21458    && !satisfies_constraint_K (operands[2])"
21459   [(set (match_dup 3) (match_dup 1))
21460    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21461               (clobber (reg:CC FLAGS_REG))])]
21462 "")
21463
21464 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21465 ;; Convert it into imul reg, reg
21466 ;; It would be better to force assembler to encode instruction using long
21467 ;; immediate, but there is apparently no way to do so.
21468 (define_peephole2
21469   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21470                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21471                             (match_operand:DI 2 "const_int_operand" "")))
21472               (clobber (reg:CC FLAGS_REG))])
21473    (match_scratch:DI 3 "r")]
21474   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21475    && satisfies_constraint_K (operands[2])"
21476   [(set (match_dup 3) (match_dup 2))
21477    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21478               (clobber (reg:CC FLAGS_REG))])]
21479 {
21480   if (!rtx_equal_p (operands[0], operands[1]))
21481     emit_move_insn (operands[0], operands[1]);
21482 })
21483
21484 (define_peephole2
21485   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21486                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21487                             (match_operand:SI 2 "const_int_operand" "")))
21488               (clobber (reg:CC FLAGS_REG))])
21489    (match_scratch:SI 3 "r")]
21490   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21491    && satisfies_constraint_K (operands[2])"
21492   [(set (match_dup 3) (match_dup 2))
21493    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21494               (clobber (reg:CC FLAGS_REG))])]
21495 {
21496   if (!rtx_equal_p (operands[0], operands[1]))
21497     emit_move_insn (operands[0], operands[1]);
21498 })
21499
21500 (define_peephole2
21501   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21502                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21503                             (match_operand:HI 2 "immediate_operand" "")))
21504               (clobber (reg:CC FLAGS_REG))])
21505    (match_scratch:HI 3 "r")]
21506   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21507   [(set (match_dup 3) (match_dup 2))
21508    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21509               (clobber (reg:CC FLAGS_REG))])]
21510 {
21511   if (!rtx_equal_p (operands[0], operands[1]))
21512     emit_move_insn (operands[0], operands[1]);
21513 })
21514
21515 ;; After splitting up read-modify operations, array accesses with memory
21516 ;; operands might end up in form:
21517 ;;  sall    $2, %eax
21518 ;;  movl    4(%esp), %edx
21519 ;;  addl    %edx, %eax
21520 ;; instead of pre-splitting:
21521 ;;  sall    $2, %eax
21522 ;;  addl    4(%esp), %eax
21523 ;; Turn it into:
21524 ;;  movl    4(%esp), %edx
21525 ;;  leal    (%edx,%eax,4), %eax
21526
21527 (define_peephole2
21528   [(parallel [(set (match_operand 0 "register_operand" "")
21529                    (ashift (match_operand 1 "register_operand" "")
21530                            (match_operand 2 "const_int_operand" "")))
21531                (clobber (reg:CC FLAGS_REG))])
21532    (set (match_operand 3 "register_operand")
21533         (match_operand 4 "x86_64_general_operand" ""))
21534    (parallel [(set (match_operand 5 "register_operand" "")
21535                    (plus (match_operand 6 "register_operand" "")
21536                          (match_operand 7 "register_operand" "")))
21537                    (clobber (reg:CC FLAGS_REG))])]
21538   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21539    /* Validate MODE for lea.  */
21540    && ((!TARGET_PARTIAL_REG_STALL
21541         && (GET_MODE (operands[0]) == QImode
21542             || GET_MODE (operands[0]) == HImode))
21543        || GET_MODE (operands[0]) == SImode
21544        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21545    /* We reorder load and the shift.  */
21546    && !rtx_equal_p (operands[1], operands[3])
21547    && !reg_overlap_mentioned_p (operands[0], operands[4])
21548    /* Last PLUS must consist of operand 0 and 3.  */
21549    && !rtx_equal_p (operands[0], operands[3])
21550    && (rtx_equal_p (operands[3], operands[6])
21551        || rtx_equal_p (operands[3], operands[7]))
21552    && (rtx_equal_p (operands[0], operands[6])
21553        || rtx_equal_p (operands[0], operands[7]))
21554    /* The intermediate operand 0 must die or be same as output.  */
21555    && (rtx_equal_p (operands[0], operands[5])
21556        || peep2_reg_dead_p (3, operands[0]))"
21557   [(set (match_dup 3) (match_dup 4))
21558    (set (match_dup 0) (match_dup 1))]
21559 {
21560   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21561   int scale = 1 << INTVAL (operands[2]);
21562   rtx index = gen_lowpart (Pmode, operands[1]);
21563   rtx base = gen_lowpart (Pmode, operands[3]);
21564   rtx dest = gen_lowpart (mode, operands[5]);
21565
21566   operands[1] = gen_rtx_PLUS (Pmode, base,
21567                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21568   if (mode != Pmode)
21569     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21570   operands[0] = dest;
21571 })
21572 \f
21573 ;; Call-value patterns last so that the wildcard operand does not
21574 ;; disrupt insn-recog's switch tables.
21575
21576 (define_insn "*call_value_pop_0"
21577   [(set (match_operand 0 "" "")
21578         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21579               (match_operand:SI 2 "" "")))
21580    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21581                             (match_operand:SI 3 "immediate_operand" "")))]
21582   "!TARGET_64BIT"
21583 {
21584   if (SIBLING_CALL_P (insn))
21585     return "jmp\t%P1";
21586   else
21587     return "call\t%P1";
21588 }
21589   [(set_attr "type" "callv")])
21590
21591 (define_insn "*call_value_pop_1"
21592   [(set (match_operand 0 "" "")
21593         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21594               (match_operand:SI 2 "" "")))
21595    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21596                             (match_operand:SI 3 "immediate_operand" "i")))]
21597   "!TARGET_64BIT"
21598 {
21599   if (constant_call_address_operand (operands[1], Pmode))
21600     {
21601       if (SIBLING_CALL_P (insn))
21602         return "jmp\t%P1";
21603       else
21604         return "call\t%P1";
21605     }
21606   if (SIBLING_CALL_P (insn))
21607     return "jmp\t%A1";
21608   else
21609     return "call\t%A1";
21610 }
21611   [(set_attr "type" "callv")])
21612
21613 (define_insn "*call_value_0"
21614   [(set (match_operand 0 "" "")
21615         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21616               (match_operand:SI 2 "" "")))]
21617   "!TARGET_64BIT"
21618 {
21619   if (SIBLING_CALL_P (insn))
21620     return "jmp\t%P1";
21621   else
21622     return "call\t%P1";
21623 }
21624   [(set_attr "type" "callv")])
21625
21626 (define_insn "*call_value_0_rex64"
21627   [(set (match_operand 0 "" "")
21628         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21629               (match_operand:DI 2 "const_int_operand" "")))]
21630   "TARGET_64BIT"
21631 {
21632   if (SIBLING_CALL_P (insn))
21633     return "jmp\t%P1";
21634   else
21635     return "call\t%P1";
21636 }
21637   [(set_attr "type" "callv")])
21638
21639 (define_insn "*call_value_0_rex64_ms_sysv"
21640   [(set (match_operand 0 "" "")
21641         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21642               (match_operand:DI 2 "const_int_operand" "")))
21643    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21644    (clobber (reg:TI XMM6_REG))
21645    (clobber (reg:TI XMM7_REG))
21646    (clobber (reg:TI XMM8_REG))
21647    (clobber (reg:TI XMM9_REG))
21648    (clobber (reg:TI XMM10_REG))
21649    (clobber (reg:TI XMM11_REG))
21650    (clobber (reg:TI XMM12_REG))
21651    (clobber (reg:TI XMM13_REG))
21652    (clobber (reg:TI XMM14_REG))
21653    (clobber (reg:TI XMM15_REG))
21654    (clobber (reg:DI SI_REG))
21655    (clobber (reg:DI DI_REG))]
21656   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21657 {
21658   if (SIBLING_CALL_P (insn))
21659     return "jmp\t%P1";
21660   else
21661     return "call\t%P1";
21662 }
21663   [(set_attr "type" "callv")])
21664
21665 (define_insn "*call_value_1"
21666   [(set (match_operand 0 "" "")
21667         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21668               (match_operand:SI 2 "" "")))]
21669   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21670 {
21671   if (constant_call_address_operand (operands[1], Pmode))
21672     return "call\t%P1";
21673   return "call\t%A1";
21674 }
21675   [(set_attr "type" "callv")])
21676
21677 (define_insn "*sibcall_value_1"
21678   [(set (match_operand 0 "" "")
21679         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21680               (match_operand:SI 2 "" "")))]
21681   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21682 {
21683   if (constant_call_address_operand (operands[1], Pmode))
21684     return "jmp\t%P1";
21685   return "jmp\t%A1";
21686 }
21687   [(set_attr "type" "callv")])
21688
21689 (define_insn "*call_value_1_rex64"
21690   [(set (match_operand 0 "" "")
21691         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21692               (match_operand:DI 2 "" "")))]
21693   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21694    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21695 {
21696   if (constant_call_address_operand (operands[1], Pmode))
21697     return "call\t%P1";
21698   return "call\t%A1";
21699 }
21700   [(set_attr "type" "callv")])
21701
21702 (define_insn "*call_value_1_rex64_ms_sysv"
21703   [(set (match_operand 0 "" "")
21704         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21705               (match_operand:DI 2 "" "")))
21706    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21707    (clobber (reg:TI 27))
21708    (clobber (reg:TI 28))
21709    (clobber (reg:TI 45))
21710    (clobber (reg:TI 46))
21711    (clobber (reg:TI 47))
21712    (clobber (reg:TI 48))
21713    (clobber (reg:TI 49))
21714    (clobber (reg:TI 50))
21715    (clobber (reg:TI 51))
21716    (clobber (reg:TI 52))
21717    (clobber (reg:DI SI_REG))
21718    (clobber (reg:DI DI_REG))]
21719   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21720 {
21721   if (constant_call_address_operand (operands[1], Pmode))
21722     return "call\t%P1";
21723   return "call\t%A1";
21724 }
21725   [(set_attr "type" "callv")])
21726
21727 (define_insn "*call_value_1_rex64_large"
21728   [(set (match_operand 0 "" "")
21729         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21730               (match_operand:DI 2 "" "")))]
21731   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21732   "call\t%A1"
21733   [(set_attr "type" "callv")])
21734
21735 (define_insn "*sibcall_value_1_rex64"
21736   [(set (match_operand 0 "" "")
21737         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21738               (match_operand:DI 2 "" "")))]
21739   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21740   "jmp\t%P1"
21741   [(set_attr "type" "callv")])
21742
21743 (define_insn "*sibcall_value_1_rex64_v"
21744   [(set (match_operand 0 "" "")
21745         (call (mem:QI (reg:DI R11_REG))
21746               (match_operand:DI 1 "" "")))]
21747   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21748   "jmp\t{*%%}r11"
21749   [(set_attr "type" "callv")])
21750 \f
21751 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21752 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21753 ;; caught for use by garbage collectors and the like.  Using an insn that
21754 ;; maps to SIGILL makes it more likely the program will rightfully die.
21755 ;; Keeping with tradition, "6" is in honor of #UD.
21756 (define_insn "trap"
21757   [(trap_if (const_int 1) (const_int 6))]
21758   ""
21759   { return ASM_SHORT "0x0b0f"; }
21760   [(set_attr "length" "2")])
21761
21762 (define_expand "sse_prologue_save"
21763   [(parallel [(set (match_operand:BLK 0 "" "")
21764                    (unspec:BLK [(reg:DI 21)
21765                                 (reg:DI 22)
21766                                 (reg:DI 23)
21767                                 (reg:DI 24)
21768                                 (reg:DI 25)
21769                                 (reg:DI 26)
21770                                 (reg:DI 27)
21771                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21772               (use (match_operand:DI 1 "register_operand" ""))
21773               (use (match_operand:DI 2 "immediate_operand" ""))
21774               (use (label_ref:DI (match_operand 3 "" "")))])]
21775   "TARGET_64BIT"
21776   "")
21777
21778 (define_insn "*sse_prologue_save_insn"
21779   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21780                           (match_operand:DI 4 "const_int_operand" "n")))
21781         (unspec:BLK [(reg:DI 21)
21782                      (reg:DI 22)
21783                      (reg:DI 23)
21784                      (reg:DI 24)
21785                      (reg:DI 25)
21786                      (reg:DI 26)
21787                      (reg:DI 27)
21788                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21789    (use (match_operand:DI 1 "register_operand" "r"))
21790    (use (match_operand:DI 2 "const_int_operand" "i"))
21791    (use (label_ref:DI (match_operand 3 "" "X")))]
21792   "TARGET_64BIT
21793    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21794    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21795 {
21796   int i;
21797   operands[0] = gen_rtx_MEM (Pmode,
21798                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21799   /* VEX instruction with a REX prefix will #UD.  */
21800   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21801     gcc_unreachable ();
21802
21803   output_asm_insn ("jmp\t%A1", operands);
21804   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21805     {
21806       operands[4] = adjust_address (operands[0], DImode, i*16);
21807       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21808       PUT_MODE (operands[4], TImode);
21809       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21810         output_asm_insn ("rex", operands);
21811       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21812     }
21813   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21814                                      CODE_LABEL_NUMBER (operands[3]));
21815   return "";
21816 }
21817   [(set_attr "type" "other")
21818    (set_attr "length_immediate" "0")
21819    (set_attr "length_address" "0")
21820    (set (attr "length")
21821      (if_then_else
21822        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21823        (const_string "34")
21824        (const_string "42")))
21825    (set_attr "memory" "store")
21826    (set_attr "modrm" "0")
21827    (set_attr "prefix" "maybe_vex")
21828    (set_attr "mode" "DI")])
21829
21830 (define_expand "prefetch"
21831   [(prefetch (match_operand 0 "address_operand" "")
21832              (match_operand:SI 1 "const_int_operand" "")
21833              (match_operand:SI 2 "const_int_operand" ""))]
21834   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21835 {
21836   int rw = INTVAL (operands[1]);
21837   int locality = INTVAL (operands[2]);
21838
21839   gcc_assert (rw == 0 || rw == 1);
21840   gcc_assert (locality >= 0 && locality <= 3);
21841   gcc_assert (GET_MODE (operands[0]) == Pmode
21842               || GET_MODE (operands[0]) == VOIDmode);
21843
21844   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21845      supported by SSE counterpart or the SSE prefetch is not available
21846      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21847      of locality.  */
21848   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21849     operands[2] = GEN_INT (3);
21850   else
21851     operands[1] = const0_rtx;
21852 })
21853
21854 (define_insn "*prefetch_sse"
21855   [(prefetch (match_operand:SI 0 "address_operand" "p")
21856              (const_int 0)
21857              (match_operand:SI 1 "const_int_operand" ""))]
21858   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21859 {
21860   static const char * const patterns[4] = {
21861    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21862   };
21863
21864   int locality = INTVAL (operands[1]);
21865   gcc_assert (locality >= 0 && locality <= 3);
21866
21867   return patterns[locality];
21868 }
21869   [(set_attr "type" "sse")
21870    (set_attr "atom_sse_attr" "prefetch")
21871    (set_attr "memory" "none")])
21872
21873 (define_insn "*prefetch_sse_rex"
21874   [(prefetch (match_operand:DI 0 "address_operand" "p")
21875              (const_int 0)
21876              (match_operand:SI 1 "const_int_operand" ""))]
21877   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21878 {
21879   static const char * const patterns[4] = {
21880    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21881   };
21882
21883   int locality = INTVAL (operands[1]);
21884   gcc_assert (locality >= 0 && locality <= 3);
21885
21886   return patterns[locality];
21887 }
21888   [(set_attr "type" "sse")
21889    (set_attr "atom_sse_attr" "prefetch")
21890    (set_attr "memory" "none")])
21891
21892 (define_insn "*prefetch_3dnow"
21893   [(prefetch (match_operand:SI 0 "address_operand" "p")
21894              (match_operand:SI 1 "const_int_operand" "n")
21895              (const_int 3))]
21896   "TARGET_3DNOW && !TARGET_64BIT"
21897 {
21898   if (INTVAL (operands[1]) == 0)
21899     return "prefetch\t%a0";
21900   else
21901     return "prefetchw\t%a0";
21902 }
21903   [(set_attr "type" "mmx")
21904    (set_attr "memory" "none")])
21905
21906 (define_insn "*prefetch_3dnow_rex"
21907   [(prefetch (match_operand:DI 0 "address_operand" "p")
21908              (match_operand:SI 1 "const_int_operand" "n")
21909              (const_int 3))]
21910   "TARGET_3DNOW && TARGET_64BIT"
21911 {
21912   if (INTVAL (operands[1]) == 0)
21913     return "prefetch\t%a0";
21914   else
21915     return "prefetchw\t%a0";
21916 }
21917   [(set_attr "type" "mmx")
21918    (set_attr "memory" "none")])
21919
21920 (define_expand "stack_protect_set"
21921   [(match_operand 0 "memory_operand" "")
21922    (match_operand 1 "memory_operand" "")]
21923   ""
21924 {
21925 #ifdef TARGET_THREAD_SSP_OFFSET
21926   if (TARGET_64BIT)
21927     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21928                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21929   else
21930     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21931                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21932 #else
21933   if (TARGET_64BIT)
21934     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21935   else
21936     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21937 #endif
21938   DONE;
21939 })
21940
21941 (define_insn "stack_protect_set_si"
21942   [(set (match_operand:SI 0 "memory_operand" "=m")
21943         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21944    (set (match_scratch:SI 2 "=&r") (const_int 0))
21945    (clobber (reg:CC FLAGS_REG))]
21946   ""
21947   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21948   [(set_attr "type" "multi")])
21949
21950 (define_insn "stack_protect_set_di"
21951   [(set (match_operand:DI 0 "memory_operand" "=m")
21952         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21953    (set (match_scratch:DI 2 "=&r") (const_int 0))
21954    (clobber (reg:CC FLAGS_REG))]
21955   "TARGET_64BIT"
21956   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21957   [(set_attr "type" "multi")])
21958
21959 (define_insn "stack_tls_protect_set_si"
21960   [(set (match_operand:SI 0 "memory_operand" "=m")
21961         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21962    (set (match_scratch:SI 2 "=&r") (const_int 0))
21963    (clobber (reg:CC FLAGS_REG))]
21964   ""
21965   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21966   [(set_attr "type" "multi")])
21967
21968 (define_insn "stack_tls_protect_set_di"
21969   [(set (match_operand:DI 0 "memory_operand" "=m")
21970         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21971    (set (match_scratch:DI 2 "=&r") (const_int 0))
21972    (clobber (reg:CC FLAGS_REG))]
21973   "TARGET_64BIT"
21974   {
21975      /* The kernel uses a different segment register for performance reasons; a
21976         system call would not have to trash the userspace segment register,
21977         which would be expensive */
21978      if (ix86_cmodel != CM_KERNEL)
21979         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21980      else
21981         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21982   }
21983   [(set_attr "type" "multi")])
21984
21985 (define_expand "stack_protect_test"
21986   [(match_operand 0 "memory_operand" "")
21987    (match_operand 1 "memory_operand" "")
21988    (match_operand 2 "" "")]
21989   ""
21990 {
21991   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21992
21993 #ifdef TARGET_THREAD_SSP_OFFSET
21994   if (TARGET_64BIT)
21995     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21996                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21997   else
21998     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21999                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22000 #else
22001   if (TARGET_64BIT)
22002     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22003   else
22004     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
22005 #endif
22006
22007   ix86_compare_op0 = flags;
22008   ix86_compare_op1 = const0_rtx;
22009   emit_jump_insn (gen_beq (operands[2]));
22010   DONE;
22011 })
22012
22013 (define_insn "stack_protect_test_si"
22014   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22015         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22016                      (match_operand:SI 2 "memory_operand" "m")]
22017                     UNSPEC_SP_TEST))
22018    (clobber (match_scratch:SI 3 "=&r"))]
22019   ""
22020   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22021   [(set_attr "type" "multi")])
22022
22023 (define_insn "stack_protect_test_di"
22024   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22025         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22026                      (match_operand:DI 2 "memory_operand" "m")]
22027                     UNSPEC_SP_TEST))
22028    (clobber (match_scratch:DI 3 "=&r"))]
22029   "TARGET_64BIT"
22030   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22031   [(set_attr "type" "multi")])
22032
22033 (define_insn "stack_tls_protect_test_si"
22034   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22035         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22036                      (match_operand:SI 2 "const_int_operand" "i")]
22037                     UNSPEC_SP_TLS_TEST))
22038    (clobber (match_scratch:SI 3 "=r"))]
22039   ""
22040   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22041   [(set_attr "type" "multi")])
22042
22043 (define_insn "stack_tls_protect_test_di"
22044   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22045         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22046                      (match_operand:DI 2 "const_int_operand" "i")]
22047                     UNSPEC_SP_TLS_TEST))
22048    (clobber (match_scratch:DI 3 "=r"))]
22049   "TARGET_64BIT"
22050   {
22051      /* The kernel uses a different segment register for performance reasons; a
22052         system call would not have to trash the userspace segment register,
22053         which would be expensive */
22054      if (ix86_cmodel != CM_KERNEL)
22055         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22056      else
22057         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22058   }
22059   [(set_attr "type" "multi")])
22060
22061 (define_mode_iterator CRC32MODE [QI HI SI])
22062 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22063 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22064
22065 (define_insn "sse4_2_crc32<mode>"
22066   [(set (match_operand:SI 0 "register_operand" "=r")
22067         (unspec:SI
22068           [(match_operand:SI 1 "register_operand" "0")
22069            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22070           UNSPEC_CRC32))]
22071   "TARGET_SSE4_2"
22072   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22073   [(set_attr "type" "sselog1")
22074    (set_attr "prefix_rep" "1")
22075    (set_attr "prefix_extra" "1")
22076    (set_attr "mode" "SI")])
22077
22078 (define_insn "sse4_2_crc32di"
22079   [(set (match_operand:DI 0 "register_operand" "=r")
22080         (unspec:DI
22081           [(match_operand:DI 1 "register_operand" "0")
22082            (match_operand:DI 2 "nonimmediate_operand" "rm")]
22083           UNSPEC_CRC32))]
22084   "TARGET_SSE4_2 && TARGET_64BIT"
22085   "crc32q\t{%2, %0|%0, %2}"
22086   [(set_attr "type" "sselog1")
22087    (set_attr "prefix_rep" "1")
22088    (set_attr "prefix_extra" "1")
22089    (set_attr "mode" "DI")])
22090
22091 (include "mmx.md")
22092 (include "sse.md")
22093 (include "sync.md")